Page MenuHomePhabricator

D7572.diff

diff --git a/resources/sql/patches/20131112.userverified.1.col.sql b/resources/sql/patches/20131112.userverified.1.col.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/patches/20131112.userverified.1.col.sql
@@ -0,0 +1,10 @@
+ALTER TABLE {$NAMESPACE}_user.user
+ ADD isEmailVerified INT UNSIGNED NOT NULL;
+
+ALTER TABLE {$NAMESPACE}_user.user
+ ADD isApproved INT UNSIGNED NOT NULL;
+
+ALTER TABLE {$NAMESPACE}_user.user
+ ADD KEY `key_approved` (isApproved);
+
+UPDATE {$NAMESPACE}_user.user SET isApproved = 1;
diff --git a/resources/sql/patches/20131112.userverified.2.mig.php b/resources/sql/patches/20131112.userverified.2.mig.php
new file mode 100644
--- /dev/null
+++ b/resources/sql/patches/20131112.userverified.2.mig.php
@@ -0,0 +1,33 @@
+<?php
+
+$table = new PhabricatorUser();
+$conn_w = $table->establishConnection('w');
+
+foreach (new LiskMigrationIterator($table) as $user) {
+ $username = $user->getUsername();
+ echo "Migrating {$username}...\n";
+ if ($user->getIsEmailVerified()) {
+ // Email already verified.
+ continue;
+ }
+
+ $primary = $user->loadPrimaryEmail();
+ if (!$primary) {
+ // No primary email.
+ continue;
+ }
+
+ if (!$primary->getIsVerified()) {
+ // Primary email not verified.
+ continue;
+ }
+
+ // Primary email is verified, so mark the account as verified.
+ queryfx(
+ $conn_w,
+ 'UPDATE %T SET isEmailVerified = 1 WHERE id = %d',
+ $table->getTableName(),
+ $user->getID());
+}
+
+echo "Done.\n";
diff --git a/scripts/ssh/ssh-exec.php b/scripts/ssh/ssh-exec.php
--- a/scripts/ssh/ssh-exec.php
+++ b/scripts/ssh/ssh-exec.php
@@ -38,8 +38,8 @@
throw new Exception("Invalid username.");
}
- if ($user->getIsDisabled()) {
- throw new Exception("You have been exiled.");
+ if (!$user->isUserActivated()) {
+ throw new Exception(pht("Your account is not activated."));
}
if ($args->getArg('ssh-command')) {
diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php
--- a/src/__celerity_resource_map__.php
+++ b/src/__celerity_resource_map__.php
@@ -857,7 +857,7 @@
),
'aphront-dialog-view-css' =>
array(
- 'uri' => '/res/830fa2de/rsrc/css/aphront/dialog-view.css',
+ 'uri' => '/res/6b6a41c6/rsrc/css/aphront/dialog-view.css',
'type' => 'css',
'requires' =>
array(
@@ -1889,7 +1889,7 @@
),
'javelin-behavior-maniphest-batch-selector' =>
array(
- 'uri' => '/res/423c5f1b/rsrc/js/application/maniphest/behavior-batch-selector.js',
+ 'uri' => '/res/a82658b3/rsrc/js/application/maniphest/behavior-batch-selector.js',
'type' => 'js',
'requires' =>
array(
@@ -1917,7 +1917,7 @@
),
'javelin-behavior-maniphest-subpriority-editor' =>
array(
- 'uri' => '/res/1fa4961f/rsrc/js/application/maniphest/behavior-subpriorityeditor.js',
+ 'uri' => '/res/95f3d4a6/rsrc/js/application/maniphest/behavior-subpriorityeditor.js',
'type' => 'js',
'requires' =>
array(
@@ -4328,7 +4328,7 @@
), array(
'packages' =>
array(
- 'f0d63822' =>
+ 'd831cac3' =>
array(
'name' => 'core.pkg.css',
'symbols' =>
@@ -4377,7 +4377,7 @@
41 => 'phabricator-tag-view-css',
42 => 'phui-list-view-css',
),
- 'uri' => '/res/pkg/f0d63822/core.pkg.css',
+ 'uri' => '/res/pkg/d831cac3/core.pkg.css',
'type' => 'css',
),
'2c1dba03' =>
@@ -4552,7 +4552,7 @@
'uri' => '/res/pkg/49898640/maniphest.pkg.css',
'type' => 'css',
),
- '0a694954' =>
+ '0474f45c' =>
array(
'name' => 'maniphest.pkg.js',
'symbols' =>
@@ -4563,21 +4563,21 @@
3 => 'javelin-behavior-maniphest-transaction-expand',
4 => 'javelin-behavior-maniphest-subpriority-editor',
),
- 'uri' => '/res/pkg/0a694954/maniphest.pkg.js',
+ 'uri' => '/res/pkg/0474f45c/maniphest.pkg.js',
'type' => 'js',
),
),
'reverse' =>
array(
- 'aphront-dialog-view-css' => 'f0d63822',
- 'aphront-error-view-css' => 'f0d63822',
- 'aphront-list-filter-view-css' => 'f0d63822',
- 'aphront-pager-view-css' => 'f0d63822',
- 'aphront-panel-view-css' => 'f0d63822',
- 'aphront-table-view-css' => 'f0d63822',
- 'aphront-tokenizer-control-css' => 'f0d63822',
- 'aphront-tooltip-css' => 'f0d63822',
- 'aphront-typeahead-control-css' => 'f0d63822',
+ 'aphront-dialog-view-css' => 'd831cac3',
+ 'aphront-error-view-css' => 'd831cac3',
+ 'aphront-list-filter-view-css' => 'd831cac3',
+ 'aphront-pager-view-css' => 'd831cac3',
+ 'aphront-panel-view-css' => 'd831cac3',
+ 'aphront-table-view-css' => 'd831cac3',
+ 'aphront-tokenizer-control-css' => 'd831cac3',
+ 'aphront-tooltip-css' => 'd831cac3',
+ 'aphront-typeahead-control-css' => 'd831cac3',
'differential-changeset-view-css' => '1084b12b',
'differential-core-view-css' => '1084b12b',
'differential-inline-comment-editor' => '5e9e5c4e',
@@ -4591,7 +4591,7 @@
'differential-table-of-contents-css' => '1084b12b',
'diffusion-commit-view-css' => '7aa115b4',
'diffusion-icons-css' => '7aa115b4',
- 'global-drag-and-drop-css' => 'f0d63822',
+ 'global-drag-and-drop-css' => 'd831cac3',
'inline-comment-summary-css' => '1084b12b',
'javelin-aphlict' => '2c1dba03',
'javelin-behavior' => '3e3be199',
@@ -4623,11 +4623,11 @@
'javelin-behavior-konami' => '2c1dba03',
'javelin-behavior-lightbox-attachments' => '2c1dba03',
'javelin-behavior-load-blame' => '5e9e5c4e',
- 'javelin-behavior-maniphest-batch-selector' => '0a694954',
- 'javelin-behavior-maniphest-subpriority-editor' => '0a694954',
- 'javelin-behavior-maniphest-transaction-controls' => '0a694954',
- 'javelin-behavior-maniphest-transaction-expand' => '0a694954',
- 'javelin-behavior-maniphest-transaction-preview' => '0a694954',
+ 'javelin-behavior-maniphest-batch-selector' => '0474f45c',
+ 'javelin-behavior-maniphest-subpriority-editor' => '0474f45c',
+ 'javelin-behavior-maniphest-transaction-controls' => '0474f45c',
+ 'javelin-behavior-maniphest-transaction-expand' => '0474f45c',
+ 'javelin-behavior-maniphest-transaction-preview' => '0474f45c',
'javelin-behavior-phabricator-active-nav' => '2c1dba03',
'javelin-behavior-phabricator-autofocus' => '2c1dba03',
'javelin-behavior-phabricator-gesture' => '2c1dba03',
@@ -4666,56 +4666,56 @@
'javelin-util' => '3e3be199',
'javelin-vector' => '3e3be199',
'javelin-workflow' => '3e3be199',
- 'lightbox-attachment-css' => 'f0d63822',
+ 'lightbox-attachment-css' => 'd831cac3',
'maniphest-task-summary-css' => '49898640',
- 'phabricator-action-list-view-css' => 'f0d63822',
- 'phabricator-application-launch-view-css' => 'f0d63822',
+ 'phabricator-action-list-view-css' => 'd831cac3',
+ 'phabricator-application-launch-view-css' => 'd831cac3',
'phabricator-busy' => '2c1dba03',
'phabricator-content-source-view-css' => '1084b12b',
- 'phabricator-core-css' => 'f0d63822',
- 'phabricator-crumbs-view-css' => 'f0d63822',
+ 'phabricator-core-css' => 'd831cac3',
+ 'phabricator-crumbs-view-css' => 'd831cac3',
'phabricator-drag-and-drop-file-upload' => '5e9e5c4e',
'phabricator-dropdown-menu' => '2c1dba03',
'phabricator-file-upload' => '2c1dba03',
- 'phabricator-filetree-view-css' => 'f0d63822',
- 'phabricator-flag-css' => 'f0d63822',
+ 'phabricator-filetree-view-css' => 'd831cac3',
+ 'phabricator-flag-css' => 'd831cac3',
'phabricator-hovercard' => '2c1dba03',
- 'phabricator-jump-nav' => 'f0d63822',
+ 'phabricator-jump-nav' => 'd831cac3',
'phabricator-keyboard-shortcut' => '2c1dba03',
'phabricator-keyboard-shortcut-manager' => '2c1dba03',
- 'phabricator-main-menu-view' => 'f0d63822',
+ 'phabricator-main-menu-view' => 'd831cac3',
'phabricator-menu-item' => '2c1dba03',
- 'phabricator-nav-view-css' => 'f0d63822',
+ 'phabricator-nav-view-css' => 'd831cac3',
'phabricator-notification' => '2c1dba03',
- 'phabricator-notification-css' => 'f0d63822',
- 'phabricator-notification-menu-css' => 'f0d63822',
+ 'phabricator-notification-css' => 'd831cac3',
+ 'phabricator-notification-menu-css' => 'd831cac3',
'phabricator-object-selector-css' => '1084b12b',
'phabricator-phtize' => '2c1dba03',
'phabricator-prefab' => '2c1dba03',
'phabricator-project-tag-css' => '49898640',
- 'phabricator-remarkup-css' => 'f0d63822',
+ 'phabricator-remarkup-css' => 'd831cac3',
'phabricator-shaped-request' => '5e9e5c4e',
- 'phabricator-side-menu-view-css' => 'f0d63822',
- 'phabricator-standard-page-view' => 'f0d63822',
- 'phabricator-tag-view-css' => 'f0d63822',
+ 'phabricator-side-menu-view-css' => 'd831cac3',
+ 'phabricator-standard-page-view' => 'd831cac3',
+ 'phabricator-tag-view-css' => 'd831cac3',
'phabricator-textareautils' => '2c1dba03',
'phabricator-tooltip' => '2c1dba03',
- 'phabricator-transaction-view-css' => 'f0d63822',
- 'phabricator-zindex-css' => 'f0d63822',
- 'phui-button-css' => 'f0d63822',
- 'phui-form-css' => 'f0d63822',
- 'phui-form-view-css' => 'f0d63822',
- 'phui-header-view-css' => 'f0d63822',
- 'phui-icon-view-css' => 'f0d63822',
- 'phui-list-view-css' => 'f0d63822',
- 'phui-object-item-list-view-css' => 'f0d63822',
- 'phui-property-list-view-css' => 'f0d63822',
- 'phui-spacing-css' => 'f0d63822',
- 'sprite-apps-large-css' => 'f0d63822',
- 'sprite-gradient-css' => 'f0d63822',
- 'sprite-icons-css' => 'f0d63822',
- 'sprite-menu-css' => 'f0d63822',
- 'sprite-status-css' => 'f0d63822',
- 'syntax-highlighting-css' => 'f0d63822',
+ 'phabricator-transaction-view-css' => 'd831cac3',
+ 'phabricator-zindex-css' => 'd831cac3',
+ 'phui-button-css' => 'd831cac3',
+ 'phui-form-css' => 'd831cac3',
+ 'phui-form-view-css' => 'd831cac3',
+ 'phui-header-view-css' => 'd831cac3',
+ 'phui-icon-view-css' => 'd831cac3',
+ 'phui-list-view-css' => 'd831cac3',
+ 'phui-object-item-list-view-css' => 'd831cac3',
+ 'phui-property-list-view-css' => 'd831cac3',
+ 'phui-spacing-css' => 'd831cac3',
+ 'sprite-apps-large-css' => 'd831cac3',
+ 'sprite-gradient-css' => 'd831cac3',
+ 'sprite-icons-css' => 'd831cac3',
+ 'sprite-menu-css' => 'd831cac3',
+ 'sprite-status-css' => 'd831cac3',
+ 'syntax-highlighting-css' => 'd831cac3',
),
));
diff --git a/src/applications/auth/controller/PhabricatorEmailVerificationController.php b/src/applications/auth/controller/PhabricatorEmailVerificationController.php
--- a/src/applications/auth/controller/PhabricatorEmailVerificationController.php
+++ b/src/applications/auth/controller/PhabricatorEmailVerificationController.php
@@ -39,8 +39,20 @@
$continue = pht('Continue to Phabricator');
} else {
$guard = AphrontWriteGuard::beginScopedUnguardedWrites();
- $email->setIsVerified(1);
- $email->save();
+ $email->openTransaction();
+
+ $email->setIsVerified(1);
+ $email->save();
+
+ // If the user just verified their primary email address, mark their
+ // account as email verified.
+ $user_primary = $user->loadPrimaryEmail();
+ if ($user_primary->getID() == $email->getID()) {
+ $user->setIsEmailVerified(1);
+ $user->save();
+ }
+
+ $email->saveTransaction();
unset($guard);
$title = pht('Address Verified');
diff --git a/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php b/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php
--- a/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php
+++ b/src/applications/auth/controller/PhabricatorMustVerifyEmailController.php
@@ -31,42 +31,33 @@
$sent = new AphrontErrorView();
$sent->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
$sent->setTitle(pht('Email Sent'));
- $sent->appendChild(phutil_tag(
- 'p',
- array(),
+ $sent->appendChild(
pht(
'Another verification email was sent to %s.',
- phutil_tag('strong', array(), $email_address))));
+ phutil_tag('strong', array(), $email_address)));
}
- $error_view = new AphrontRequestFailureView();
- $error_view->setHeader(pht('Check Your Email'));
- $error_view->appendChild(phutil_tag('p', array(), pht(
- 'You must verify your email address to login. You should have a new '.
- 'email message from Phabricator with verification instructions in your '.
- 'inbox (%s).', phutil_tag('strong', array(), $email_address))));
- $error_view->appendChild(phutil_tag('p', array(), pht(
+ $must_verify = pht(
+ 'You must verify your email address to login. You should have a '.
+ 'new email message from Phabricator with verification instructions '.
+ 'in your inbox (%s).',
+ phutil_tag('strong', array(), $email_address));
+
+ $send_again = pht(
'If you did not receive an email, you can click the button below '.
- 'to try sending another one.')));
- $error_view->appendChild(phutil_tag_div(
- 'aphront-failure-continue',
- phabricator_form(
- $user,
- array(
- 'action' => '/login/mustverify/',
- 'method' => 'POST',
- ),
- phutil_tag(
- 'button',
- array(
- ),
- pht('Send Another Email')))));
+ 'to try sending another one.');
+ $dialog = id(new AphrontDialogView())
+ ->setUser($user)
+ ->setTitle(pht('Check Your Email'))
+ ->appendParagraph($must_verify)
+ ->appendParagraph($send_again)
+ ->addSubmitButton(pht('Send Another Email'));
return $this->buildApplicationPage(
array(
$sent,
- $error_view,
+ $dialog,
),
array(
'title' => pht('Must Verify Email'),
diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php
--- a/src/applications/base/controller/PhabricatorController.php
+++ b/src/applications/base/controller/PhabricatorController.php
@@ -114,12 +114,7 @@
if ($user->isLoggedIn()) {
if ($this->shouldRequireEmailVerification()) {
- $email = $user->loadPrimaryEmail();
- if (!$email) {
- throw new Exception(
- "No primary email address associated with this account!");
- }
- if (!$email->getIsVerified()) {
+ if (!$user->getIsEmailVerified()) {
$controller = new PhabricatorMustVerifyEmailController($request);
$this->setCurrentApplication($auth_application);
return $this->delegateToController($controller);
diff --git a/src/applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php b/src/applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php
--- a/src/applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php
+++ b/src/applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php
@@ -31,7 +31,7 @@
$u_unverified = $this->generateNewTestUser()
->setUsername('unverified')
->save();
- $u_unverified->loadPrimaryEmail()->setIsVerified(0)->save();
+ $u_unverified->setIsEmailVerified(0)->save();
$u_normal = $this->generateNewTestUser()
->setUsername('normal')
diff --git a/src/applications/conduit/controller/PhabricatorConduitAPIController.php b/src/applications/conduit/controller/PhabricatorConduitAPIController.php
--- a/src/applications/conduit/controller/PhabricatorConduitAPIController.php
+++ b/src/applications/conduit/controller/PhabricatorConduitAPIController.php
@@ -313,24 +313,11 @@
ConduitAPIRequest $request,
PhabricatorUser $user) {
- if ($user->getIsDisabled()) {
+ if (!$user->isUserActivated()) {
return array(
'ERR-USER-DISABLED',
- 'User is disabled.');
- }
-
- if (PhabricatorUserEmail::isEmailVerificationRequired()) {
- $email = $user->loadPrimaryEmail();
- if (!$email) {
- return array(
- 'ERR-USER-NOEMAIL',
- 'User has no primary email address.');
- }
- if (!$email->getIsVerified()) {
- return array(
- 'ERR-USER-UNVERIFIED',
- 'User has unverified email address.');
- }
+ pht('User account is not activated.'),
+ );
}
$request->setUser($user);
diff --git a/src/applications/diffusion/controller/DiffusionServeController.php b/src/applications/diffusion/controller/DiffusionServeController.php
--- a/src/applications/diffusion/controller/DiffusionServeController.php
+++ b/src/applications/diffusion/controller/DiffusionServeController.php
@@ -382,6 +382,11 @@
return null;
}
+ if (!$user->isUserActivated()) {
+ // User is not activated.
+ return null;
+ }
+
$password_entry = id(new PhabricatorRepositoryVCSPassword())
->loadOneWhere('userPHID = %s', $user->getPHID());
if (!$password_entry) {
@@ -394,11 +399,6 @@
return null;
}
- if ($user->getIsDisabled()) {
- // User is disabled.
- return null;
- }
-
return $user;
}
diff --git a/src/applications/herald/query/HeraldRuleQuery.php b/src/applications/herald/query/HeraldRuleQuery.php
--- a/src/applications/herald/query/HeraldRuleQuery.php
+++ b/src/applications/herald/query/HeraldRuleQuery.php
@@ -219,7 +219,7 @@
$rule->attachValidAuthor(false);
continue;
}
- if ($users[$author_phid]->getIsDisabled()) {
+ if (!$users[$author_phid]->isUserActivated()) {
$rule->attachValidAuthor(false);
continue;
}
diff --git a/src/applications/metamta/query/PhabricatorMetaMTAActorQuery.php b/src/applications/metamta/query/PhabricatorMetaMTAActorQuery.php
--- a/src/applications/metamta/query/PhabricatorMetaMTAActorQuery.php
+++ b/src/applications/metamta/query/PhabricatorMetaMTAActorQuery.php
@@ -82,6 +82,11 @@
$actor->setUndeliverable(
pht('This user is a bot; bot accounts do not receive mail.'));
}
+
+ // NOTE: We do send email to unapproved users, and to unverified users,
+ // because it would otherwise be impossible to get them to verify their
+ // email addresses. Possibly we should white-list this kind of mail and
+ // deny all other types of mail.
}
$email = idx($emails, $phid);
diff --git a/src/applications/metamta/receiver/PhabricatorMailReceiver.php b/src/applications/metamta/receiver/PhabricatorMailReceiver.php
--- a/src/applications/metamta/receiver/PhabricatorMailReceiver.php
+++ b/src/applications/metamta/receiver/PhabricatorMailReceiver.php
@@ -19,16 +19,13 @@
PhabricatorMetaMTAReceivedMail $mail,
PhabricatorUser $sender) {
- if ($sender->getIsDisabled()) {
+ if (!$sender->isUserActivated()) {
throw new PhabricatorMetaMTAReceivedMailProcessingException(
MetaMTAReceivedMailStatus::STATUS_DISABLED_SENDER,
pht(
- "Sender '%s' has a disabled user account.",
+ "Sender '%s' does not have an activated user account.",
$sender->getUsername()));
}
-
-
- return;
}
/**
diff --git a/src/applications/people/conduit/ConduitAPI_user_Method.php b/src/applications/people/conduit/ConduitAPI_user_Method.php
--- a/src/applications/people/conduit/ConduitAPI_user_Method.php
+++ b/src/applications/people/conduit/ConduitAPI_user_Method.php
@@ -32,6 +32,14 @@
$roles[] = 'unverified';
}
+ if ($user->getIsApproved()) {
+ $roles[] = 'approved';
+ }
+
+ if ($user->isUserActivated()) {
+ $roles[] = 'activated';
+ }
+
$return = array(
'phid' => $user->getPHID(),
'userName' => $user->getUserName(),
diff --git a/src/applications/people/controller/PhabricatorPeopleEditController.php b/src/applications/people/controller/PhabricatorPeopleEditController.php
--- a/src/applications/people/controller/PhabricatorPeopleEditController.php
+++ b/src/applications/people/controller/PhabricatorPeopleEditController.php
@@ -325,7 +325,9 @@
if ($user->getIsDisabled()) {
$roles[] = pht('Disabled');
}
-
+ if (!$user->getIsApproved()) {
+ $roles[] = pht('Not Approved');
+ }
if (!$roles) {
$roles[] = pht('Normal User');
}
diff --git a/src/applications/people/controller/PhabricatorPeopleListController.php b/src/applications/people/controller/PhabricatorPeopleListController.php
--- a/src/applications/people/controller/PhabricatorPeopleListController.php
+++ b/src/applications/people/controller/PhabricatorPeopleListController.php
@@ -61,6 +61,10 @@
$item->addIcon('disable', pht('Disabled'));
}
+ if (!$user->getIsApproved()) {
+ $item->addIcon('raise-priority', pht('Not Approved'));
+ }
+
if ($user->getIsAdmin()) {
$item->addIcon('highlight', pht('Admin'));
}
diff --git a/src/applications/people/customfield/PhabricatorUserRolesField.php b/src/applications/people/customfield/PhabricatorUserRolesField.php
--- a/src/applications/people/customfield/PhabricatorUserRolesField.php
+++ b/src/applications/people/customfield/PhabricatorUserRolesField.php
@@ -31,6 +31,9 @@
if ($user->getIsDisabled()) {
$roles[] = pht('Disabled');
}
+ if (!$user->getIsApproved()) {
+ $roles[] = pht('Not Approved');
+ }
if ($user->getIsSystemAgent()) {
$roles[] = pht('Bot');
}
diff --git a/src/applications/people/editor/PhabricatorUserEditor.php b/src/applications/people/editor/PhabricatorUserEditor.php
--- a/src/applications/people/editor/PhabricatorUserEditor.php
+++ b/src/applications/people/editor/PhabricatorUserEditor.php
@@ -41,6 +41,12 @@
// Always set a new user's email address to primary.
$email->setIsPrimary(1);
+ // If the primary address is already verified, also set the verified flag
+ // on the user themselves.
+ if ($email->getIsVerified()) {
+ $user->setIsEmailVerified(1);
+ }
+
$this->willAddEmail($email);
$user->openTransaction();
diff --git a/src/applications/people/event/PhabricatorPeopleHovercardEventListener.php b/src/applications/people/event/PhabricatorPeopleHovercardEventListener.php
--- a/src/applications/people/event/PhabricatorPeopleHovercardEventListener.php
+++ b/src/applications/people/event/PhabricatorPeopleHovercardEventListener.php
@@ -35,6 +35,8 @@
if ($user->getIsDisabled()) {
$hovercard->addField(pht('Account'), pht('Disabled'));
+ } else if (!$user->isUserActivated()) {
+ $hovercard->addField(pht('Account'), pht('Not Activated'));
} else {
$statuses = id(new PhabricatorUserStatus())->loadCurrentStatuses(
array($user->getPHID()));
diff --git a/src/applications/people/phid/PhabricatorPeoplePHIDTypeUser.php b/src/applications/people/phid/PhabricatorPeoplePHIDTypeUser.php
--- a/src/applications/people/phid/PhabricatorPeoplePHIDTypeUser.php
+++ b/src/applications/people/phid/PhabricatorPeoplePHIDTypeUser.php
@@ -38,7 +38,7 @@
$handle->setFullName(
$user->getUsername().' ('.$user->getRealName().')');
$handle->setImageURI($user->loadProfileImageURI());
- $handle->setDisabled($user->getIsDisabled());
+ $handle->setDisabled(!$user->isUserActivated());
if ($user->hasStatus()) {
$status = $user->getStatus();
$handle->setStatus($status->getTextStatus());
diff --git a/src/applications/people/remarkup/PhabricatorRemarkupRuleMention.php b/src/applications/people/remarkup/PhabricatorRemarkupRuleMention.php
--- a/src/applications/people/remarkup/PhabricatorRemarkupRuleMention.php
+++ b/src/applications/people/remarkup/PhabricatorRemarkupRuleMention.php
@@ -107,7 +107,7 @@
->setName('@'.$user->getUserName())
->setHref('/p/'.$user->getUserName().'/');
- if ($user->getIsDisabled()) {
+ if (!$user->isUserActivated()) {
$tag->setDotColor(PhabricatorTagView::COLOR_GREY);
} else {
$status = idx($user_statuses, $user->getPHID());
diff --git a/src/applications/people/search/PhabricatorUserSearchIndexer.php b/src/applications/people/search/PhabricatorUserSearchIndexer.php
--- a/src/applications/people/search/PhabricatorUserSearchIndexer.php
+++ b/src/applications/people/search/PhabricatorUserSearchIndexer.php
@@ -20,7 +20,7 @@
// TODO: Index the blurbs from their profile or something? Probably not
// actually useful...
- if (!$user->getIsDisabled()) {
+ if ($user->isUserActivated()) {
$doc->addRelationship(
PhabricatorSearchRelationship::RELATIONSHIP_OPEN,
$user->getPHID(),
diff --git a/src/applications/people/storage/PhabricatorUser.php b/src/applications/people/storage/PhabricatorUser.php
--- a/src/applications/people/storage/PhabricatorUser.php
+++ b/src/applications/people/storage/PhabricatorUser.php
@@ -29,6 +29,8 @@
protected $isSystemAgent = 0;
protected $isAdmin = 0;
protected $isDisabled = 0;
+ protected $isEmailVerified = 0;
+ protected $isApproved = 1;
private $profileImage = null;
private $profile = null;
@@ -51,11 +53,41 @@
return (bool)$this->isDisabled;
case 'isSystemAgent':
return (bool)$this->isSystemAgent;
+ case 'isEmailVerified':
+ return (bool)$this->isEmailVerified;
+ case 'isApproved':
+ return (bool)$this->isApproved;
default:
return parent::readField($field);
}
}
+
+ /**
+ * Is this a live account which has passed required approvals? Returns true
+ * if this is an enabled, verified (if required), approved (if required)
+ * account, and false otherwise.
+ *
+ * @return bool True if this is a standard, usable account.
+ */
+ public function isUserActivated() {
+ if ($this->getIsDisabled()) {
+ return false;
+ }
+
+ if (!$this->getIsApproved()) {
+ return false;
+ }
+
+ if (PhabricatorUserEmail::isEmailVerificationRequired()) {
+ if (!$this->getIsEmailVerified()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
diff --git a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
--- a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
+++ b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
@@ -1748,6 +1748,14 @@
'type' => 'sql',
'name' => $this->getPatchPath('20131107.buildlog.sql'),
),
+ '20131112.userverified.1.col.sql' => array(
+ 'type' => 'sql',
+ 'name' => $this->getPatchPath('20131112.userverified.1.col.sql'),
+ ),
+ '20131112.userverified.2.mig.php' => array(
+ 'type' => 'php',
+ 'name' => $this->getPatchPath('20131112.userverified.2.mig.php'),
+ ),
);
}
}
diff --git a/src/infrastructure/testing/PhabricatorTestCase.php b/src/infrastructure/testing/PhabricatorTestCase.php
--- a/src/infrastructure/testing/PhabricatorTestCase.php
+++ b/src/infrastructure/testing/PhabricatorTestCase.php
@@ -105,6 +105,11 @@
'phabricator.show-beta-applications',
true);
+ // Reset application settings to defaults, particularly policies.
+ $this->env->overrideEnvConfig(
+ 'phabricator.application-settings',
+ array());
+
// TODO: Remove this when we remove "releeph.installed".
$this->env->overrideEnvConfig('releeph.installed', true);
}
diff --git a/src/view/AphrontDialogView.php b/src/view/AphrontDialogView.php
--- a/src/view/AphrontDialogView.php
+++ b/src/view/AphrontDialogView.php
@@ -111,6 +111,16 @@
return $this;
}
+ public function appendParagraph($paragraph) {
+ return $this->appendChild(
+ phutil_tag(
+ 'p',
+ array(
+ 'class' => 'aphront-dialog-view-paragraph',
+ ),
+ $paragraph));
+ }
+
final public function render() {
require_celerity_resource('aphront-dialog-view-css');
diff --git a/webroot/rsrc/css/aphront/dialog-view.css b/webroot/rsrc/css/aphront/dialog-view.css
--- a/webroot/rsrc/css/aphront/dialog-view.css
+++ b/webroot/rsrc/css/aphront/dialog-view.css
@@ -124,3 +124,7 @@
.aphront-capability-details {
margin: 20px 0 4px;
}
+
+.aphront-dialog-view-paragraph + .aphront-dialog-view-paragraph {
+ margin-top: 16px;
+}

File Metadata

Mime Type
text/x-diff
Storage Engine
amazon-s3
Storage Format
Raw Data
Storage Handle
phabricator/sd/m5/xloxee4o6ju2wplq
Default Alt Text
D7572.diff (28 KB)

Event Timeline