1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-30 02:32:42 +01:00

When a user takes actions while in a high security session, note it on the resulting transactions

Summary:
Ref T13197. See PHI873. Record when a user has MFA'd and add a little icon to the transaction, similar to the exiting "Silent" icon.

For now, this just makes this stuff more auditable. Future changes may add ways to require MFA for certain specific transactions, outside of the ones that already always require MFA (like revealing credentials).

Test Plan: {F5877960}

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13197

Differential Revision: https://secure.phabricator.com/D19665
This commit is contained in:
epriestley 2018-09-11 13:47:15 -07:00
parent 8268abcb78
commit f5e90a363e
7 changed files with 63 additions and 3 deletions

View file

@ -490,8 +490,7 @@ final class PhabricatorAuthSessionEngine extends Phobject {
PhabricatorAuthSession $session, PhabricatorAuthSession $session,
$force = false) { $force = false) {
$until = $session->getHighSecurityUntil(); if ($session->isHighSecuritySession() || $force) {
if ($until > time() || $force) {
return new PhabricatorAuthHighSecurityToken(); return new PhabricatorAuthHighSecurityToken();
} }

View file

@ -74,6 +74,22 @@ final class PhabricatorAuthSession extends PhabricatorAuthDAO
} }
} }
public function isHighSecuritySession() {
$until = $this->getHighSecurityUntil();
if (!$until) {
return false;
}
$now = PhabricatorTime::getNow();
if ($until < $now) {
return false;
}
return true;
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */ /* -( PhabricatorPolicyInterface )----------------------------------------- */

View file

@ -306,6 +306,14 @@ final class PhabricatorUser
return ($this->session !== self::ATTACHABLE); return ($this->session !== self::ATTACHABLE);
} }
public function hasHighSecuritySession() {
if (!$this->hasSession()) {
return false;
}
return $this->getSession()->isHighSecuritySession();
}
private function generateConduitCertificate() { private function generateConduitCertificate() {
return Filesystem::readRandomCharacters(255); return Filesystem::readRandomCharacters(255);
} }

View file

@ -850,6 +850,10 @@ abstract class PhabricatorApplicationTransactionEditor
$xaction->setIsSilentTransaction(true); $xaction->setIsSilentTransaction(true);
} }
if ($actor->hasHighSecuritySession()) {
$xaction->setIsMFATransaction(true);
}
return $xaction; return $xaction;
} }

View file

@ -165,6 +165,14 @@ abstract class PhabricatorApplicationTransaction
return (bool)$this->getMetadataValue('core.silent', false); return (bool)$this->getMetadataValue('core.silent', false);
} }
public function setIsMFATransaction($mfa) {
return $this->setMetadataValue('core.mfa', $mfa);
}
public function getIsMFATransaction() {
return (bool)$this->getMetadataValue('core.mfa', false);
}
public function attachComment( public function attachComment(
PhabricatorApplicationTransactionComment $comment) { PhabricatorApplicationTransactionComment $comment) {
$this->comment = $comment; $this->comment = $comment;
@ -1461,6 +1469,12 @@ abstract class PhabricatorApplicationTransaction
if ($is_silent != $xaction->getIsSilentTransaction()) { if ($is_silent != $xaction->getIsSilentTransaction()) {
return false; return false;
} }
// Don't group MFA and non-MFA transactions together.
$is_mfa = $this->getIsMFATransaction();
if ($is_mfa != $xaction->getIsMFATransaction()) {
return false;
}
} }
return true; return true;

View file

@ -424,7 +424,8 @@ class PhabricatorApplicationTransactionView extends AphrontView {
->setIcon($xaction->getIcon()) ->setIcon($xaction->getIcon())
->setColor($xaction->getColor()) ->setColor($xaction->getColor())
->setHideCommentOptions($this->getHideCommentOptions()) ->setHideCommentOptions($this->getHideCommentOptions())
->setIsSilent($xaction->getIsSilentTransaction()); ->setIsSilent($xaction->getIsSilentTransaction())
->setIsMFA($xaction->getIsMFATransaction());
list($token, $token_removed) = $xaction->getToken(); list($token, $token_removed) = $xaction->getToken();
if ($token) { if ($token) {

View file

@ -30,6 +30,7 @@ final class PHUITimelineEventView extends AphrontView {
private $badges = array(); private $badges = array();
private $pinboardItems = array(); private $pinboardItems = array();
private $isSilent; private $isSilent;
private $isMFA;
public function setAuthorPHID($author_phid) { public function setAuthorPHID($author_phid) {
$this->authorPHID = $author_phid; $this->authorPHID = $author_phid;
@ -187,6 +188,15 @@ final class PHUITimelineEventView extends AphrontView {
return $this->isSilent; return $this->isSilent;
} }
public function setIsMFA($is_mfa) {
$this->isMFA = $is_mfa;
return $this;
}
public function getIsMFA() {
return $this->isMFA;
}
public function setReallyMajorEvent($me) { public function setReallyMajorEvent($me) {
$this->reallyMajorEvent = $me; $this->reallyMajorEvent = $me;
return $this; return $this;
@ -590,6 +600,14 @@ final class PHUITimelineEventView extends AphrontView {
->setIcon('fa-bell-slash', 'red') ->setIcon('fa-bell-slash', 'red')
->setTooltip(pht('Silent Edit')); ->setTooltip(pht('Silent Edit'));
} }
// If this edit was applied while the actor was in high-security mode,
// provide a hint that it was extra authentic.
if ($this->getIsMFA()) {
$extra[] = id(new PHUIIconView())
->setIcon('fa-vcard', 'green')
->setTooltip(pht('MFA Authenticated'));
}
} }
$extra = javelin_tag( $extra = javelin_tag(