Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/auth/xaction/PhabricatorAuthFactorProviderStatusTransaction.php
12256 views
1
<?php
2
3
final class PhabricatorAuthFactorProviderStatusTransaction
4
extends PhabricatorAuthFactorProviderTransactionType {
5
6
const TRANSACTIONTYPE = 'status';
7
8
public function generateOldValue($object) {
9
return $object->getStatus();
10
}
11
12
public function applyInternalEffects($object, $value) {
13
$object->setStatus($value);
14
}
15
16
public function getTitle() {
17
$old = $this->getOldValue();
18
$new = $this->getNewValue();
19
20
$old_display = PhabricatorAuthFactorProviderStatus::newForStatus($old)
21
->getName();
22
$new_display = PhabricatorAuthFactorProviderStatus::newForStatus($new)
23
->getName();
24
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));
30
}
31
32
public function validateTransactions($object, array $xactions) {
33
$errors = array();
34
$actor = $this->getActor();
35
36
$map = PhabricatorAuthFactorProviderStatus::getMap();
37
foreach ($xactions as $xaction) {
38
$new_value = $xaction->getNewValue();
39
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;
48
}
49
50
$require_key = 'security.require-multi-factor-auth';
51
$require_mfa = PhabricatorEnv::getEnvConfig($require_key);
52
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,
61
))
62
->execute();
63
$active_providers = mpull($active_providers, null, 'getID');
64
unset($active_providers[$object->getID()]);
65
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;
75
}
76
}
77
}
78
}
79
80
return $errors;
81
}
82
83
public function didCommitTransaction($object, $value) {
84
$status = PhabricatorAuthFactorProviderStatus::newForStatus($value);
85
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.
89
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.
93
94
$table = new PhabricatorUser();
95
$conn = $table->establishConnection('w');
96
97
queryfx(
98
$conn,
99
'UPDATE %R SET isEnrolledInMultiFactor = 0',
100
$table);
101
}
102
103
}
104
105