mirror of
https://we.phorge.it/source/phorge.git
synced 2025-03-27 19:50:21 +01:00
New Registration Workflow
Summary: Currently, registration and authentication are pretty messy. Two concrete problems: - The `PhabricatorLDAPRegistrationController` and `PhabricatorOAuthDefaultRegistrationController` controllers are giant copy/pastes of one another. This is really bad. - We can't practically implement OpenID because we can't reissue the authentication request. Additionally, the OAuth registration controller can be replaced wholesale by config, which is a huge API surface area and a giant mess. Broadly, the problem right now is that registration does too much: we hand it some set of indirect credentials (like OAuth tokens) and expect it to take those the entire way to a registered user. Instead, break registration into smaller steps: - User authenticates with remote service. - Phabricator pulls information (remote account ID, username, email, real name, profile picture, etc) from the remote service and saves it as `PhabricatorUserCredentials`. - Phabricator hands the `PhabricatorUserCredentials` to the registration form, which is agnostic about where they originate from: it can process LDAP credentials, OAuth credentials, plain old email credentials, HTTP basic auth credentials, etc. This doesn't do anything yet -- there is no way to create credentials objects (and no storage patch), but I wanted to get any initial feedback, especially about the event call for T2394. In particular, I think the implementation would look something like this: $profile = $event->getValue('profile') $username = $profile->getDefaultUsername(); $is_employee = is_this_a_facebook_employee($username); if (!$is_employee) { throw new Exception("You are not employed at Facebook."); } $fbid = get_fbid_for_facebook_username($username); $profile->setDefaultEmail($fbid); $profile->setCanEditUsername(false); $profile->setCanEditEmail(false); $profile->setCanEditRealName(false); $profile->setShouldVerifyEmail(true); Seem reasonable? Test Plan: N/A yet, probably fatals. Reviewers: vrana, btrahan, codeblock, chad Reviewed By: btrahan CC: aran, asherkin, nh, wez Maniphest Tasks: T1536, T2394 Differential Revision: https://secure.phabricator.com/D4647
This commit is contained in:
parent
8744cdb699
commit
db1cf41ec4
6 changed files with 616 additions and 0 deletions
|
@ -815,6 +815,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorAuditReplyHandler' => 'applications/audit/mail/PhabricatorAuditReplyHandler.php',
|
||||
'PhabricatorAuditStatusConstants' => 'applications/audit/constants/PhabricatorAuditStatusConstants.php',
|
||||
'PhabricatorAuthController' => 'applications/auth/controller/PhabricatorAuthController.php',
|
||||
'PhabricatorAuthRegisterController' => 'applications/auth/controller/PhabricatorAuthRegisterController.php',
|
||||
'PhabricatorAuthenticationConfigOptions' => 'applications/config/option/PhabricatorAuthenticationConfigOptions.php',
|
||||
'PhabricatorBarePageExample' => 'applications/uiexample/examples/PhabricatorBarePageExample.php',
|
||||
'PhabricatorBarePageView' => 'view/page/PhabricatorBarePageView.php',
|
||||
|
@ -1335,6 +1336,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorRecaptchaConfigOptions' => 'applications/config/option/PhabricatorRecaptchaConfigOptions.php',
|
||||
'PhabricatorRedirectController' => 'applications/base/controller/PhabricatorRedirectController.php',
|
||||
'PhabricatorRefreshCSRFController' => 'applications/auth/controller/PhabricatorRefreshCSRFController.php',
|
||||
'PhabricatorRegistrationProfile' => 'applications/people/storage/PhabricatorRegistrationProfile.php',
|
||||
'PhabricatorRemarkupControl' => 'view/form/control/PhabricatorRemarkupControl.php',
|
||||
'PhabricatorRemarkupRuleEmbedFile' => 'applications/files/remarkup/PhabricatorRemarkupRuleEmbedFile.php',
|
||||
'PhabricatorRemarkupRuleImageMacro' => 'applications/macro/remarkup/PhabricatorRemarkupRuleImageMacro.php',
|
||||
|
@ -2667,6 +2669,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorAuditPreviewController' => 'PhabricatorAuditController',
|
||||
'PhabricatorAuditReplyHandler' => 'PhabricatorMailReplyHandler',
|
||||
'PhabricatorAuthController' => 'PhabricatorController',
|
||||
'PhabricatorAuthRegisterController' => 'PhabricatorAuthController',
|
||||
'PhabricatorAuthenticationConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||
'PhabricatorBarePageExample' => 'PhabricatorUIExample',
|
||||
'PhabricatorBarePageView' => 'AphrontPageView',
|
||||
|
@ -3182,6 +3185,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorRecaptchaConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||
'PhabricatorRedirectController' => 'PhabricatorController',
|
||||
'PhabricatorRefreshCSRFController' => 'PhabricatorAuthController',
|
||||
'PhabricatorRegistrationProfile' => 'Phobject',
|
||||
'PhabricatorRemarkupControl' => 'AphrontFormTextAreaControl',
|
||||
'PhabricatorRemarkupRuleEmbedFile' => 'PhutilRemarkupRule',
|
||||
'PhabricatorRemarkupRuleImageMacro' => 'PhutilRemarkupRule',
|
||||
|
|
|
@ -29,4 +29,12 @@ final class PhabricatorApplicationAuth extends PhabricatorApplication {
|
|||
return $items;
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/auth/' => array(
|
||||
'register/(?P<akey>[^/]+)/' => 'PhabricatorAuthRegisterController',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,4 +14,39 @@ abstract class PhabricatorAuthController extends PhabricatorController {
|
|||
return $response->setContent($page->render());
|
||||
}
|
||||
|
||||
protected function renderErrorPage($title, array $messages) {
|
||||
$view = new AphrontErrorView();
|
||||
$view->setTitle($title);
|
||||
$view->setErrors($messages);
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
$view,
|
||||
array(
|
||||
'title' => $title,
|
||||
'device' => true,
|
||||
'dust' => true,
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
protected function establishWebSession(PhabricatorUser $user) {
|
||||
$session_key = $user->establishSession('web');
|
||||
|
||||
$request = $this->getRequest();
|
||||
|
||||
// NOTE: We allow disabled users to login and roadblock them later, so
|
||||
// there's no check for users being disabled here.
|
||||
|
||||
$request->setCookie('phusr', $user->getUsername());
|
||||
$request->setCookie('phsid', $session_key);
|
||||
$request->clearCookie('phreg');
|
||||
}
|
||||
|
||||
protected function buildLoginValidateResponse(PhabricatorUser $user) {
|
||||
$validate_uri = new PhutilURI($this->getApplicationURI('validate/'));
|
||||
$validate_uri->setQueryParam('phusr', $user->getUsername());
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI((string)$validate_uri);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,483 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorAuthRegisterController
|
||||
extends PhabricatorAuthController {
|
||||
|
||||
private $accountKey;
|
||||
private $account;
|
||||
private $provider;
|
||||
|
||||
public function shouldRequireLogin() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->accountKey = idx($data, 'akey');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
|
||||
if ($request->getUser()->isLoggedIn()) {
|
||||
return $this->renderError(pht('You are already logged in.'));
|
||||
}
|
||||
|
||||
if (strlen($this->accountKey)) {
|
||||
$response = $this->loadAccount();
|
||||
} else {
|
||||
$response = $this->loadDefaultAccount();
|
||||
}
|
||||
|
||||
if ($response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$account = $this->account;
|
||||
|
||||
$user = new PhabricatorUser();
|
||||
|
||||
$default_username = $account->getUsername();
|
||||
$default_realname = $account->getRealName();
|
||||
$default_email = $account->getEmail();
|
||||
if ($default_email) {
|
||||
// If the account source provided an email but it's not allowed by
|
||||
// the configuration, just pretend we didn't get an email at all.
|
||||
if (!PhabricatorUserEmail::isAllowedAddress($default_email)) {
|
||||
$default_email = null;
|
||||
}
|
||||
|
||||
// If the account source provided an email, but another account already
|
||||
// has that email, just pretend we didn't get an email.
|
||||
|
||||
// TODO: See T3340.
|
||||
|
||||
if ($default_email) {
|
||||
$same_email = id(new PhabricatorUserEmail())->loadOneWhere(
|
||||
'address = %s',
|
||||
$default_email);
|
||||
if ($same_email) {
|
||||
$default_email = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$profile = id(new PhabricatorRegistrationProfile())
|
||||
->setDefaultUsername($default_username)
|
||||
->setDefaultEmail($default_email)
|
||||
->setDefaultRealName($default_realname)
|
||||
->setCanEditUsername(true)
|
||||
->setCanEditEmail(($default_email === null))
|
||||
->setCanEditRealName(true)
|
||||
->setShouldVerifyEmail(false);
|
||||
|
||||
$event_type = PhabricatorEventType::TYPE_AUTH_WILLREGISTERUSER;
|
||||
$event_data = array(
|
||||
'account' => $account,
|
||||
'profile' => $profile,
|
||||
);
|
||||
|
||||
$event = id(new PhabricatorEvent($event_type, $event_data))
|
||||
->setUser($user);
|
||||
PhutilEventEngine::dispatchEvent($event);
|
||||
|
||||
$default_username = $profile->getDefaultUsername();
|
||||
$default_email = $profile->getDefaultEmail();
|
||||
$default_realname = $profile->getDefaultRealName();
|
||||
|
||||
$can_edit_username = $profile->getCanEditUsername();
|
||||
$can_edit_email = $profile->getCanEditEmail();
|
||||
$can_edit_realname = $profile->getCanEditRealName();
|
||||
|
||||
$must_set_password = $this->provider->shouldRequireRegistrationPassword();
|
||||
|
||||
$can_edit_anything = $profile->getCanEditAnything() || $must_set_password;
|
||||
$force_verify = $profile->getShouldVerifyEmail();
|
||||
|
||||
$value_username = $default_username;
|
||||
$value_realname = $default_realname;
|
||||
$value_email = $default_email;
|
||||
$value_password = null;
|
||||
|
||||
$errors = array();
|
||||
|
||||
$e_username = strlen($value_username) ? null : true;
|
||||
$e_realname = strlen($value_realname) ? null : true;
|
||||
$e_email = strlen($value_email) ? null : true;
|
||||
$e_password = true;
|
||||
|
||||
$min_len = PhabricatorEnv::getEnvConfig('account.minimum-password-length');
|
||||
$min_len = (int)$min_len;
|
||||
|
||||
if ($request->isFormPost() || !$can_edit_anything) {
|
||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||
|
||||
if ($can_edit_username) {
|
||||
$value_username = $request->getStr('username');
|
||||
if (!strlen($value_username)) {
|
||||
$e_username = pht('Required');
|
||||
$errors[] = pht('Username is required.');
|
||||
} else if (!PhabricatorUser::validateUsername($value_username)) {
|
||||
$e_username = pht('Invalid');
|
||||
$errors[] = PhabricatorUser::describeValidUsername();
|
||||
} else {
|
||||
$e_username = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($must_set_password) {
|
||||
$value_password = $request->getStr('password');
|
||||
$value_confirm = $request->getStr('confirm');
|
||||
if (!strlen($value_password)) {
|
||||
$e_password = pht('Required');
|
||||
$errors[] = pht('You must choose a password.');
|
||||
} else if ($value_password !== $value_confirm) {
|
||||
$e_password = pht('No Match');
|
||||
$errors[] = pht('Password and confirmation must match.');
|
||||
} else if (strlen($value_password) < $min_len) {
|
||||
$e_password = pht('Too Short');
|
||||
$errors[] = pht(
|
||||
'Password is too short (must be at least %d characters long).',
|
||||
$min_len);
|
||||
} else {
|
||||
$e_password = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($can_edit_email) {
|
||||
$value_email = $request->getStr('email');
|
||||
if (!strlen($value_email)) {
|
||||
$e_email = pht('Required');
|
||||
$errors[] = pht('Email is required.');
|
||||
} else if (!PhabricatorUserEmail::isAllowedAddress($value_email)) {
|
||||
$e_email = pht('Invalid');
|
||||
$errors[] = PhabricatorUserEmail::describeAllowedAddresses();
|
||||
} else {
|
||||
$e_email = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($can_edit_realname) {
|
||||
$value_realname = $request->getStr('realName');
|
||||
if (!strlen($value_realname)) {
|
||||
$e_realname = pht('Required');
|
||||
$errors[] = pht('Real name is required.');
|
||||
} else {
|
||||
$e_realname = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
$image = $this->loadProfilePicture($account);
|
||||
if ($image) {
|
||||
$user->setProfileImagePHID($image->getPHID());
|
||||
}
|
||||
|
||||
try {
|
||||
if ($force_verify) {
|
||||
$verify_email = true;
|
||||
} else {
|
||||
$verify_email =
|
||||
($account->getEmailVerified()) &&
|
||||
($value_email === $default_email);
|
||||
}
|
||||
|
||||
$email_obj = id(new PhabricatorUserEmail())
|
||||
->setAddress($value_email)
|
||||
->setIsVerified((int)$verify_email);
|
||||
|
||||
$user->setUsername($value_username);
|
||||
$user->setRealname($value_realname);
|
||||
|
||||
$user->openTransaction();
|
||||
|
||||
$editor = id(new PhabricatorUserEditor())
|
||||
->setActor($user);
|
||||
|
||||
$editor->createNewUser($user, $email_obj);
|
||||
if ($must_set_password) {
|
||||
$envelope = new PhutilOpaqueEnvelope($value_password);
|
||||
$editor->changePassword($user, $envelope);
|
||||
}
|
||||
|
||||
$account->setUserPHID($user->getPHID());
|
||||
$this->provider->willRegisterAccount($account);
|
||||
$account->save();
|
||||
|
||||
$user->saveTransaction();
|
||||
|
||||
$this->establishWebSession($user);
|
||||
|
||||
if (!$email_obj->getIsVerified()) {
|
||||
$email_obj->sendVerificationEmail($user);
|
||||
}
|
||||
|
||||
return $this->buildLoginValidateResponse($user);
|
||||
} catch (AphrontQueryDuplicateKeyException $exception) {
|
||||
$same_username = id(new PhabricatorUser())->loadOneWhere(
|
||||
'userName = %s',
|
||||
$user->getUserName());
|
||||
|
||||
$same_email = id(new PhabricatorUserEmail())->loadOneWhere(
|
||||
'address = %s',
|
||||
$value_email);
|
||||
|
||||
if ($same_username) {
|
||||
$e_username = pht('Duplicate');
|
||||
$errors[] = pht('Another user already has that username.');
|
||||
}
|
||||
|
||||
if ($same_email) {
|
||||
// TODO: See T3340.
|
||||
$e_email = pht('Duplicate');
|
||||
$errors[] = pht('Another user already has that email.');
|
||||
}
|
||||
|
||||
if (!$same_username && !$same_email) {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($unguarded);
|
||||
}
|
||||
|
||||
$error_view = null;
|
||||
if ($errors) {
|
||||
$error_view = new AphrontErrorView();
|
||||
$error_view->setTitle(pht('Registration Failed'));
|
||||
$error_view->setErrors($errors);
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($request->getUser())
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Username'))
|
||||
->setName('username')
|
||||
->setValue($value_username)
|
||||
->setError($e_username));
|
||||
|
||||
if ($must_set_password) {
|
||||
$form->appendChild(
|
||||
id(new AphrontFormPasswordControl())
|
||||
->setLabel(pht('Password'))
|
||||
->setName('password')
|
||||
->setError($e_password)
|
||||
->setCaption(
|
||||
$min_len
|
||||
? pht('Minimum length of %d characters.', $min_len)
|
||||
: null));
|
||||
$form->appendChild(
|
||||
id(new AphrontFormPasswordControl())
|
||||
->setLabel(pht('Confirm Password'))
|
||||
->setName('confirm')
|
||||
->setError($e_password));
|
||||
}
|
||||
|
||||
if ($can_edit_email) {
|
||||
$form->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Email'))
|
||||
->setName('email')
|
||||
->setValue($value_email)
|
||||
->setCaption(PhabricatorUserEmail::describeAllowedAddresses())
|
||||
->setError($e_email));
|
||||
}
|
||||
|
||||
if ($can_edit_realname) {
|
||||
$form->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel(pht('Real Name'))
|
||||
->setName('realName')
|
||||
->setValue($value_realname)
|
||||
->setError($e_realname));
|
||||
}
|
||||
|
||||
$form->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Create Account')));
|
||||
|
||||
$title = pht('Phabricator Registration');
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addCrumb(
|
||||
id(new PhabricatorCrumbView())
|
||||
->setName(pht('Register')));
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
array(
|
||||
$crumbs,
|
||||
$error_view,
|
||||
$form,
|
||||
),
|
||||
array(
|
||||
'title' => $title,
|
||||
'device' => true,
|
||||
'dust' => true,
|
||||
));
|
||||
}
|
||||
|
||||
private function loadAccount() {
|
||||
$request = $this->getRequest();
|
||||
|
||||
if (!$this->accountKey) {
|
||||
return $this->renderError(pht('Request did not include account key.'));
|
||||
}
|
||||
|
||||
$account = id(new PhabricatorExternalAccount())->loadOneWhere(
|
||||
'accountSecret = %s',
|
||||
$this->accountKey);
|
||||
|
||||
if (!$account) {
|
||||
return $this->renderError(pht('No registration account.'));
|
||||
}
|
||||
|
||||
if ($account->getUserPHID()) {
|
||||
return $this->renderError(
|
||||
pht(
|
||||
'The account you are attempting to register with is already '.
|
||||
'registered to another user.'));
|
||||
}
|
||||
|
||||
$registration_key = $request->getCookie('phreg');
|
||||
|
||||
// NOTE: This registration key check is not strictly necessary, because
|
||||
// we're only creating new accounts, not linking existing accounts. It
|
||||
// might be more hassle than it is worth, especially for email.
|
||||
//
|
||||
// The attack this prevents is getting to the registration screen, then
|
||||
// copy/pasting the URL and getting someone else to click it and complete
|
||||
// the process. They end up with an account bound to credentials you
|
||||
// control. This doesn't really let you do anything meaningful, though,
|
||||
// since you could have simply completed the process yourself.
|
||||
|
||||
if (!$registration_key) {
|
||||
return $this->renderError(
|
||||
pht(
|
||||
'Your browser did not submit a registration key with the request. '.
|
||||
'You must use the same browser to begin and complete registration. '.
|
||||
'Check that cookies are enabled and try again.'));
|
||||
}
|
||||
|
||||
if ($registration_key != $account->getProperty('registrationKey')) {
|
||||
return $this->renderError(
|
||||
pht(
|
||||
'Your browser submitted a different registration key than the one '.
|
||||
'associated with this account. You may need to clear your cookies.'));
|
||||
}
|
||||
|
||||
$other_account = id(new PhabricatorExternalAccount())->loadAllWhere(
|
||||
'accountType = %s AND accountDomain = %s AND accountID = %s
|
||||
AND id != %d',
|
||||
$account->getAccountType(),
|
||||
$account->getAccountDomain(),
|
||||
$account->getAccountID(),
|
||||
$account->getID());
|
||||
|
||||
if ($other_account) {
|
||||
return $this->renderError(
|
||||
pht(
|
||||
'The account you are attempting to register with already belongs '.
|
||||
'to another user.'));
|
||||
}
|
||||
|
||||
$provider = PhabricatorAuthProvider::getEnabledProviderByKey(
|
||||
$account->getProviderKey());
|
||||
|
||||
if (!$provider) {
|
||||
return $this->renderError(
|
||||
pht(
|
||||
'The account you are attempting to register with uses a nonexistent '.
|
||||
'or disabled authentication provider (with key "%s"). An '.
|
||||
'administrator may have recently disabled this provider.',
|
||||
$account->getProviderKey()));
|
||||
}
|
||||
|
||||
if (!$provider->shouldAllowRegistration()) {
|
||||
|
||||
// TODO: This is a routine error if you click "Login" on an external
|
||||
// auth source which doesn't allow registration. The error should be
|
||||
// more tailored.
|
||||
|
||||
return $this->renderError(
|
||||
pht(
|
||||
'The account you are attempting to register with uses an '.
|
||||
'authentication provider ("%s") which does not allow registration. '.
|
||||
'An administrator may have recently disabled registration with this '.
|
||||
'provider.',
|
||||
$provider->getProviderName()));
|
||||
}
|
||||
|
||||
$this->account = $account;
|
||||
$this->provider = $provider;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function loadDefaultAccount() {
|
||||
$providers = PhabricatorAuthProvider::getAllEnabledProviders();
|
||||
foreach ($providers as $key => $provider) {
|
||||
if (!$provider->shouldAllowRegistration()) {
|
||||
unset($providers[$key]);
|
||||
continue;
|
||||
}
|
||||
if (!$provider->isDefaultRegistrationProvider()) {
|
||||
unset($providers[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$providers) {
|
||||
return $this->renderError(
|
||||
pht(
|
||||
"There are no configured default registration providers."));
|
||||
} else if (count($providers) > 1) {
|
||||
return $this->renderError(
|
||||
pht(
|
||||
"There are too many configured default registration providers."));
|
||||
}
|
||||
|
||||
$this->account = $provider->getDefaultExternalAccount();
|
||||
$this->provider = $provider;
|
||||
return null;
|
||||
}
|
||||
|
||||
private function loadProfilePicture(PhabricatorExternalAccount $account) {
|
||||
$phid = $account->getProfileImagePHID();
|
||||
if (!$phid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// NOTE: Use of omnipotent user is okay here because the registering user
|
||||
// can not control the field value, and we can't use their user object to
|
||||
// do meaningful policy checks anyway since they have not registered yet.
|
||||
// Reaching this means the user holds the account secret key and the
|
||||
// registration secret key, and thus has permission to view the image.
|
||||
|
||||
$file = id(new PhabricatorFileQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withPHIDs(array($phid))
|
||||
->executeOne();
|
||||
if (!$file) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$xformer = new PhabricatorImageTransformer();
|
||||
return $xformer->executeProfileTransform(
|
||||
$file,
|
||||
$width = 50,
|
||||
$min_height = 50,
|
||||
$max_height = 50);
|
||||
} catch (Exception $ex) {
|
||||
phlog($ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private function renderError($message) {
|
||||
return $this->renderErrorPage(
|
||||
pht('Registration Failed'),
|
||||
array($message));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorRegistrationProfile extends Phobject {
|
||||
|
||||
private $defaultUsername;
|
||||
private $defaultEmail;
|
||||
private $defaultRealName;
|
||||
private $canEditUsername;
|
||||
private $canEditEmail;
|
||||
private $canEditRealName;
|
||||
private $shouldVerifyEmail;
|
||||
|
||||
public function setShouldVerifyEmail($should_verify_email) {
|
||||
$this->shouldVerifyEmail = $should_verify_email;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getShouldVerifyEmail() {
|
||||
return $this->shouldVerifyEmail;
|
||||
}
|
||||
|
||||
public function setCanEditEmail($can_edit_email) {
|
||||
$this->canEditEmail = $can_edit_email;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCanEditEmail() {
|
||||
return $this->canEditEmail;
|
||||
}
|
||||
|
||||
public function setCanEditRealName($can_edit_real_name) {
|
||||
$this->canEditRealName = $can_edit_real_name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCanEditRealName() {
|
||||
return $this->canEditRealName;
|
||||
}
|
||||
|
||||
|
||||
public function setCanEditUsername($can_edit_username) {
|
||||
$this->canEditUsername = $can_edit_username;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCanEditUsername() {
|
||||
return $this->canEditUsername;
|
||||
}
|
||||
|
||||
public function setDefaultEmail($default_email) {
|
||||
$this->defaultEmail = $default_email;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDefaultEmail() {
|
||||
return $this->defaultEmail;
|
||||
}
|
||||
|
||||
public function setDefaultRealName($default_real_name) {
|
||||
$this->defaultRealName = $default_real_name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDefaultRealName() {
|
||||
return $this->defaultRealName;
|
||||
}
|
||||
|
||||
|
||||
public function setDefaultUsername($default_username) {
|
||||
$this->defaultUsername = $default_username;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDefaultUsername() {
|
||||
return $this->defaultUsername;
|
||||
}
|
||||
|
||||
public function getCanEditAnything() {
|
||||
return $this->getCanEditUsername() ||
|
||||
$this->getCanEditEmail() ||
|
||||
$this->getCanEditRealName();
|
||||
}
|
||||
|
||||
}
|
|
@ -36,4 +36,6 @@ final class PhabricatorEventType extends PhutilEventType {
|
|||
const TYPE_UI_DIDRENDERHOVERCARD = 'ui.didRenderHovercard';
|
||||
|
||||
const TYPE_PEOPLE_DIDRENDERMENU = 'people.didRenderMenu';
|
||||
const TYPE_AUTH_WILLREGISTERUSER = 'auth.willRegisterUser';
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue