mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-09 16:32:39 +01:00
Implement an approval queue
Summary: - Add an option for the queue. - By default, enable it. - Dump new users into the queue. - Send admins an email to approve them. Test Plan: - Registered new accounts with queue on and off. - As an admin, approved accounts and disabled the queue from email. Reviewers: btrahan Reviewed By: btrahan CC: aran Differential Revision: https://secure.phabricator.com/D7576
This commit is contained in:
parent
0fa411083f
commit
c0e1a63a63
8 changed files with 101 additions and 16 deletions
|
@ -181,6 +181,7 @@ $user->openTransaction();
|
|||
$editor->createNewUser($user, $email);
|
||||
} else {
|
||||
if ($verify_email) {
|
||||
$user->setIsEmailVerified(1);
|
||||
$verify_email->setIsVerified($set_verified ? 1 : 0);
|
||||
}
|
||||
$editor->updateUser($user, $verify_email);
|
||||
|
|
|
@ -42,6 +42,7 @@ if ($existing_email) {
|
|||
$user = new PhabricatorUser();
|
||||
$user->setUsername($username);
|
||||
$user->setRealname($realname);
|
||||
$user->setIsApproved(1);
|
||||
|
||||
$email_object = id(new PhabricatorUserEmail())
|
||||
->setAddress($email)
|
||||
|
|
|
@ -232,6 +232,19 @@ final class PhabricatorAuthRegisterController
|
|||
$user->setUsername($value_username);
|
||||
$user->setRealname($value_realname);
|
||||
|
||||
if ($is_setup) {
|
||||
$must_approve = false;
|
||||
} else {
|
||||
$must_approve = PhabricatorEnv::getEnvConfig(
|
||||
'auth.require-approval');
|
||||
}
|
||||
|
||||
if ($must_approve) {
|
||||
$user->setIsApproved(0);
|
||||
} else {
|
||||
$user->setIsApproved(1);
|
||||
}
|
||||
|
||||
$user->openTransaction();
|
||||
|
||||
$editor = id(new PhabricatorUserEditor())
|
||||
|
@ -257,6 +270,10 @@ final class PhabricatorAuthRegisterController
|
|||
$email_obj->sendVerificationEmail($user);
|
||||
}
|
||||
|
||||
if ($must_approve) {
|
||||
$this->sendWaitingForApprovalEmail($user);
|
||||
}
|
||||
|
||||
return $this->loginUser($user);
|
||||
} catch (AphrontQueryDuplicateKeyException $exception) {
|
||||
$same_username = id(new PhabricatorUser())->loadOneWhere(
|
||||
|
@ -506,4 +523,43 @@ final class PhabricatorAuthRegisterController
|
|||
array($message));
|
||||
}
|
||||
|
||||
private function sendWaitingForApprovalEmail(PhabricatorUser $user) {
|
||||
$title = '[Phabricator] '.pht(
|
||||
'New User "%s" Awaiting Approval',
|
||||
$user->getUsername());
|
||||
|
||||
$body = new PhabricatorMetaMTAMailBody();
|
||||
|
||||
$body->addRawSection(
|
||||
pht(
|
||||
'Newly registered user "%s" is awaiting account approval by an '.
|
||||
'administrator.',
|
||||
$user->getUsername()));
|
||||
|
||||
$body->addTextSection(
|
||||
pht('APPROVAL QUEUE'),
|
||||
PhabricatorEnv::getProductionURI(
|
||||
'/people/query/approval/'));
|
||||
|
||||
$body->addTextSection(
|
||||
pht('DISABLE APPROVAL QUEUE'),
|
||||
PhabricatorEnv::getProductionURI(
|
||||
'/config/edit/auth.require-approval/'));
|
||||
|
||||
$admins = id(new PhabricatorPeopleQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withIsAdmin(true)
|
||||
->execute();
|
||||
|
||||
if (!$admins) {
|
||||
return;
|
||||
}
|
||||
|
||||
$mail = id(new PhabricatorMetaMTAMail())
|
||||
->addTos(mpull($admins, 'getPHID'))
|
||||
->setSubject($title)
|
||||
->setBody($body->render())
|
||||
->saveAndSend();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -490,7 +490,7 @@ final class PhabricatorConfigEditController
|
|||
|
||||
$table[] = phutil_tag('tr', array(), array(
|
||||
phutil_tag('th', array(), $description),
|
||||
phutil_tag('th', array(), $value),
|
||||
phutil_tag('td', array(), $value),
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ final class PhabricatorAuthenticationConfigOptions
|
|||
"Maximum number of simultaneous web sessions each user is ".
|
||||
"permitted to have. Setting this to '1' will prevent a user from ".
|
||||
"logging in on more than one browser at the same time.")),
|
||||
$this->newOption('auth.sessions.conduit', 'int', 5)
|
||||
$this->newOption('auth.sessions.conduit', 'int', 5)
|
||||
->setSummary(
|
||||
pht(
|
||||
"Number of simultaneous Conduit sessions each user is permitted."))
|
||||
|
@ -29,7 +29,7 @@ final class PhabricatorAuthenticationConfigOptions
|
|||
pht(
|
||||
"Maximum number of simultaneous Conduit sessions each user is ".
|
||||
"permitted to have.")),
|
||||
$this->newOption('auth.require-email-verification', 'bool', false)
|
||||
$this->newOption('auth.require-email-verification', 'bool', false)
|
||||
->setBoolOptions(
|
||||
array(
|
||||
pht("Require email verification"),
|
||||
|
@ -41,24 +41,47 @@ final class PhabricatorAuthenticationConfigOptions
|
|||
pht(
|
||||
"If true, email addresses must be verified (by clicking a link ".
|
||||
"in an email) before a user can login. By default, verification ".
|
||||
"is optional unless 'auth.email-domains' is nonempty.")),
|
||||
$this->newOption('auth.email-domains', 'list<string>', array())
|
||||
"is optional unless {{auth.email-domains}} is nonempty.")),
|
||||
$this->newOption('auth.require-approval', 'bool', true)
|
||||
->setBoolOptions(
|
||||
array(
|
||||
pht("Require Administrators to Approve Accounts"),
|
||||
pht("Don't Require Manual Approval"),
|
||||
))
|
||||
->setSummary(
|
||||
pht("Require administrators to approve new accounts."))
|
||||
->setDescription(
|
||||
pht(
|
||||
"Newly registered Phabricator accounts can either be placed ".
|
||||
"into a manual approval queue for administrative review, or ".
|
||||
"automatically activated immediately. The approval queue is ".
|
||||
"enabled by default because it gives you greater control over ".
|
||||
"who can register an account and access Phabricator.\n\n".
|
||||
"If your install is completely public, or on a VPN, or users can ".
|
||||
"only register with a trusted provider like LDAP, or you've ".
|
||||
"otherwise configured Phabricator to prevent unauthorized ".
|
||||
"registration, you can disable the queue to reduce administrative ".
|
||||
"overhead.\n\n".
|
||||
"NOTE: Before you disable the queue, make sure ".
|
||||
"{{auth.email-domains}} is configured correctly for your ".
|
||||
"install!")),
|
||||
$this->newOption('auth.email-domains', 'list<string>', array())
|
||||
->setSummary(pht("Only allow registration from particular domains."))
|
||||
->setDescription(
|
||||
pht(
|
||||
"You can restrict allowed email addresses to certain domains ".
|
||||
"(like 'yourcompany.com') by setting a list of allowed domains ".
|
||||
"here. Users will only be allowed to register using email ".
|
||||
"(like `yourcompany.com`) by setting a list of allowed domains ".
|
||||
"here.\n\nUsers will only be allowed to register using email ".
|
||||
"addresses at one of the domains, and will only be able to add ".
|
||||
"new email addresses for these domains. If you configure this, ".
|
||||
"it implies 'auth.require-email-verification'.\n\n".
|
||||
"You should omit the '@' from domains. Note that the domain must ".
|
||||
"match exactly. If you allow 'yourcompany.com', that permits ".
|
||||
"'joe@yourcompany.com' but rejects 'joe@mail.yourcompany.com'."))
|
||||
"it implies {{auth.require-email-verification}}.\n\n".
|
||||
"You should omit the `@` from domains. Note that the domain must ".
|
||||
"match exactly. If you allow `yourcompany.com`, that permits ".
|
||||
"`joe@yourcompany.com` but rejects `joe@mail.yourcompany.com`."))
|
||||
->addExample(
|
||||
"yourcompany.com\nmail.yourcompany.com",
|
||||
pht('Valid Setting')),
|
||||
$this->newOption('auth.login-message', 'string', null)
|
||||
$this->newOption('auth.login-message', 'string', null)
|
||||
->setLocked(true)
|
||||
->setSummary(pht("A block of HTML displayed on the login screen."))
|
||||
->setDescription(
|
||||
|
@ -66,7 +89,7 @@ final class PhabricatorAuthenticationConfigOptions
|
|||
"You can provide an arbitrary block of HTML here, which will ".
|
||||
"appear on the login screen. Normally, you'd use this to provide ".
|
||||
"login or registration instructions to users.")),
|
||||
$this->newOption('account.editable', 'bool', true)
|
||||
$this->newOption('account.editable', 'bool', true)
|
||||
->setBoolOptions(
|
||||
array(
|
||||
pht("Allow editing"),
|
||||
|
@ -83,7 +106,7 @@ final class PhabricatorAuthenticationConfigOptions
|
|||
"synchronize account information from some other authoritative ".
|
||||
"system, you can disable this to ensure information remains ".
|
||||
"consistent across both systems.")),
|
||||
$this->newOption('account.minimum-password-length', 'int', 8)
|
||||
$this->newOption('account.minimum-password-length', 'int', 8)
|
||||
->setSummary(pht("Minimum password length."))
|
||||
->setDescription(
|
||||
pht(
|
||||
|
|
|
@ -182,6 +182,9 @@ final class PhabricatorPeopleEditController
|
|||
->setAddress($new_email)
|
||||
->setIsVerified(0);
|
||||
|
||||
// Automatically approve the user, since an admin is creating them.
|
||||
$user->setIsApproved(1);
|
||||
|
||||
id(new PhabricatorUserEditor())
|
||||
->setActor($admin)
|
||||
->createNewUser($user, $email);
|
||||
|
|
|
@ -30,7 +30,7 @@ final class PhabricatorUser
|
|||
protected $isAdmin = 0;
|
||||
protected $isDisabled = 0;
|
||||
protected $isEmailVerified = 0;
|
||||
protected $isApproved = 1;
|
||||
protected $isApproved = 0;
|
||||
|
||||
private $profileImage = null;
|
||||
private $profile = null;
|
||||
|
|
|
@ -181,7 +181,8 @@ abstract class PhabricatorTestCase extends ArcanistPhutilTestCase {
|
|||
|
||||
$user = id(new PhabricatorUser())
|
||||
->setRealName("Test User {$seed}}")
|
||||
->setUserName("test{$seed}");
|
||||
->setUserName("test{$seed}")
|
||||
->setIsApproved(1);
|
||||
|
||||
$email = id(new PhabricatorUserEmail())
|
||||
->setAddress("testuser{$seed}@example.com")
|
||||
|
|
Loading…
Reference in a new issue