public function processRequest() { $request = $this->getRequest(); $this->pages = array('account' => 'Account', 'profile' => 'Profile', 'email' => 'Email', 'password' => 'Password', 'preferences' => 'Preferences', 'conduit' => 'Conduit Certificate'); if (!PhabricatorEnv::getEnvConfig('account.editable') || !PhabricatorEnv::getEnvConfig('auth.password-auth-enabled')) { unset($this->pages['password']); } if (PhabricatorUserSSHKeysSettingsPanelController::isEnabled()) { $this->pages['sshkeys'] = 'SSH Public Keys'; } $oauth_providers = PhabricatorOAuthProvider::getAllProviders(); foreach ($oauth_providers as $provider) { if (!$provider->isProviderEnabled()) { continue; } $key = $provider->getProviderKey(); $name = $provider->getProviderName(); $this->pages[$key] = $name . ' Account'; } if (empty($this->pages[$this->page])) { $this->page = key($this->pages); } switch ($this->page) { case 'account': $delegate = new PhabricatorUserAccountSettingsPanelController($request); break; case 'profile': $delegate = new PhabricatorUserProfileSettingsPanelController($request); break; case 'email': $delegate = new PhabricatorUserEmailSettingsPanelController($request); break; case 'password': $delegate = new PhabricatorUserPasswordSettingsPanelController($request); break; case 'conduit': $delegate = new PhabricatorUserConduitSettingsPanelController($request); break; case 'sshkeys': $delegate = new PhabricatorUserSSHKeysSettingsPanelController($request); break; case 'preferences': $delegate = new PhabricatorUserPreferenceSettingsPanelController($request); break; default: if (empty($this->pages[$this->page])) { return new Aphront404Response(); } $delegate = new PhabricatorUserOAuthSettingsPanelController($request); $delegate->setOAuthProvider($oauth_providers[$this->page]); } $response = $this->delegateToController($delegate); if ($response instanceof AphrontView) { $sidenav = $this->renderSideNav(); $sidenav->appendChild($response); return $this->buildStandardPageResponse($sidenav, array('title' => 'Account Settings')); } else { return $response; } }
public function buildPanels() { $panels = array(); $providers = PhabricatorOAuthProvider::getAllProviders(); foreach ($providers as $provider) { $panel = clone $this; $panel->setOAuthProvider($provider); $panels[] = $panel; } return $panels; }
public function processRequest() { $request = $this->getRequest(); $oauth_providers = PhabricatorOAuthProvider::getAllProviders(); $sidenav = $this->renderSideNav($oauth_providers); $this->page = $sidenav->selectFilter($this->page, 'account'); switch ($this->page) { case 'account': $delegate = new PhabricatorUserAccountSettingsPanelController($request); break; case 'profile': $delegate = new PhabricatorUserProfileSettingsPanelController($request); break; case 'email': $delegate = new PhabricatorUserEmailSettingsPanelController($request); break; case 'emailpref': $delegate = new PhabricatorUserEmailPreferenceSettingsPanelController($request); break; case 'password': $delegate = new PhabricatorUserPasswordSettingsPanelController($request); break; case 'conduit': $delegate = new PhabricatorUserConduitSettingsPanelController($request); break; case 'sshkeys': $delegate = new PhabricatorUserSSHKeysSettingsPanelController($request); break; case 'preferences': $delegate = new PhabricatorUserPreferenceSettingsPanelController($request); break; case 'search': $delegate = new PhabricatorUserSearchSettingsPanelController($request); break; case 'ldap': $delegate = new PhabricatorUserLDAPSettingsPanelController($request); break; default: $delegate = new PhabricatorUserOAuthSettingsPanelController($request); $delegate->setOAuthProvider($oauth_providers[$this->page]); break; } $response = $this->delegateToController($delegate); if ($response instanceof AphrontView) { $sidenav->appendChild($response); return $this->buildStandardPageResponse($sidenav, array('title' => 'Account Settings')); } else { return $response; } }
private function retrieveOAuthInfo(PhabricatorOAuthProvider $provider) { $oauth_info = id(new PhabricatorUserOAuthInfo())->loadOneWhere('oauthProvider = %s and oauthUID = %s', $provider->getProviderKey(), $provider->retrieveUserID()); if (!$oauth_info) { $oauth_info = new PhabricatorUserOAuthInfo(); $oauth_info->setOAuthProvider($provider->getProviderKey()); $oauth_info->setOAuthUID($provider->retrieveUserID()); } $oauth_info->setAccountURI($provider->retrieveUserAccountURI()); $oauth_info->setAccountName($provider->retrieveUserAccountName()); $oauth_info->setToken($provider->getAccessToken()); $oauth_info->setTokenStatus(PhabricatorUserOAuthInfo::TOKEN_STATUS_GOOD); // If we have out-of-date expiration info, just clear it out. Then replace // it with good info if the provider gave it to us. $expires = $oauth_info->getTokenExpires(); if ($expires <= time()) { $expires = null; } if ($this->tokenExpires) { $expires = $this->tokenExpires; } $oauth_info->setTokenExpires($expires); return $oauth_info; }
public function willProcessRequest(array $data) { $this->provider = PhabricatorOAuthProvider::newProvider($data['provider']); }
public function processRequest() { $viewer = $this->getRequest()->getUser(); $user = id(new PhabricatorUser())->loadOneWhere('userName = %s', $this->username); if (!$user) { return new Aphront404Response(); } $profile = id(new PhabricatorUserProfile())->loadOneWhere('userPHID = %s', $user->getPHID()); if (!$profile) { $profile = new PhabricatorUserProfile(); } $links = array(); if ($user->getPHID() == $viewer->getPHID()) { $links[] = phutil_render_tag('a', array('href' => '/settings/page/profile/'), 'Edit Profile'); } $oauths = id(new PhabricatorUserOAuthInfo())->loadAllWhere('userID = %d', $user->getID()); $oauths = mpull($oauths, null, 'getOAuthProvider'); $providers = PhabricatorOAuthProvider::getAllProviders(); foreach ($providers as $provider) { if (!$provider->isProviderEnabled()) { continue; } $provider_key = $provider->getProviderKey(); if (!isset($oauths[$provider_key])) { continue; } $name = $provider->getProviderName() . ' Profile'; $href = $oauths[$provider_key]->getAccountURI(); if ($href) { $links[] = phutil_render_tag('a', array('href' => $href), phutil_escape_html($name)); } } // TODO: perhaps, if someone wants to add to the profile of the user the // ability to show the task/revisions where he is working/commenting // on, this has to be changed to something like // |$this->page = key($pages)|, since the "page" regexp was added to // the aphrontconfiguration. if (empty($links[$this->page])) { $this->page = 'action'; } switch ($this->page) { default: $content = $this->renderBasicInformation($user, $profile); break; } $src_phid = $profile->getProfileImagePHID(); if (!$src_phid) { $src_phid = $user->getProfileImagePHID(); } $picture = PhabricatorFileURI::getViewURIForPHID($src_phid); $title = nonempty($profile->getTitle(), 'Untitled Document'); $realname = '(' . $user->getRealName() . ')'; $profile = new PhabricatorProfileView(); $profile->setProfilePicture($picture); $profile->setProfileNames($user->getUserName(), $realname, $title); foreach ($links as $page => $name) { if (is_integer($page)) { $profile->addProfileItem(phutil_render_tag('span', array(), $name)); } else { $profile->addProfileItem($page); } } $profile->appendChild($content); return $this->buildStandardPageResponse($profile, array('title' => $user->getUsername())); }
public function processRequest() { $request = $this->getRequest(); if ($request->getUser()->getPHID()) { // Kick the user out if they're already logged in. return id(new AphrontRedirectResponse())->setURI('/'); } $next_uri = $this->getRequest()->getPath(); $request->setCookie('next_uri', $next_uri); if ($next_uri == '/login/' && !$request->isFormPost()) { // The user went straight to /login/, so presumably they want to go // to the dashboard upon logging in. Because, you know, that's logical. // And people are logical. Sometimes... Fine, no they're not. // We check for POST here because getPath() would get reset to /login/. $request->setCookie('next_uri', '/'); } // Always use $request->getCookie('next_uri', '/') after the above. $password_auth = PhabricatorEnv::getEnvConfig('auth.password-auth-enabled'); $forms = array(); $error_view = null; if ($password_auth) { $error = false; $username_or_email = $request->getCookie('phusr'); if ($request->isFormPost()) { $username_or_email = $request->getStr('username_or_email'); $user = id(new PhabricatorUser())->loadOneWhere('username = %s', $username_or_email); if (!$user) { $user = id(new PhabricatorUser())->loadOneWhere('email = %s', $username_or_email); } $okay = false; if ($user) { if ($user->comparePassword($request->getStr('password'))) { $session_key = $user->establishSession('web'); $request->setCookie('phusr', $user->getUsername()); $request->setCookie('phsid', $session_key); return id(new AphrontRedirectResponse())->setURI($request->getCookie('next_uri', '/')); } else { $log = PhabricatorUserLog::newLog(null, $user, PhabricatorUserLog::ACTION_LOGIN_FAILURE); $log->save(); } } if (!$okay) { $request->clearCookie('phusr'); $request->clearCookie('phsid'); } $error = true; } if ($error) { $error_view = new AphrontErrorView(); $error_view->setTitle('Bad username/password.'); } $form = new AphrontFormView(); $form->setUser($request->getUser())->setAction('/login/')->appendChild(id(new AphrontFormTextControl())->setLabel('Username/Email')->setName('username_or_email')->setValue($username_or_email))->appendChild(id(new AphrontFormPasswordControl())->setLabel('Password')->setName('password')->setCaption('<a href="/login/email/">' . 'Forgot your password? / Email Login</a>'))->appendChild(id(new AphrontFormSubmitControl())->setValue('Login')); // $panel->setCreateButton('Register New Account', '/login/register/'); $forms['Phabricator Login'] = $form; } $providers = PhabricatorOAuthProvider::getAllProviders(); foreach ($providers as $provider) { $enabled = $provider->isProviderEnabled(); if (!$enabled) { continue; } $auth_uri = $provider->getAuthURI(); $redirect_uri = $provider->getRedirectURI(); $client_id = $provider->getClientID(); $provider_name = $provider->getProviderName(); $minimum_scope = $provider->getMinimumScope(); $extra_auth = $provider->getExtraAuthParameters(); // TODO: In theory we should use 'state' to prevent CSRF, but the total // effect of the CSRF attack is that an attacker can cause a user to login // to Phabricator if they're already logged into some OAuth provider. This // does not seem like the most severe threat in the world, and generating // CSRF for logged-out users is vaugely tricky. if ($provider->isProviderRegistrationEnabled()) { $title = "Login or Register with {$provider_name}"; $body = "Login or register for Phabricator using your " . "{$provider_name} account."; $button = "Login or Register with {$provider_name}"; } else { $title = "Login with {$provider_name}"; $body = "Login to your existing Phabricator account using your " . "{$provider_name} account.<br /><br /><strong>You can not use " . "{$provider_name} to register a new account.</strong>"; $button = "Login with {$provider_name}"; } $auth_form = new AphrontFormView(); $auth_form->setAction($auth_uri)->addHiddenInput('client_id', $client_id)->addHiddenInput('redirect_uri', $redirect_uri)->addHiddenInput('scope', $minimum_scope); foreach ($extra_auth as $key => $value) { $auth_form->addHiddenInput($key, $value); } $auth_form->setUser($request->getUser())->setMethod('GET')->appendChild('<p class="aphront-form-instructions">' . $body . '</p>')->appendChild(id(new AphrontFormSubmitControl())->setValue("{$button} »")); $forms[$title] = $auth_form; } $panel = new AphrontPanelView(); $panel->setWidth(AphrontPanelView::WIDTH_FORM); foreach ($forms as $name => $form) { $panel->appendChild('<h1>' . $name . '</h1>'); $panel->appendChild($form); $panel->appendChild('<br />'); } return $this->buildStandardPageResponse(array($error_view, $panel), array('title' => 'Login')); }
public function processRequest() { $request = $this->getRequest(); if ($request->getUser()->getPHID()) { // Kick the user out if they're already logged in. return id(new AphrontRedirectResponse())->setURI('/'); } if ($request->isConduit()) { // A common source of errors in Conduit client configuration is getting // the request path wrong. The client will end up here, so make some // effort to give them a comprehensible error message. $request_path = $this->getRequest()->getPath(); $conduit_path = '/api/<method>'; $example_path = '/api/conduit.ping'; $message = "ERROR: You are making a Conduit API request to '{$request_path}', " . "but the correct HTTP request path to use in order to access a " . "Conduit method is '{$conduit_path}' (for example, " . "'{$example_path}'). Check your configuration."; return id(new AphrontPlainTextResponse())->setContent($message); } $error_view = null; if ($request->getCookie('phusr') && $request->getCookie('phsid')) { // The session cookie is invalid, so clear it. $request->clearCookie('phusr'); $request->clearCookie('phsid'); $error_view = new AphrontErrorView(); $error_view->setTitle('Invalid Session'); $error_view->setErrors(array("Your login session is invalid. Try logging in again. If that " . "doesn't work, clear your browser cookies.")); } $next_uri = $this->getRequest()->getPath(); if ($next_uri == '/login/') { $next_uri = '/'; } if (!$request->isFormPost()) { $request->setCookie('next_uri', $next_uri); } $password_auth = PhabricatorEnv::getEnvConfig('auth.password-auth-enabled'); $forms = array(); $errors = array(); if ($password_auth) { $require_captcha = false; $e_captcha = true; $username_or_email = $request->getCookie('phusr'); if ($request->isFormPost()) { if (AphrontFormRecaptchaControl::isRecaptchaEnabled()) { $failed_attempts = PhabricatorUserLog::loadRecentEventsFromThisIP(PhabricatorUserLog::ACTION_LOGIN_FAILURE, 60 * 15); if (count($failed_attempts) > 5) { $require_captcha = true; if (!AphrontFormRecaptchaControl::processCaptcha($request)) { if (AphrontFormRecaptchaControl::hasCaptchaResponse($request)) { $e_captcha = 'Invalid'; $errors[] = 'CAPTCHA was not entered correctly.'; } else { $e_captcha = 'Required'; $errors[] = 'Too many login failures recently. You must ' . 'submit a CAPTCHA with your login request.'; } } } } $username_or_email = $request->getStr('username_or_email'); $user = id(new PhabricatorUser())->loadOneWhere('username = %s', $username_or_email); if (!$user) { $user = id(new PhabricatorUser())->loadOneWhere('email = %s', $username_or_email); } if (!$errors) { // Perform username/password tests only if we didn't get rate limited // by the CAPTCHA. if (!$user || !$user->comparePassword($request->getStr('password'))) { $errors[] = 'Bad username/password.'; } } if (!$errors) { $session_key = $user->establishSession('web'); $request->setCookie('phusr', $user->getUsername()); $request->setCookie('phsid', $session_key); $uri = new PhutilURI('/login/validate/'); $uri->setQueryParams(array('phusr' => $user->getUsername())); return id(new AphrontRedirectResponse())->setURI((string) $uri); } else { $log = PhabricatorUserLog::newLog(null, $user, PhabricatorUserLog::ACTION_LOGIN_FAILURE); $log->save(); $request->clearCookie('phusr'); $request->clearCookie('phsid'); } } if ($errors) { $error_view = new AphrontErrorView(); $error_view->setTitle('Login Failed'); $error_view->setErrors($errors); } $form = new AphrontFormView(); $form->setUser($request->getUser())->setAction('/login/')->appendChild(id(new AphrontFormTextControl())->setLabel('Username/Email')->setName('username_or_email')->setValue($username_or_email))->appendChild(id(new AphrontFormPasswordControl())->setLabel('Password')->setName('password')->setCaption('<a href="/login/email/">' . 'Forgot your password? / Email Login</a>')); if ($require_captcha) { $form->appendChild(id(new AphrontFormRecaptchaControl())->setError($e_captcha)); } $form->appendChild(id(new AphrontFormSubmitControl())->setValue('Login')); // $panel->setCreateButton('Register New Account', '/login/register/'); $forms['Phabricator Login'] = $form; } $providers = PhabricatorOAuthProvider::getAllProviders(); foreach ($providers as $provider) { $enabled = $provider->isProviderEnabled(); if (!$enabled) { continue; } $auth_uri = $provider->getAuthURI(); $redirect_uri = $provider->getRedirectURI(); $client_id = $provider->getClientID(); $provider_name = $provider->getProviderName(); $minimum_scope = $provider->getMinimumScope(); $extra_auth = $provider->getExtraAuthParameters(); // TODO: In theory we should use 'state' to prevent CSRF, but the total // effect of the CSRF attack is that an attacker can cause a user to login // to Phabricator if they're already logged into some OAuth provider. This // does not seem like the most severe threat in the world, and generating // CSRF for logged-out users is vaugely tricky. if ($provider->isProviderRegistrationEnabled()) { $title = "Login or Register with {$provider_name}"; $body = 'Login or register for Phabricator using your ' . phutil_escape_html($provider_name) . ' account.'; $button = "Login or Register with {$provider_name}"; } else { $title = "Login with {$provider_name}"; $body = 'Login to your existing Phabricator account using your ' . phutil_escape_html($provider_name) . ' account.<br /><br />' . '<strong>You can not use ' . phutil_escape_html($provider_name) . ' to register a new ' . 'account.</strong>'; $button = "Login with {$provider_name}"; } $auth_form = new AphrontFormView(); $auth_form->setAction($auth_uri)->addHiddenInput('client_id', $client_id)->addHiddenInput('redirect_uri', $redirect_uri)->addHiddenInput('scope', $minimum_scope); foreach ($extra_auth as $key => $value) { $auth_form->addHiddenInput($key, $value); } $auth_form->setUser($request->getUser())->setMethod('GET')->appendChild('<p class="aphront-form-instructions">' . $body . '</p>')->appendChild(id(new AphrontFormSubmitControl())->setValue("{$button} »")); $forms[$title] = $auth_form; } $panel = new AphrontPanelView(); $panel->setWidth(AphrontPanelView::WIDTH_FORM); foreach ($forms as $name => $form) { $panel->appendChild('<h1>' . $name . '</h1>'); $panel->appendChild($form); $panel->appendChild('<br />'); } return $this->buildStandardPageResponse(array($error_view, $panel), array('title' => 'Login')); }
public function processRequest() { $viewer = $this->getRequest()->getUser(); $user = id(new PhabricatorUser())->loadOneWhere('userName = %s', $this->username); if (!$user) { return new Aphront404Response(); } require_celerity_resource('phabricator-profile-css'); $profile = id(new PhabricatorUserProfile())->loadOneWhere('userPHID = %s', $user->getPHID()); if (!$profile) { $profile = new PhabricatorUserProfile(); } $username = phutil_escape_uri($user->getUserName()); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI('/p/' . $username . '/')); $nav->addFilter('feed', 'Feed'); $nav->addFilter('about', 'About'); $nav->addSpacer(); $nav->addLabel('Activity'); $external_arrow = "↗"; $nav->addFilter(null, "Revisions {$external_arrow}", '/differential/filter/revisions/' . $username . '/'); $nav->addFilter(null, "Tasks {$external_arrow}", '/maniphest/view/action/?users=' . $user->getPHID()); $nav->addFilter(null, "Commits {$external_arrow}", '/audit/view/author/' . $username . '/'); $oauths = id(new PhabricatorUserOAuthInfo())->loadAllWhere('userID = %d', $user->getID()); $oauths = mpull($oauths, null, 'getOAuthProvider'); $providers = PhabricatorOAuthProvider::getAllProviders(); $added_spacer = false; foreach ($providers as $provider) { if (!$provider->isProviderEnabled()) { continue; } $provider_key = $provider->getProviderKey(); if (!isset($oauths[$provider_key])) { continue; } $name = $provider->getProviderName() . ' Profile'; $href = $oauths[$provider_key]->getAccountURI(); if ($href) { if (!$added_spacer) { $nav->addSpacer(); $nav->addLabel('Linked Accounts'); $added_spacer = true; } $nav->addFilter(null, $name . ' ' . $external_arrow, $href); } } $this->page = $nav->selectFilter($this->page, 'feed'); switch ($this->page) { case 'feed': $content = $this->renderUserFeed($user); break; case 'about': $content = $this->renderBasicInformation($user, $profile); break; default: throw new Exception("Unknown page '{$this->page}'!"); } $picture = $user->loadProfileImageURI(); $header = new PhabricatorProfileHeaderView(); $header->setProfilePicture($picture)->setName($user->getUserName() . ' (' . $user->getRealName() . ')')->setDescription($profile->getTitle()); if ($user->getIsDisabled()) { $header->setStatus('Disabled'); } else { $statuses = id(new PhabricatorUserStatus())->loadCurrentStatuses(array($user->getPHID())); if ($statuses) { $header->setStatus(reset($statuses)->getStatusDescription($viewer)); } } $header->appendChild($nav); $nav->appendChild('<div style="padding: 1em;">' . $content . '</div>'); if ($user->getPHID() == $viewer->getPHID()) { $nav->addSpacer(); $nav->addFilter(null, 'Edit Profile...', '/settings/page/profile/'); } if ($viewer->getIsAdmin()) { $nav->addSpacer(); $nav->addFilter(null, 'Administrate User...', '/people/edit/' . $user->getID() . '/'); } return $this->buildStandardPageResponse($header, array('title' => $user->getUsername())); }
private function retrieveOAuthInfo(PhabricatorOAuthProvider $provider) { $oauth_info = id(new PhabricatorUserOAuthInfo())->loadOneWhere('oauthProvider = %s and oauthUID = %s', $provider->getProviderKey(), $provider->retrieveUserID()); $scope = $this->getRequest()->getStr('scope'); if (!$oauth_info) { $oauth_info = new PhabricatorUserOAuthInfo(); $oauth_info->setOAuthProvider($provider->getProviderKey()); $oauth_info->setOAuthUID($provider->retrieveUserID()); // some providers don't tell you what scope you got, so default // to the minimum Phabricator requires rather than assuming no scope if (!$scope) { $scope = $provider->getMinimumScope(); } } $oauth_info->setAccountURI($provider->retrieveUserAccountURI()); $oauth_info->setAccountName($provider->retrieveUserAccountName()); $oauth_info->setToken($provider->getAccessToken()); $oauth_info->setTokenStatus(PhabricatorUserOAuthInfo::TOKEN_STATUS_GOOD); $oauth_info->setTokenScope($scope); // If we have out-of-date expiration info, just clear it out. Then replace // it with good info if the provider gave it to us. $expires = $oauth_info->getTokenExpires(); if ($expires <= time()) { $expires = null; } if ($this->tokenExpires) { $expires = $this->tokenExpires; } $oauth_info->setTokenExpires($expires); return $oauth_info; }