Changeset View
Changeset View
Standalone View
Standalone View
src/applications/auth/engine/PhabricatorAuthSessionEngine.php
<?php | <?php | ||||
/** | /** | ||||
* @task hisec High Security Mode | * | ||||
* @task use Using Sessions | |||||
* @task new Creating Sessions | |||||
* @task hisec High Security | |||||
* @task partial Partial Sessions | |||||
*/ | */ | ||||
final class PhabricatorAuthSessionEngine extends Phobject { | final class PhabricatorAuthSessionEngine extends Phobject { | ||||
/** | /** | ||||
* Session issued to normal users after they login through a standard channel. | * Session issued to normal users after they login through a standard channel. | ||||
* Associates the client with a standard user identity. | * Associates the client with a standard user identity. | ||||
*/ | */ | ||||
const KIND_USER = 'U'; | const KIND_USER = 'U'; | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | switch ($kind) { | ||||
case self::KIND_EXTERNAL: | case self::KIND_EXTERNAL: | ||||
return $kind; | return $kind; | ||||
default: | default: | ||||
return self::KIND_UNKNOWN; | return self::KIND_UNKNOWN; | ||||
} | } | ||||
} | } | ||||
/** | |||||
* Load the user identity associated with a session of a given type, | |||||
* identified by token. | |||||
* | |||||
* When the user presents a session token to an API, this method verifies | |||||
* it is of the correct type and loads the corresponding identity if the | |||||
* session exists and is valid. | |||||
* | |||||
* NOTE: `$session_type` is the type of session that is required by the | |||||
* loading context. This prevents use of a Conduit sesssion as a Web | |||||
* session, for example. | |||||
* | |||||
* @param const The type of session to load. | |||||
* @param string The session token. | |||||
* @return PhabricatorUser|null | |||||
* @task use | |||||
*/ | |||||
public function loadUserForSession($session_type, $session_token) { | public function loadUserForSession($session_type, $session_token) { | ||||
$session_kind = self::getSessionKindFromToken($session_token); | $session_kind = self::getSessionKindFromToken($session_token); | ||||
switch ($session_kind) { | switch ($session_kind) { | ||||
case self::KIND_ANONYMOUS: | case self::KIND_ANONYMOUS: | ||||
// Don't bother trying to load a user for an anonymous session, since | // Don't bother trying to load a user for an anonymous session, since | ||||
// neither the session nor the user exist. | // neither the session nor the user exist. | ||||
return null; | return null; | ||||
case self::KIND_UNKNOWN: | case self::KIND_UNKNOWN: | ||||
▲ Show 20 Lines • Show All 135 Lines • ▼ Show 20 Lines | $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); | ||||
$log->setSession($digest_key); | $log->setSession($digest_key); | ||||
$log->save(); | $log->save(); | ||||
unset($unguarded); | unset($unguarded); | ||||
return $session_key; | return $session_key; | ||||
} | } | ||||
/* -( High Security )------------------------------------------------------ */ | |||||
/** | /** | ||||
* Require high security, or prompt the user to enter high security. | * Require high security, or prompt the user to enter high security. | ||||
* | * | ||||
* If the user's session is in high security, this method will return a | * If the user's session is in high security, this method will return a | ||||
* token. Otherwise, it will throw an exception which will eventually | * token. Otherwise, it will throw an exception which will eventually | ||||
* be converted into a multi-factor authentication workflow. | * be converted into a multi-factor authentication workflow. | ||||
* | * | ||||
* @param PhabricatorUser User whose session needs to be in high security. | * @param PhabricatorUser User whose session needs to be in high security. | ||||
* @param AphrontReqeust Current request. | * @param AphrontReqeust Current request. | ||||
* @param string URI to return the user to if they cancel. | * @param string URI to return the user to if they cancel. | ||||
* @return PhabricatorAuthHighSecurityToken Security token. | * @return PhabricatorAuthHighSecurityToken Security token. | ||||
* @task hisec | |||||
*/ | */ | ||||
public function requireHighSecuritySession( | public function requireHighSecuritySession( | ||||
PhabricatorUser $viewer, | PhabricatorUser $viewer, | ||||
AphrontRequest $request, | AphrontRequest $request, | ||||
$cancel_uri) { | $cancel_uri) { | ||||
if (!$viewer->hasSession()) { | if (!$viewer->hasSession()) { | ||||
throw new Exception( | throw new Exception( | ||||
▲ Show 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | /* -( High Security )------------------------------------------------------ */ | ||||
/** | /** | ||||
* Issue a high security token for a session, if authorized. | * Issue a high security token for a session, if authorized. | ||||
* | * | ||||
* @param PhabricatorAuthSession Session to issue a token for. | * @param PhabricatorAuthSession Session to issue a token for. | ||||
* @param bool Force token issue. | * @param bool Force token issue. | ||||
* @return PhabricatorAuthHighSecurityToken|null Token, if authorized. | * @return PhabricatorAuthHighSecurityToken|null Token, if authorized. | ||||
* @task hisec | |||||
*/ | */ | ||||
private function issueHighSecurityToken( | private function issueHighSecurityToken( | ||||
PhabricatorAuthSession $session, | PhabricatorAuthSession $session, | ||||
$force = false) { | $force = false) { | ||||
$until = $session->getHighSecurityUntil(); | $until = $session->getHighSecurityUntil(); | ||||
if ($until > time() || $force) { | if ($until > time() || $force) { | ||||
return new PhabricatorAuthHighSecurityToken(); | return new PhabricatorAuthHighSecurityToken(); | ||||
} | } | ||||
return null; | return null; | ||||
} | } | ||||
/** | /** | ||||
* Render a form for providing relevant multi-factor credentials. | * Render a form for providing relevant multi-factor credentials. | ||||
* | * | ||||
* @param PhabricatorUser Viewing user. | * @param PhabricatorUser Viewing user. | ||||
* @param AphrontRequest Current request. | * @param AphrontRequest Current request. | ||||
* @return AphrontFormView Renderable form. | * @return AphrontFormView Renderable form. | ||||
* @task hisec | |||||
*/ | */ | ||||
public function renderHighSecurityForm( | public function renderHighSecurityForm( | ||||
array $factors, | array $factors, | ||||
array $validation_results, | array $validation_results, | ||||
PhabricatorUser $viewer, | PhabricatorUser $viewer, | ||||
AphrontRequest $request) { | AphrontRequest $request) { | ||||
$form = id(new AphrontFormView()) | $form = id(new AphrontFormView()) | ||||
Show All 9 Lines | public function renderHighSecurityForm( | ||||
} | } | ||||
$form->appendRemarkupInstructions(''); | $form->appendRemarkupInstructions(''); | ||||
return $form; | return $form; | ||||
} | } | ||||
/** | |||||
* Strip the high security flag from a session. | |||||
* | |||||
* Kicks a session out of high security and logs the exit. | |||||
* | |||||
* @param PhabricatorUser Acting user. | |||||
* @param PhabricatorAuthSession Session to return to normal security. | |||||
* @return void | |||||
* @task hisec | |||||
*/ | |||||
public function exitHighSecurity( | public function exitHighSecurity( | ||||
PhabricatorUser $viewer, | PhabricatorUser $viewer, | ||||
PhabricatorAuthSession $session) { | PhabricatorAuthSession $session) { | ||||
if (!$session->getHighSecurityUntil()) { | |||||
return; | |||||
} | |||||
queryfx( | queryfx( | ||||
$session->establishConnection('w'), | $session->establishConnection('w'), | ||||
'UPDATE %T SET highSecurityUntil = NULL WHERE id = %d', | 'UPDATE %T SET highSecurityUntil = NULL WHERE id = %d', | ||||
$session->getTableName(), | $session->getTableName(), | ||||
$session->getID()); | $session->getID()); | ||||
$log = PhabricatorUserLog::initializeNewLog( | $log = PhabricatorUserLog::initializeNewLog( | ||||
$viewer, | $viewer, | ||||
$viewer->getPHID(), | $viewer->getPHID(), | ||||
PhabricatorUserLog::ACTION_EXIT_HISEC); | PhabricatorUserLog::ACTION_EXIT_HISEC); | ||||
$log->save(); | $log->save(); | ||||
} | } | ||||
/* -( Partial Sessions )--------------------------------------------------- */ | |||||
/** | /** | ||||
* Upgrade a partial session to a full session. | * Upgrade a partial session to a full session. | ||||
* | * | ||||
* @param PhabricatorAuthSession Session to upgrade. | * @param PhabricatorAuthSession Session to upgrade. | ||||
* @return void | * @return void | ||||
* @task partial | |||||
*/ | */ | ||||
public function upgradePartialSession(PhabricatorUser $viewer) { | public function upgradePartialSession(PhabricatorUser $viewer) { | ||||
if (!$viewer->hasSession()) { | if (!$viewer->hasSession()) { | ||||
throw new Exception( | throw new Exception( | ||||
pht('Upgrading partial session of user with no session!')); | pht('Upgrading partial session of user with no session!')); | ||||
} | } | ||||
$session = $viewer->getSession(); | $session = $viewer->getSession(); | ||||
Show All 25 Lines |