1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-23 05:50: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:
epriestley 2013-06-16 16:35:36 -07:00
parent 0250b48c05
commit 61a0c6d6e3
9 changed files with 64 additions and 29 deletions

View file

@ -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,
));
}
}

View file

@ -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();

View file

@ -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));

View file

@ -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));

View file

@ -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);
}
}

View file

@ -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',

View file

@ -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,

View file

@ -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();

View file

@ -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';
}