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