openid_memento_service = $openid_memento_service; $this->oauth2_memento_service = $oauth2_memento_service; $this->auth_service = $auth_service; $this->server_configuration_service = $server_configuration_service; $this->trusted_sites_service = $trusted_sites_service; $this->discovery = $discovery; $this->user_service = $user_service; $this->user_action_service = $user_action_service; $this->client_repository = $client_repository; $this->scope_repository = $scope_repository; $this->token_service = $token_service; $this->resource_server_service = $resource_server_service; $this->utils_configuration_service = $utils_configuration_service; $this->security_context_service = $security_context_service; $this->middleware(function ($request, $next) { Log::debug(sprintf("UserController::middleware route %s %s", $request->getMethod(), $request->getRequestUri())); if ($this->openid_memento_service->exists()) { //openid stuff Log::debug(sprintf("UserController::middleware OIDC")); $this->login_strategy = new OpenIdLoginStrategy ( $this->openid_memento_service, $this->user_action_service, $this->auth_service ); $this->consent_strategy = new OpenIdConsentStrategy ( $this->openid_memento_service, $this->auth_service, $this->server_configuration_service, $this->user_action_service ); } else if ($this->oauth2_memento_service->exists()) { Log::debug(sprintf("UserController::middleware OAUTH2")); $this->login_strategy = new OAuth2LoginStrategy ( $this->auth_service, $this->oauth2_memento_service, $this->user_action_service, $this->security_context_service ); $this->consent_strategy = new OAuth2ConsentStrategy ( $this->auth_service, $this->oauth2_memento_service, $this->scope_repository, $this->client_repository ); } else { //default stuff Log::debug(sprintf("UserController::middleware DEFAULT")); $this->login_strategy = new DefaultLoginStrategy($this->user_action_service, $this->auth_service); $this->consent_strategy = null; } return $next($request); }); } public function getLogin() { return $this->login_strategy->getLogin(); } public function cancelLogin() { return $this->login_strategy->cancelLogin(); } use JsonResponses; /** * @return \Illuminate\Http\JsonResponse|mixed */ public function getAccount() { try { $email = Request::input("email", ""); if (empty($email)) { throw new ValidationException("empty email."); } $user = $this->auth_service->getUserByUsername($email); if (is_null($user)) throw new EntityNotFoundException(); return $this->ok( [ 'pic' => $user->getPic(), 'full_name' => $user->getFullName() ] ); } catch (ValidationException $ex) { Log::warning($ex); return $this->error412($ex->getMessages()); } catch (EntityNotFoundException $ex) { Log::warning($ex); return $this->error404(); } catch (Exception $ex) { Log::error($ex); return $this->error500($ex); } } /** * @return \Illuminate\Http\JsonResponse|mixed */ public function emitOTP() { try { $username = Request::input("username", ""); $connection = Request::input("connection", ""); $send = Request::input("send", ""); if (empty($username)) { throw new ValidationException("empty username."); } if (empty($connection)) { throw new ValidationException("empty username."); } if (empty($send)) { throw new ValidationException("empty username."); } $client = null; // check if we have a former oauth2 request if ($this->oauth2_memento_service->exists()) { Log::debug("UserController::getOTP exist a oauth auth request on session"); $oauth_auth_request = OAuth2AuthorizationRequestFactory::getInstance()->build ( OAuth2Message::buildFromMemento($this->oauth2_memento_service->load()) ); if ($oauth_auth_request->isValid()) { $client_id = $oauth_auth_request->getClientId(); $client = $this->client_repository->getClientById($client_id); if (is_null($client)) throw new ValidationException("client does not exists"); $this->oauth2_memento_service->serialize($oauth_auth_request->getMessage()->createMemento()); } } $otp = $this->token_service->createOTPFromPayload([ OAuth2Protocol::OAuth2PasswordlessConnection => $connection, OAuth2Protocol::OAuth2PasswordlessSend => $send, OAuth2Protocol::OAuth2PasswordlessEmail => ($connection == OAuth2Protocol::OAuth2PasswordlessConnectionEmail) ? $username : null, OAuth2Protocol::OAuth2PasswordlessPhoneNumber => ($connection == OAuth2Protocol::OAuth2PasswordlessConnectionSMS) ? $username : null ], $client); return $this->created([ 'otp_length' => $otp->getLength(), 'otp_lifetime' => $otp->getLifetime(), ]); } catch (ValidationException $ex) { Log::warning($ex); return $this->error412($ex->getMessages()); } catch (EntityNotFoundException $ex) { Log::warning($ex); return $this->error404(); } catch (Exception $ex) { Log::error($ex); return $this->error500($ex); } } public function postLogin() { $max_login_attempts_2_show_captcha = $this->server_configuration_service->getConfigValue("MaxFailed.LoginAttempts.2ShowCaptcha"); $login_attempts = 0; $username = ''; $user = null; try { $data = Request::all(); if (isset($data['username'])) $data['username'] = trim($data['username']); if (isset($data['password'])) $data['password'] = trim($data['password']); $login_attempts = intval(Request::input('login_attempts')); // Build the validation constraint set. $rules = [ 'username' => 'required|email', 'password' => 'required', 'flow' => 'required|in:otp,password', 'connection' => 'sometimes|string|in:sms,email', ]; if ($login_attempts >= $max_login_attempts_2_show_captcha) { $rules['g-recaptcha-response'] = 'required|recaptcha'; } // Create a new validator instance. $validator = Validator::make($data, $rules); if ($validator->passes()) { $username = $data['username']; $password = $data['password']; $flow = $data['flow']; $remember = Request::input("remember"); $remember = !is_null($remember); $connection = $data['connection'] ?? null; try { if ($flow == "password" && $this->auth_service->login($username, $password, $remember)) { return $this->login_strategy->postLogin(); } if ($flow == "otp") { $client = null; // check if we have a former oauth2 request if ($this->oauth2_memento_service->exists()) { Log::debug("UserController::getOTP exist a oauth auth request on session"); $oauth_auth_request = OAuth2AuthorizationRequestFactory::getInstance()->build ( OAuth2Message::buildFromMemento($this->oauth2_memento_service->load()) ); if ($oauth_auth_request->isValid()) { $client_id = $oauth_auth_request->getClientId(); $client = $this->client_repository->getClientById($client_id); if (is_null($client)) throw new ValidationException("client does not exists"); $this->oauth2_memento_service->serialize($oauth_auth_request->getMessage()->createMemento()); } } $otpClaim = OAuth2OTP::fromParams($username, $connection, $password); $this->auth_service->loginWithOTP($otpClaim, $client); return $this->login_strategy->postLogin(); } } catch (AuthenticationException $ex) { // failed login attempt... $user = $this->auth_service->getUserByUsername($username); if (!is_null($user)) { $login_attempts = $user->getLoginFailedAttempt(); } return $this->login_strategy->errorLogin ( [ 'max_login_attempts_2_show_captcha' => $max_login_attempts_2_show_captcha, 'login_attempts' => $login_attempts, 'error_message' => $ex->getMessage(), 'user_fullname' => !is_null($user) ? $user->getFullName() : "", 'user_pic' => !is_null($user) ? $user->getPic(): "", 'user_verified' => true, 'username' => $username, 'flow' => $flow ] ); } } // validator errors $response_data = [ 'max_login_attempts_2_show_captcha' => $max_login_attempts_2_show_captcha, 'login_attempts' => $login_attempts, 'validator' => $validator, ]; if(!is_null($user)){ $response_data['user_fullname'] = $user->getFullName(); $response_data['user_pic'] = $user->getPic(); $response_data['user_verified'] = true; } return $this->login_strategy->errorLogin ( $response_data ); } catch (UnverifiedEmailMemberException $ex1) { Log::warning($ex1); $user = $this->auth_service->getUserByUsername($username); $response_data = [ 'max_login_attempts_2_show_captcha' => $max_login_attempts_2_show_captcha, 'login_attempts' => $login_attempts, 'username' => $username, 'error_message' => $ex1->getMessage() ]; if(!is_null($user)){ $response_data['user_fullname'] = $user->getFullName(); $response_data['user_pic'] = $user->getPic(); $response_data['user_verified'] = true; } return $this->login_strategy->errorLogin ( $response_data ); } catch (AuthenticationException $ex2) { Log::warning($ex2); return Redirect::action('UserController@getLogin'); } catch (Exception $ex) { Log::error($ex); return Redirect::action('UserController@getLogin'); } } /** * @return \Illuminate\Http\Response|mixed */ public function getConsent() { if (is_null($this->consent_strategy)) { Log::error(sprintf("UserController::getConsent consent strategy is null. request %s %s", Request::method(), Request::path())); return Response::view ( 'errors.400', [ 'error' => "Bad Request", 'error_description' => "Generic Error" ], 400 ); } return $this->consent_strategy->getConsent(); } /** * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|mixed */ public function postConsent() { try { $data = Request::all(); $rules = array ( 'trust' => 'required|oauth2_trust_response', ); // Create a new validator instance. $validator = Validator::make($data, $rules); if ($validator->passes()) { if (is_null($this->consent_strategy)) { Log::error(sprintf("UserController::postConsent consent strategy is null. request %s %s", Request::method(), Request::path())); return Response::view ( 'errors.400', [ 'error' => "Bad Request", 'error_description' => "Generic Error" ], 400 ); } return $this->consent_strategy->postConsent(Request::input("trust")); } return Redirect::action('UserController@getConsent')->withErrors($validator); } catch (Exception $ex) { Log::error($ex); return Redirect::action('UserController@getConsent'); } } public function getIdentity($identifier) { try { $user = $this->auth_service->getUserByOpenId($identifier); if (is_null($user)) { return View::make("errors.404"); } if ($this->isDiscoveryRequest()) { /* * If the Claimed Identifier was not previously discovered by the Relying Party * (the "openid.identity" in the request was "http://specs.openid.net/auth/2.0/identifier_select" * or a different Identifier, or if the OP is sending an unsolicited positive assertion), * the Relying Party MUST perform discovery on the Claimed Identifier in * the response to make sure that the OP is authorized to make assertions about the Claimed Identifier. */ return $this->discovery->user($identifier); } $redirect = Session::get('backurl'); if (!empty($redirect)) { Session::forget('backurl'); Session::save(); return Redirect::to($redirect); } $current_user = $this->auth_service->getCurrentUser(); $another_user = false; if ($current_user && $current_user->getIdentifier() != $user->getIdentifier()) { $another_user = true; } $assets_url = $this->utils_configuration_service->getConfigValue("Assets.Url"); $pic_url = $user->getPic(); $pic_url = str_contains($pic_url, 'http') ? $pic_url : $assets_url . $pic_url; $params = [ 'show_fullname' => $user->getShowProfileFullName(), 'username' => $user->getFullName(), 'show_email' => $user->getShowProfileEmail(), 'email' => $user->getEmail(), 'identifier' => $user->getIdentifier(), 'show_pic' => $user->getShowProfilePic(), 'pic' => $pic_url, 'another_user' => $another_user, ]; return View::make("identity", $params); } catch (Exception $ex) { Log::error($ex); return View::make("errors.404"); } } public function logout() { $this->user_action_service->addUserAction ( $this->auth_service->getCurrentUser()->getId(), IPHelper::getUserIp(), IUserActionService::LogoutAction ); $this->auth_service->logout(); Session::flush(); Session::regenerate(); return Redirect::action("UserController@getLogin"); } public function getProfile() { $user = $this->auth_service->getCurrentUser(); $sites = $user->getTrustedSites(); $actions = $user->getLatestNActions(10); // init database $isoCodes = new IsoCodesFactory(); // get languages database $languages = $isoCodes->getLanguages()->toArray(); $lang2Code = []; foreach ($languages as $lang) { if (!empty($lang->getAlpha2())) $lang2Code[] = $lang; } return View::make("profile", [ 'user' => $user, "openid_url" => $this->server_configuration_service->getUserIdentityEndpointURL($user->getIdentifier()), "sites" => $sites, 'actions' => $actions, 'countries' => CountryList::getCountries(), 'languages' => $lang2Code, ]); } public function deleteTrustedSite($id) { $this->trusted_sites_service->delete($id); return Redirect::action("UserController@getProfile"); } }