Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15481376
D20170.id48184.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
11 KB
Referenced Files
None
Subscribers
None
D20170.id48184.diff
View Options
diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -9,7 +9,7 @@
'names' => array(
'conpherence.pkg.css' => '3c8a0668',
'conpherence.pkg.js' => '020aebcf',
- 'core.pkg.css' => 'e0f5d66f',
+ 'core.pkg.css' => '4ed8ce1f',
'core.pkg.js' => '5c737607',
'differential.pkg.css' => 'b8df73d4',
'differential.pkg.js' => '67c9ea4c',
@@ -164,7 +164,7 @@
'rsrc/css/phui/phui-left-right.css' => '68513c34',
'rsrc/css/phui/phui-lightbox.css' => '4ebf22da',
'rsrc/css/phui/phui-list.css' => '470b1adb',
- 'rsrc/css/phui/phui-object-box.css' => '9b58483d',
+ 'rsrc/css/phui/phui-object-box.css' => 'f434b6be',
'rsrc/css/phui/phui-pager.css' => 'd022c7ad',
'rsrc/css/phui/phui-pinboard-view.css' => '1f08f5d8',
'rsrc/css/phui/phui-property-list-view.css' => 'cad62236',
@@ -833,7 +833,7 @@
'phui-left-right-css' => '68513c34',
'phui-lightbox-css' => '4ebf22da',
'phui-list-view-css' => '470b1adb',
- 'phui-object-box-css' => '9b58483d',
+ 'phui-object-box-css' => 'f434b6be',
'phui-oi-big-ui-css' => '9e037c7a',
'phui-oi-color-css' => 'b517bfa0',
'phui-oi-drag-ui-css' => 'da15d3dc',
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2272,6 +2272,7 @@
'PhabricatorAuthInviteVerifyException' => 'applications/auth/exception/PhabricatorAuthInviteVerifyException.php',
'PhabricatorAuthInviteWorker' => 'applications/auth/worker/PhabricatorAuthInviteWorker.php',
'PhabricatorAuthLinkController' => 'applications/auth/controller/PhabricatorAuthLinkController.php',
+ 'PhabricatorAuthLinkMessageType' => 'applications/auth/message/PhabricatorAuthLinkMessageType.php',
'PhabricatorAuthListController' => 'applications/auth/controller/config/PhabricatorAuthListController.php',
'PhabricatorAuthLoginController' => 'applications/auth/controller/PhabricatorAuthLoginController.php',
'PhabricatorAuthLoginMessageType' => 'applications/auth/message/PhabricatorAuthLoginMessageType.php',
@@ -2370,6 +2371,7 @@
'PhabricatorAuthSessionPHIDType' => 'applications/auth/phid/PhabricatorAuthSessionPHIDType.php',
'PhabricatorAuthSessionQuery' => 'applications/auth/query/PhabricatorAuthSessionQuery.php',
'PhabricatorAuthSessionRevoker' => 'applications/auth/revoker/PhabricatorAuthSessionRevoker.php',
+ 'PhabricatorAuthSetExternalController' => 'applications/auth/controller/PhabricatorAuthSetExternalController.php',
'PhabricatorAuthSetPasswordController' => 'applications/auth/controller/PhabricatorAuthSetPasswordController.php',
'PhabricatorAuthSetupCheck' => 'applications/config/check/PhabricatorAuthSetupCheck.php',
'PhabricatorAuthStartController' => 'applications/auth/controller/PhabricatorAuthStartController.php',
@@ -8023,6 +8025,7 @@
'PhabricatorAuthInviteVerifyException' => 'PhabricatorAuthInviteDialogException',
'PhabricatorAuthInviteWorker' => 'PhabricatorWorker',
'PhabricatorAuthLinkController' => 'PhabricatorAuthController',
+ 'PhabricatorAuthLinkMessageType' => 'PhabricatorAuthMessageType',
'PhabricatorAuthListController' => 'PhabricatorAuthProviderConfigController',
'PhabricatorAuthLoginController' => 'PhabricatorAuthController',
'PhabricatorAuthLoginMessageType' => 'PhabricatorAuthMessageType',
@@ -8142,6 +8145,7 @@
'PhabricatorAuthSessionPHIDType' => 'PhabricatorPHIDType',
'PhabricatorAuthSessionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorAuthSessionRevoker' => 'PhabricatorAuthRevoker',
+ 'PhabricatorAuthSetExternalController' => 'PhabricatorAuthController',
'PhabricatorAuthSetPasswordController' => 'PhabricatorAuthController',
'PhabricatorAuthSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorAuthStartController' => 'PhabricatorAuthController',
diff --git a/src/applications/auth/application/PhabricatorAuthApplication.php b/src/applications/auth/application/PhabricatorAuthApplication.php
--- a/src/applications/auth/application/PhabricatorAuthApplication.php
+++ b/src/applications/auth/application/PhabricatorAuthApplication.php
@@ -86,7 +86,9 @@
=> 'PhabricatorAuthSSHKeyRevokeController',
'view/(?P<id>\d+)/' => 'PhabricatorAuthSSHKeyViewController',
),
+
'password/' => 'PhabricatorAuthSetPasswordController',
+ 'external/' => 'PhabricatorAuthSetExternalController',
'mfa/' => array(
$this->getQueryRoutePattern() =>
diff --git a/src/applications/auth/controller/PhabricatorAuthOneTimeLoginController.php b/src/applications/auth/controller/PhabricatorAuthOneTimeLoginController.php
--- a/src/applications/auth/controller/PhabricatorAuthOneTimeLoginController.php
+++ b/src/applications/auth/controller/PhabricatorAuthOneTimeLoginController.php
@@ -225,17 +225,45 @@
return (string)new PhutilURI($panel_uri, $params);
}
- $providers = id(new PhabricatorAuthProviderConfigQuery())
+ // Check if the user already has external accounts linked. If they do,
+ // it's not obvious why they aren't using them to log in, but assume they
+ // know what they're doing. We won't send them to the link workflow.
+ $accounts = id(new PhabricatorExternalAccountQuery())
+ ->setViewer($user)
+ ->withUserPHIDs(array($user->getPHID()))
+ ->execute();
+
+ $configs = id(new PhabricatorAuthProviderConfigQuery())
->setViewer($user)
->withIsEnabled(true)
->execute();
+ $linkable = array();
+ foreach ($configs as $config) {
+ if (!$config->getShouldAllowLink()) {
+ continue;
+ }
+
+ $provider = $config->getProvider();
+ if (!$provider->isLoginFormAButton()) {
+ continue;
+ }
+
+ $linkable[] = $provider;
+ }
+
+ // If there's at least one linkable provider, and the user doesn't already
+ // have accounts, send the user to the link workflow.
+ if (!$accounts && $linkable) {
+ return '/auth/external/';
+ }
+
// If there are no configured providers and the user is an administrator,
// send them to Auth to configure a provider. This is probably where they
// want to go. You can end up in this state by accidentally losing your
// first session during initial setup, or after restoring exported data
// from a hosted instance.
- if (!$providers && $user->getIsAdmin()) {
+ if (!$configs && $user->getIsAdmin()) {
return '/auth/';
}
diff --git a/src/applications/auth/controller/PhabricatorAuthSetExternalController.php b/src/applications/auth/controller/PhabricatorAuthSetExternalController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/controller/PhabricatorAuthSetExternalController.php
@@ -0,0 +1,110 @@
+<?php
+
+final class PhabricatorAuthSetExternalController
+ extends PhabricatorAuthController {
+
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->getViewer();
+
+ $configs = id(new PhabricatorAuthProviderConfigQuery())
+ ->setViewer($viewer)
+ ->withIsEnabled(true)
+ ->execute();
+
+ $linkable = array();
+ foreach ($configs as $config) {
+ if (!$config->getShouldAllowLink()) {
+ continue;
+ }
+
+ // For now, only buttons get to appear here: for example, we can't
+ // reasonably embed an entire LDAP form into this UI.
+ $provider = $config->getProvider();
+ if (!$provider->isLoginFormAButton()) {
+ continue;
+ }
+
+ $linkable[] = $config;
+ }
+
+ if (!$linkable) {
+ return $this->newDialog()
+ ->setTitle(pht('No Linkable External Providers'))
+ ->appendParagraph(
+ pht(
+ 'Currently, there are no configured external auth providers '.
+ 'which you can link your account to.'))
+ ->addCancelButton('/');
+ }
+
+ $text = PhabricatorAuthMessage::loadMessageText(
+ $viewer,
+ PhabricatorAuthLinkMessageType::MESSAGEKEY);
+ if (!strlen($text)) {
+ $text = pht(
+ 'You can link your Phabricator account to an external account to '.
+ 'allow you to log in more easily in the future. To continue, choose '.
+ 'an account to link below. If you prefer not to link your account, '.
+ 'you can skip this step.');
+ }
+
+ $remarkup_view = new PHUIRemarkupView($viewer, $text);
+ $remarkup_view = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'phui-object-box-instructions',
+ ),
+ $remarkup_view);
+
+ PhabricatorCookies::setClientIDCookie($request);
+
+ $view = array();
+ foreach ($configs as $config) {
+ $provider = $config->getProvider();
+
+ $form = $provider->buildLinkForm($this);
+
+ if ($provider->isLoginFormAButton()) {
+ require_celerity_resource('auth-css');
+ $form = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'phabricator-link-button pl',
+ ),
+ $form);
+ }
+
+ $view[] = $form;
+ }
+
+ $form = id(new AphrontFormView())
+ ->setViewer($viewer)
+ ->appendControl(
+ id(new AphrontFormSubmitControl())
+ ->addCancelButton('/', pht('Skip This Step')));
+
+ $header = id(new PHUIHeaderView())
+ ->setHeader(pht('Link External Account'));
+
+ $box = id(new PHUIObjectBoxView())
+ ->setViewer($viewer)
+ ->setHeader($header)
+ ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
+ ->appendChild($remarkup_view)
+ ->appendChild($view)
+ ->appendChild($form);
+
+ $main_view = id(new PHUITwoColumnView())
+ ->setFooter($box);
+
+ $crumbs = $this->buildApplicationCrumbs()
+ ->addTextCrumb(pht('Link External Account'))
+ ->setBorder(true);
+
+ return $this->newPage()
+ ->setTitle(pht('Link External Account'))
+ ->setCrumbs($crumbs)
+ ->appendChild($main_view);
+ }
+
+}
diff --git a/src/applications/auth/message/PhabricatorAuthLinkMessageType.php b/src/applications/auth/message/PhabricatorAuthLinkMessageType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/message/PhabricatorAuthLinkMessageType.php
@@ -0,0 +1,18 @@
+<?php
+
+final class PhabricatorAuthLinkMessageType
+ extends PhabricatorAuthMessageType {
+
+ const MESSAGEKEY = 'auth.link';
+
+ public function getDisplayName() {
+ return pht('Unlinked Account Instructions');
+ }
+
+ public function getShortDescription() {
+ return pht(
+ 'Guidance shown after a user logs in with an email link and is '.
+ 'prompted to link an external account.');
+ }
+
+}
diff --git a/src/applications/auth/provider/PhabricatorAuthProvider.php b/src/applications/auth/provider/PhabricatorAuthProvider.php
--- a/src/applications/auth/provider/PhabricatorAuthProvider.php
+++ b/src/applications/auth/provider/PhabricatorAuthProvider.php
@@ -161,7 +161,7 @@
abstract public function processLoginRequest(
PhabricatorAuthLoginController $controller);
- public function buildLinkForm(PhabricatorAuthLinkController $controller) {
+ public function buildLinkForm($controller) {
return $this->renderLoginForm($controller->getRequest(), $mode = 'link');
}
diff --git a/src/applications/auth/provider/PhabricatorPasswordAuthProvider.php b/src/applications/auth/provider/PhabricatorPasswordAuthProvider.php
--- a/src/applications/auth/provider/PhabricatorPasswordAuthProvider.php
+++ b/src/applications/auth/provider/PhabricatorPasswordAuthProvider.php
@@ -159,8 +159,7 @@
return $dialog;
}
- public function buildLinkForm(
- PhabricatorAuthLinkController $controller) {
+ public function buildLinkForm($controller) {
throw new Exception(pht("Password providers can't be linked."));
}
diff --git a/webroot/rsrc/css/phui/phui-object-box.css b/webroot/rsrc/css/phui/phui-object-box.css
--- a/webroot/rsrc/css/phui/phui-object-box.css
+++ b/webroot/rsrc/css/phui/phui-object-box.css
@@ -158,3 +158,8 @@
margin-top: 8px;
margin-bottom: 8px;
}
+
+.phui-object-box-instructions {
+ padding: 16px;
+ border-bottom: 1px solid {$thinblueborder};
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Apr 9, 8:23 PM (4 w, 19 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7339501
Default Alt Text
D20170.id48184.diff (11 KB)
Attached To
Mode
D20170: When users follow an email login link but an install does not use passwords, try to get them to link an account
Attached
Detach File
Event Timeline
Log In to Comment