Correct a parameter order swap in "diffusion.historyquery" for Mercurial
[phabricator.git] / src / applications / auth / xaction / PhabricatorAuthFactorProviderStatusTransaction.php
blob37674f7b386b2ce31fc3eaaa9373e6489e2751c2
1 <?php
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)
21 ->getName();
22 $new_display = PhabricatorAuthFactorProviderStatus::newForStatus($new)
23 ->getName();
25 return pht(
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) {
33 $errors = array();
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(
42 pht(
43 'Status "%s" is invalid. Valid statuses are: %s.',
44 $new_value,
45 implode(', ', array_keys($map))),
46 $xaction);
47 continue;
50 $require_key = 'security.require-multi-factor-auth';
51 $require_mfa = PhabricatorEnv::getEnvConfig($require_key);
53 if ($require_mfa) {
54 $status_active = PhabricatorAuthFactorProviderStatus::STATUS_ACTIVE;
55 if ($new_value !== $status_active) {
56 $active_providers = id(new PhabricatorAuthFactorProviderQuery())
57 ->setViewer($actor)
58 ->withStatuses(
59 array(
60 $status_active,
62 ->execute();
63 $active_providers = mpull($active_providers, null, 'getID');
64 unset($active_providers[$object->getID()]);
66 if (!$active_providers) {
67 $errors[] = $this->newInvalidError(
68 pht(
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.',
73 $require_key));
74 continue;
80 return $errors;
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
88 // MFA enrollment.
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');
97 queryfx(
98 $conn,
99 'UPDATE %R SET isEnrolledInMultiFactor = 0',
100 $table);