1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-26 08:42:41 +01:00

Raise an "Account Setup Issue" if your primary address is unverified

Summary:
Ref T12237. This adds a UI cue for users who have unverified primary addresses, since we no longer send them mail.

Also adds a new `bin/mail unverify` to unverify an address (for example, because mail is bouncing).

Test Plan:
  - Unverified my address, saw setup issue.
  - Verified my address, no more setup issue.

{F2861820}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T12237

Differential Revision: https://secure.phabricator.com/D17344
This commit is contained in:
epriestley 2017-02-13 09:45:25 -08:00
parent 037c749ef3
commit 3cf6f746f0
5 changed files with 283 additions and 0 deletions

View file

@ -2947,6 +2947,7 @@ phutil_register_library_map(array(
'PhabricatorMailManagementSendTestWorkflow' => 'applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php',
'PhabricatorMailManagementShowInboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementShowInboundWorkflow.php',
'PhabricatorMailManagementShowOutboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementShowOutboundWorkflow.php',
'PhabricatorMailManagementUnverifyWorkflow' => 'applications/metamta/management/PhabricatorMailManagementUnverifyWorkflow.php',
'PhabricatorMailManagementVolumeWorkflow' => 'applications/metamta/management/PhabricatorMailManagementVolumeWorkflow.php',
'PhabricatorMailManagementWorkflow' => 'applications/metamta/management/PhabricatorMailManagementWorkflow.php',
'PhabricatorMailOutboundMailHeraldAdapter' => 'applications/metamta/herald/PhabricatorMailOutboundMailHeraldAdapter.php',
@ -3772,6 +3773,7 @@ phutil_register_library_map(array(
'PhabricatorSettingsDeveloperPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsDeveloperPanelGroup.php',
'PhabricatorSettingsEditEngine' => 'applications/settings/editor/PhabricatorSettingsEditEngine.php',
'PhabricatorSettingsEmailPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsEmailPanelGroup.php',
'PhabricatorSettingsIssueController' => 'applications/settings/controller/PhabricatorSettingsIssueController.php',
'PhabricatorSettingsListController' => 'applications/settings/controller/PhabricatorSettingsListController.php',
'PhabricatorSettingsLogsPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsLogsPanelGroup.php',
'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php',
@ -8009,6 +8011,7 @@ phutil_register_library_map(array(
'PhabricatorMailManagementSendTestWorkflow' => 'PhabricatorMailManagementWorkflow',
'PhabricatorMailManagementShowInboundWorkflow' => 'PhabricatorMailManagementWorkflow',
'PhabricatorMailManagementShowOutboundWorkflow' => 'PhabricatorMailManagementWorkflow',
'PhabricatorMailManagementUnverifyWorkflow' => 'PhabricatorMailManagementWorkflow',
'PhabricatorMailManagementVolumeWorkflow' => 'PhabricatorMailManagementWorkflow',
'PhabricatorMailManagementWorkflow' => 'PhabricatorManagementWorkflow',
'PhabricatorMailOutboundMailHeraldAdapter' => 'HeraldAdapter',
@ -9021,6 +9024,7 @@ phutil_register_library_map(array(
'PhabricatorSettingsDeveloperPanelGroup' => 'PhabricatorSettingsPanelGroup',
'PhabricatorSettingsEditEngine' => 'PhabricatorEditEngine',
'PhabricatorSettingsEmailPanelGroup' => 'PhabricatorSettingsPanelGroup',
'PhabricatorSettingsIssueController' => 'PhabricatorController',
'PhabricatorSettingsListController' => 'PhabricatorController',
'PhabricatorSettingsLogsPanelGroup' => 'PhabricatorSettingsPanelGroup',
'PhabricatorSettingsMainController' => 'PhabricatorController',

View file

@ -0,0 +1,110 @@
<?php
final class PhabricatorMailManagementUnverifyWorkflow
extends PhabricatorMailManagementWorkflow {
protected function didConstruct() {
$this
->setName('unverify')
->setSynopsis(
pht('Unverify an email address so it no longer receives mail.'))
->setExamples('**unverify** __address__ ...')
->setArguments(
array(
array(
'name' => 'addresses',
'wildcard' => true,
'help' => pht('Address (or addresses) to unverify.'),
),
));
}
public function execute(PhutilArgumentParser $args) {
$console = PhutilConsole::getConsole();
$viewer = $this->getViewer();
$addresses = $args->getArg('addresses');
if (!$addresses) {
throw new PhutilArgumentUsageException(
pht('Specify one or more email addresses to unverify.'));
}
foreach ($addresses as $address) {
$email = id(new PhabricatorUserEmail())->loadOneWhere(
'address = %s',
$address);
if (!$email) {
echo tsprintf(
"%s\n",
pht(
'Address "%s" is unknown.',
$address));
continue;
}
$user_phid = $email->getUserPHID();
$user = id(new PhabricatorPeopleQuery())
->setViewer($viewer)
->withPHIDs(array($user_phid))
->executeOne();
if (!$user) {
echo tsprintf(
"%s\n",
pht(
'Address "%s" belongs to invalid user "%s".',
$address,
$user_phid));
continue;
}
if (!$email->getIsVerified()) {
echo tsprintf(
"%s\n",
pht(
'Address "%s" (owned by "%s") is already unveriifed.',
$address,
$user->getUsername()));
continue;
}
$email->openTransaction();
$email
->setIsVerified(0)
->save();
if ($email->getIsPrimary()) {
$user
->setIsEmailVerified(0)
->save();
}
$email->saveTransaction();
if ($email->getIsPrimary()) {
echo tsprintf(
"%s\n",
pht(
'Unverified "%s", the primary address for "%s".',
$address,
$user->getUsername()));
} else {
echo tsprintf(
"%s\n",
pht(
'Unverified "%s", an address for "%s".',
$address,
$user->getUsername()));
}
}
echo tsprintf(
"%s\n",
pht('Done.'));
return 0;
}
}

View file

@ -41,6 +41,7 @@ final class PhabricatorSettingsApplication extends PhabricatorApplication {
'adjust/' => 'PhabricatorSettingsAdjustController',
'timezone/(?P<offset>[^/]+)/'
=> 'PhabricatorSettingsTimezoneController',
'issue/' => 'PhabricatorSettingsIssueController',
),
);
}

View file

@ -0,0 +1,103 @@
<?php
final class PhabricatorSettingsIssueController
extends PhabricatorController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$setup_uri = id(new PhabricatorEmailAddressesSettingsPanel())
->setViewer($viewer)
->setUser($viewer)
->getPanelURI();
$issues = array();
if (!$viewer->getIsEmailVerified()) {
// We could specifically detect that the user has missed email because
// their address is unverified here and point them at Mail so they can
// look at messages they missed.
// We could also detect that an administrator unverified their address
// and let that come with a message.
// For now, just make sure the unverified address does not escape notice.
$issues[] = array(
'title' => pht('Primary Email Unverified'),
'summary' => pht(
'Your primary email address is unverified. You will not be able '.
'to receive email until you verify it.'),
'uri' => $setup_uri,
);
}
if ($issues) {
require_celerity_resource('phabricator-notification-menu-css');
$items = array();
foreach ($issues as $issue) {
$classes = array();
$classes[] = 'phabricator-notification';
$classes[] = 'phabricator-notification-unread';
$uri = $issue['uri'];
$title = $issue['title'];
$summary = $issue['summary'];
$items[] = javelin_tag(
'div',
array(
'class' =>
'phabricator-notification phabricator-notification-unread',
'sigil' => 'notification',
'meta' => array(
'href' => $uri,
),
),
array(
phutil_tag('strong', array(), pht('%s:', $title)),
' ',
$summary,
));
}
$content = phutil_tag(
'div',
array(
'class' => 'setup-issue-menu',
),
$items);
} else {
$content = phutil_tag(
'div',
array(
'class' => 'phabricator-notification no-notifications',
),
pht('You have no account setup issues.'));
}
$header = phutil_tag(
'div',
array(
'class' => 'phabricator-notification-header',
),
phutil_tag(
'a',
array(
'href' => $setup_uri,
),
pht('Account Setup Issues')));
$content = array(
$header,
$content,
);
$json = array(
'content' => hsprintf('%s', $content),
'number' => count($issues),
);
return id(new AphrontAjaxResponse())->setContent($json);
}
}

View file

@ -595,10 +595,74 @@ final class PhabricatorMainMenuView extends AphrontView {
}
}
$user_dropdown = null;
$user_tag = null;
if ($viewer->isLoggedIn()) {
if (!$viewer->getIsEmailVerified()) {
$bubble_id = celerity_generate_unique_node_id();
$count_id = celerity_generate_unique_node_id();
$dropdown_id = celerity_generate_unique_node_id();
$settings_uri = id(new PhabricatorEmailAddressesSettingsPanel())
->setViewer($viewer)
->setUser($viewer)
->getPanelURI();
$user_icon = javelin_tag(
'span',
array(
'class' => 'phabricator-main-menu-setup-icon phui-icon-view '.
'phui-font-fa fa-user',
'sigil' => 'menu-icon',
));
$user_count = javelin_tag(
'span',
array(
'class' => 'phabricator-main-menu-setup-count',
'id' => $count_id,
),
1);
$user_tag = phutil_tag(
'a',
array(
'href' => $settings_uri,
'class' => 'setup-unread',
'id' => $bubble_id,
),
array(
$user_icon,
$user_count,
));
Javelin::initBehavior(
'aphlict-dropdown',
array(
'bubbleID' => $bubble_id,
'countID' => $count_id,
'dropdownID' => $dropdown_id,
'loadingText' => pht('Loading...'),
'uri' => '/settings/issue/',
'unreadClass' => 'setup-unread',
));
$user_dropdown = javelin_tag(
'div',
array(
'id' => $dropdown_id,
'class' => 'phabricator-notification-menu',
'sigil' => 'phabricator-notification-menu',
'style' => 'display: none;',
));
}
}
$dropdowns = array(
$notification_dropdown,
$message_notification_dropdown,
$setup_notification_dropdown,
$user_dropdown,
);
return array(
@ -606,6 +670,7 @@ final class PhabricatorMainMenuView extends AphrontView {
$bubble_tag,
$message_tag,
$setup_tag,
$user_tag,
),
$dropdowns,
$aural,