3 final class PhabricatorAuthFactorProviderStatusTransaction
4 extends PhabricatorAuthFactorProviderTransactionType
{
6 const TRANSACTIONTYPE
= 'status';
8 public function generateOldValue($object) {
9 return $object->getStatus();
12 public function applyInternalEffects($object, $value) {
13 $object->setStatus($value);
16 public function getTitle() {
17 $old = $this->getOldValue();
18 $new = $this->getNewValue();
20 $old_display = PhabricatorAuthFactorProviderStatus
::newForStatus($old)
22 $new_display = PhabricatorAuthFactorProviderStatus
::newForStatus($new)
26 '%s changed the status of this provider from %s to %s.',
27 $this->renderAuthor(),
28 $this->renderValue($old_display),
29 $this->renderValue($new_display));
32 public function validateTransactions($object, array $xactions) {
34 $actor = $this->getActor();
36 $map = PhabricatorAuthFactorProviderStatus
::getMap();
37 foreach ($xactions as $xaction) {
38 $new_value = $xaction->getNewValue();
40 if (!isset($map[$new_value])) {
41 $errors[] = $this->newInvalidError(
43 'Status "%s" is invalid. Valid statuses are: %s.',
45 implode(', ', array_keys($map))),
50 $require_key = 'security.require-multi-factor-auth';
51 $require_mfa = PhabricatorEnv
::getEnvConfig($require_key);
54 $status_active = PhabricatorAuthFactorProviderStatus
::STATUS_ACTIVE
;
55 if ($new_value !== $status_active) {
56 $active_providers = id(new PhabricatorAuthFactorProviderQuery())
63 $active_providers = mpull($active_providers, null, 'getID');
64 unset($active_providers[$object->getID()]);
66 if (!$active_providers) {
67 $errors[] = $this->newInvalidError(
69 'You can not deprecate or disable the last active MFA '.
70 'provider while "%s" is enabled, because new users would '.
71 'be unable to enroll in MFA. Disable the MFA requirement '.
72 'in Config, or create or enable another MFA provider first.',
83 public function didCommitTransaction($object, $value) {
84 $status = PhabricatorAuthFactorProviderStatus
::newForStatus($value);
86 // If a provider has undergone a status change, reset the MFA enrollment
87 // cache for all users. This may immediately force a lot of users to redo
90 // We could be more surgical about this: we only really need to affect
91 // users who had a factor under the provider, and only really need to
92 // do anything if a provider was disabled. This is just a little simpler.
94 $table = new PhabricatorUser();
95 $conn = $table->establishConnection('w');
99 'UPDATE %R SET isEnrolledInMultiFactor = 0',