mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-22 21:40:55 +01:00
Add a blanket "will login" event
Summary: Ref T1536. Facebook currently does a check which should be on-login in registration hooks, and this is generally a reasonable hook to provide. The "will login" event allows listeners to reject or modify a login, or just log it or whatever. NOTE: This doesn't cover non-web logins right now -- notably Conduit. That's presumably fine. (This can't land for a while, it depends on about 10 uncommitted revisions.) Test Plan: Logged out and in again. Reviewers: wez, btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T1536 Differential Revision: https://secure.phabricator.com/D6202
This commit is contained in:
parent
0250b48c05
commit
61a0c6d6e3
9 changed files with 64 additions and 29 deletions
|
@ -29,17 +29,54 @@ abstract class PhabricatorAuthController extends PhabricatorController {
|
|||
|
||||
}
|
||||
|
||||
protected function establishWebSession(PhabricatorUser $user) {
|
||||
$session_key = $user->establishSession('web');
|
||||
/**
|
||||
* Log a user into a web session and return an @{class:AphrontResponse} which
|
||||
* corresponds to continuing the login process.
|
||||
*
|
||||
* Normally, this is a redirect to the validation controller which makes sure
|
||||
* the user's cookies are set. However, event listeners can intercept this
|
||||
* event and do something else if they prefer.
|
||||
*
|
||||
* @param PhabricatorUser User to log the viewer in as.
|
||||
* @return AphrontResponse Response which continues the login process.
|
||||
*/
|
||||
protected function loginUser(PhabricatorUser $user) {
|
||||
|
||||
$response = $this->buildLoginValidateResponse($user);
|
||||
$session_type = 'web';
|
||||
|
||||
$event_type = PhabricatorEventType::TYPE_AUTH_WILLLOGINUSER;
|
||||
$event_data = array(
|
||||
'user' => $user,
|
||||
'type' => $session_type,
|
||||
'response' => $response,
|
||||
'shouldLogin' => true,
|
||||
);
|
||||
|
||||
$event = id(new PhabricatorEvent($event_type, $event_data))
|
||||
->setUser($user);
|
||||
PhutilEventEngine::dispatchEvent($event);
|
||||
|
||||
$should_login = $event->getValue('shouldLogin');
|
||||
if ($should_login) {
|
||||
$session_key = $user->establishSession($session_type);
|
||||
|
||||
// NOTE: We allow disabled users to login and roadblock them later, so
|
||||
// there's no check for users being disabled here.
|
||||
|
||||
$request = $this->getRequest();
|
||||
$request->setCookie('phusr', $user->getUsername());
|
||||
$request->setCookie('phsid', $session_key);
|
||||
|
||||
$this->clearRegistrationCookies();
|
||||
}
|
||||
|
||||
return $event->getValue('response');
|
||||
}
|
||||
|
||||
protected function clearRegistrationCookies() {
|
||||
$request = $this->getRequest();
|
||||
|
||||
// NOTE: We allow disabled users to login and roadblock them later, so
|
||||
// there's no check for users being disabled here.
|
||||
|
||||
$request->setCookie('phusr', $user->getUsername());
|
||||
$request->setCookie('phsid', $session_key);
|
||||
|
||||
// Clear the registration key.
|
||||
$request->clearCookie('phreg');
|
||||
|
||||
|
@ -47,11 +84,19 @@ abstract class PhabricatorAuthController extends PhabricatorController {
|
|||
$request->clearCookie('phcid');
|
||||
}
|
||||
|
||||
protected function buildLoginValidateResponse(PhabricatorUser $user) {
|
||||
private function buildLoginValidateResponse(PhabricatorUser $user) {
|
||||
$validate_uri = new PhutilURI($this->getApplicationURI('validate/'));
|
||||
$validate_uri->setQueryParam('phusr', $user->getUsername());
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI((string)$validate_uri);
|
||||
}
|
||||
|
||||
protected function renderError($message) {
|
||||
return $this->renderErrorPage(
|
||||
pht('Authentication Error'),
|
||||
array(
|
||||
$message,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -107,9 +107,7 @@ final class PhabricatorAuthLoginController
|
|||
'with a valid Phabricator user.'));
|
||||
}
|
||||
|
||||
$this->establishWebSession($user);
|
||||
|
||||
return $this->buildLoginValidateResponse($user);
|
||||
return $this->loginUser($user);
|
||||
}
|
||||
|
||||
private function processRegisterUser(PhabricatorExternalAccount $account) {
|
||||
|
@ -161,7 +159,7 @@ final class PhabricatorAuthLoginController
|
|||
return null;
|
||||
}
|
||||
|
||||
private function renderError($message) {
|
||||
protected function renderError($message) {
|
||||
$title = pht('Login Failed');
|
||||
|
||||
$view = new AphrontErrorView();
|
||||
|
|
|
@ -205,13 +205,11 @@ final class PhabricatorAuthRegisterController
|
|||
|
||||
$user->saveTransaction();
|
||||
|
||||
$this->establishWebSession($user);
|
||||
|
||||
if (!$email_obj->getIsVerified()) {
|
||||
$email_obj->sendVerificationEmail($user);
|
||||
}
|
||||
|
||||
return $this->buildLoginValidateResponse($user);
|
||||
return $this->loginUser($user);
|
||||
} catch (AphrontQueryDuplicateKeyException $exception) {
|
||||
$same_username = id(new PhabricatorUser())->loadOneWhere(
|
||||
'userName = %s',
|
||||
|
@ -480,7 +478,7 @@ final class PhabricatorAuthRegisterController
|
|||
}
|
||||
}
|
||||
|
||||
private function renderError($message) {
|
||||
protected function renderError($message) {
|
||||
return $this->renderErrorPage(
|
||||
pht('Registration Failed'),
|
||||
array($message));
|
||||
|
|
|
@ -180,7 +180,7 @@ final class PhabricatorAuthStartController
|
|||
return id(new AphrontPlainTextResponse())->setContent($message);
|
||||
}
|
||||
|
||||
private function renderError($message) {
|
||||
protected function renderError($message) {
|
||||
return $this->renderErrorPage(
|
||||
pht('Authentication Failure'),
|
||||
array($message));
|
||||
|
|
|
@ -73,8 +73,6 @@ final class PhabricatorEmailTokenController
|
|||
$target_email->save();
|
||||
unset($unguarded);
|
||||
|
||||
$this->establishWebSession($target_user);
|
||||
|
||||
$next = '/';
|
||||
if (!PhabricatorEnv::getEnvConfig('auth.password-auth-enabled')) {
|
||||
$panels = id(new PhabricatorSettingsPanelOAuth())->buildPanels();
|
||||
|
@ -95,6 +93,6 @@ final class PhabricatorEmailTokenController
|
|||
|
||||
$request->setCookie('next_uri', $next);
|
||||
|
||||
return $this->buildLoginValidateResponse($target_user);
|
||||
return $this->loginUser($target_user);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,9 +90,7 @@ final class PhabricatorLDAPLoginController extends PhabricatorAuthController {
|
|||
|
||||
$this->saveLDAPInfo($ldap_info);
|
||||
|
||||
$this->establishWebSession($known_user);
|
||||
|
||||
return $this->buildLoginValidateResponse($known_user);
|
||||
return $this->loginUser($known_user);
|
||||
}
|
||||
|
||||
$controller = newv('PhabricatorLDAPRegistrationController',
|
||||
|
|
|
@ -138,8 +138,7 @@ final class PhabricatorLoginController
|
|||
}
|
||||
|
||||
if (!$errors) {
|
||||
$this->establishWebSession($user);
|
||||
return $this->buildLoginValidateResponse($user);
|
||||
return $this->loginUser($user);
|
||||
} else {
|
||||
$log = PhabricatorUserLog::newLog(
|
||||
null,
|
||||
|
|
|
@ -148,9 +148,7 @@ final class PhabricatorOAuthLoginController
|
|||
|
||||
$this->saveOAuthInfo($oauth_info);
|
||||
|
||||
$this->establishWebSession($known_user);
|
||||
|
||||
return $this->buildLoginValidateResponse($known_user);
|
||||
return $this->loginUser($known_user);
|
||||
}
|
||||
|
||||
$oauth_email = $provider->retrieveUserEmail();
|
||||
|
|
|
@ -37,5 +37,6 @@ final class PhabricatorEventType extends PhutilEventType {
|
|||
|
||||
const TYPE_PEOPLE_DIDRENDERMENU = 'people.didRenderMenu';
|
||||
const TYPE_AUTH_WILLREGISTERUSER = 'auth.willRegisterUser';
|
||||
const TYPE_AUTH_WILLLOGINUSER = 'auth.willLoginUser';
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue