@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator

Auth - allow for "auto login" providers

Summary: Ref T7153. I am not sure if this is 100% correct because sometimes you have to POST vs GET and I don't know if the redirect response will / can do the right thing? I think options to fix this would be to 1) restrict this functionality to JUST the Phabricator OAuth provider type or 2) something really fancy with an HTTP(S) future. The other rub right now is when you logout you get half auto-logged in again... Thoughts on that?

Test Plan: setup my local instance to JUST have phabricator oauth available to login. was presented with the dialog automagically...!

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin, epriestley

Maniphest Tasks: T7153

Differential Revision: https://secure.phabricator.com/D11701

+65 -5
+2
resources/sql/autopatches/20150205.authprovider.autologin.sql
··· 1 + ALTER TABLE {$NAMESPACE}_auth.auth_providerconfig 2 + ADD shouldAutoLogin TINYINT(1) NOT NULL DEFAULT '0';
+1
src/applications/auth/application/PhabricatorAuthApplication.php
··· 97 97 ), 98 98 'login/(?P<pkey>[^/]+)/(?:(?P<extra>[^/]+)/)?' 99 99 => 'PhabricatorAuthLoginController', 100 + '(?P<loggedout>loggedout)/' => 'PhabricatorAuthStartController', 100 101 'register/(?:(?P<akey>[^/]+)/)?' => 'PhabricatorAuthRegisterController', 101 102 'start/' => 'PhabricatorAuthStartController', 102 103 'validate/' => 'PhabricatorAuthValidateController',
+14 -2
src/applications/auth/controller/PhabricatorAuthStartController.php
··· 7 7 return false; 8 8 } 9 9 10 - public function processRequest() { 11 - $request = $this->getRequest(); 10 + public function handleRequest(AphrontRequest $request) { 12 11 $viewer = $request->getUser(); 13 12 14 13 if ($viewer->isLoggedIn()) { ··· 95 94 PhabricatorCookies::setNextURICookie($request, $next_uri); 96 95 } 97 96 PhabricatorCookies::setClientIDCookie($request); 97 + } 98 + 99 + if (!$request->getURIData('loggedout') && count($providers) == 1) { 100 + $auto_login_provider = head($providers); 101 + $auto_login_config = $auto_login_provider->getProviderConfig(); 102 + if ($auto_login_provider instanceof PhabricatorPhabricatorAuthProvider && 103 + $auto_login_config->getShouldAutoLogin()) { 104 + $auto_login_adapter = $provider->getAdapter(); 105 + $auto_login_adapter->setState($provider->getAuthCSRFCode($request)); 106 + return id(new AphrontRedirectResponse()) 107 + ->setIsExternal(true) 108 + ->setURI($provider->getAdapter()->getAuthenticateURI()); 109 + } 98 110 } 99 111 100 112 $not_buttons = array();
+2 -2
src/applications/auth/controller/PhabricatorLogoutController.php
··· 21 21 return true; 22 22 } 23 23 24 - public function processRequest() { 24 + public function handleRequest(AphrontRequest $request) { 25 25 $request = $this->getRequest(); 26 26 $user = $request->getUser(); 27 27 ··· 49 49 $request->clearCookie(PhabricatorCookies::COOKIE_SESSION); 50 50 51 51 return id(new AphrontRedirectResponse()) 52 - ->setURI('/login/'); 52 + ->setURI('/auth/loggedout/'); 53 53 } 54 54 55 55 if ($user->getPHID()) {
+24
src/applications/auth/controller/config/PhabricatorAuthEditController.php
··· 83 83 $v_link = $config->getShouldAllowLink(); 84 84 $v_unlink = $config->getShouldAllowUnlink(); 85 85 $v_trust_email = $config->getShouldTrustEmails(); 86 + $v_auto_login = $config->getShouldAutoLogin(); 86 87 87 88 if ($request->isFormPost()) { 88 89 ··· 122 123 ->setTransactionType( 123 124 PhabricatorAuthProviderConfigTransaction::TYPE_TRUST_EMAILS) 124 125 ->setNewValue($request->getInt('trustEmails', 0)); 126 + 127 + if ($provider instanceof PhabricatorPhabricatorAuthProvider) { 128 + $xactions[] = id(new PhabricatorAuthProviderConfigTransaction()) 129 + ->setTransactionType( 130 + PhabricatorAuthProviderConfigTransaction::TYPE_AUTO_LOGIN) 131 + ->setNewValue($request->getInt('autoLogin', 0)); 132 + } 125 133 126 134 foreach ($properties as $key => $value) { 127 135 $xactions[] = id(new PhabricatorAuthProviderConfigTransaction()) ··· 224 232 pht( 225 233 'Phabricator will skip email verification for accounts registered '. 226 234 'through this provider.')); 235 + $str_auto_login = hsprintf( 236 + '<strong>%s:</strong> %s', 237 + pht('Allow Auto Login'), 238 + pht( 239 + 'Phabricator will automatically login with this provider if it is '. 240 + 'the only available provider.')); 227 241 228 242 $status_tag = id(new PHUITagView()) 229 243 ->setType(PHUITagView::TYPE_STATE); ··· 283 297 1, 284 298 $str_trusted_email, 285 299 $v_trust_email)); 300 + } 301 + 302 + if ($provider instanceof PhabricatorPhabricatorAuthProvider) { 303 + $form->appendChild( 304 + id(new AphrontFormCheckboxControl()) 305 + ->addCheckbox( 306 + 'autoLogin', 307 + 1, 308 + $str_auto_login, 309 + $v_auto_login)); 286 310 } 287 311 288 312 $provider->extendEditForm($request, $form, $properties, $issues);
+7
src/applications/auth/editor/PhabricatorAuthProviderConfigEditor.php
··· 19 19 $types[] = PhabricatorAuthProviderConfigTransaction::TYPE_LINK; 20 20 $types[] = PhabricatorAuthProviderConfigTransaction::TYPE_UNLINK; 21 21 $types[] = PhabricatorAuthProviderConfigTransaction::TYPE_TRUST_EMAILS; 22 + $types[] = PhabricatorAuthProviderConfigTransaction::TYPE_AUTO_LOGIN; 22 23 $types[] = PhabricatorAuthProviderConfigTransaction::TYPE_PROPERTY; 23 24 24 25 return $types; ··· 43 44 return (int)$object->getShouldAllowUnlink(); 44 45 case PhabricatorAuthProviderConfigTransaction::TYPE_TRUST_EMAILS: 45 46 return (int)$object->getShouldTrustEmails(); 47 + case PhabricatorAuthProviderConfigTransaction::TYPE_AUTO_LOGIN: 48 + return (int)$object->getShouldAutoLogin(); 46 49 case PhabricatorAuthProviderConfigTransaction::TYPE_PROPERTY: 47 50 $key = $xaction->getMetadataValue( 48 51 PhabricatorAuthProviderConfigTransaction::PROPERTY_KEY); ··· 60 63 case PhabricatorAuthProviderConfigTransaction::TYPE_LINK: 61 64 case PhabricatorAuthProviderConfigTransaction::TYPE_UNLINK: 62 65 case PhabricatorAuthProviderConfigTransaction::TYPE_TRUST_EMAILS: 66 + case PhabricatorAuthProviderConfigTransaction::TYPE_AUTO_LOGIN: 63 67 case PhabricatorAuthProviderConfigTransaction::TYPE_PROPERTY: 64 68 return $xaction->getNewValue(); 65 69 } ··· 80 84 return $object->setShouldAllowUnlink($v); 81 85 case PhabricatorAuthProviderConfigTransaction::TYPE_TRUST_EMAILS: 82 86 return $object->setShouldTrustEmails($v); 87 + case PhabricatorAuthProviderConfigTransaction::TYPE_AUTO_LOGIN: 88 + return $object->setShouldAutoLogin($v); 83 89 case PhabricatorAuthProviderConfigTransaction::TYPE_PROPERTY: 84 90 $key = $xaction->getMetadataValue( 85 91 PhabricatorAuthProviderConfigTransaction::PROPERTY_KEY); ··· 104 110 case PhabricatorAuthProviderConfigTransaction::TYPE_LINK: 105 111 case PhabricatorAuthProviderConfigTransaction::TYPE_UNLINK: 106 112 case PhabricatorAuthProviderConfigTransaction::TYPE_TRUST_EMAILS: 113 + case PhabricatorAuthProviderConfigTransaction::TYPE_AUTO_LOGIN: 107 114 // For these types, last transaction wins. 108 115 return $v; 109 116 }
+1 -1
src/applications/auth/provider/PhabricatorAuthProvider.php
··· 449 449 return null; 450 450 } 451 451 452 - protected function getAuthCSRFCode(AphrontRequest $request) { 452 + public function getAuthCSRFCode(AphrontRequest $request) { 453 453 $phcid = $request->getCookie(PhabricatorCookies::COOKIE_CLIENTID); 454 454 if (!strlen($phcid)) { 455 455 throw new Exception(
+2
src/applications/auth/storage/PhabricatorAuthProviderConfig.php
··· 16 16 protected $shouldAllowLink = 0; 17 17 protected $shouldAllowUnlink = 0; 18 18 protected $shouldTrustEmails = 0; 19 + protected $shouldAutoLogin = 0; 19 20 20 21 protected $properties = array(); 21 22 ··· 42 43 'shouldAllowLink' => 'bool', 43 44 'shouldAllowUnlink' => 'bool', 44 45 'shouldTrustEmails' => 'bool', 46 + 'shouldAutoLogin' => 'bool', 45 47 ), 46 48 self::CONFIG_KEY_SCHEMA => array( 47 49 'key_provider' => array(
+12
src/applications/auth/storage/PhabricatorAuthProviderConfigTransaction.php
··· 8 8 const TYPE_LINK = 'config:link'; 9 9 const TYPE_UNLINK = 'config:unlink'; 10 10 const TYPE_TRUST_EMAILS = 'config:trustEmails'; 11 + const TYPE_AUTO_LOGIN = 'config:autoLogin'; 11 12 const TYPE_PROPERTY = 'config:property'; 12 13 13 14 const PROPERTY_KEY = 'auth:property'; ··· 130 131 } else { 131 132 return pht( 132 133 '%s disabled email trust.', 134 + $this->renderHandleLink($author_phid)); 135 + } 136 + break; 137 + case self::TYPE_AUTO_LOGIN: 138 + if ($new) { 139 + return pht( 140 + '%s enabled auto login.', 141 + $this->renderHandleLink($author_phid)); 142 + } else { 143 + return pht( 144 + '%s disabled auto login.', 133 145 $this->renderHandleLink($author_phid)); 134 146 } 135 147 break;