diff --git a/conf/default.conf.php b/conf/default.conf.php index 276e9df1b2..07f397463a 100644 --- a/conf/default.conf.php +++ b/conf/default.conf.php @@ -181,7 +181,17 @@ return array( // Can users login with a username/password, or by following the link from // a password reset email? You can disable this and configure one or more // OAuth providers instead. - 'auth.password-auth-enabled' => true, + 'auth.password-auth-enabled' => true, + + +// -- Accounts -------------------------------------------------------------- // + + // Is basic account information (email, real name, profile picture) editable? + // If you set up Phabricator to automatically synchronize account information + // from some other authoritative system, you can disable this to ensure + // information remains consistent across both systems. + 'account.editable' => true, + // -- Facebook ------------------------------------------------------------ // diff --git a/src/aphront/applicationconfiguration/AphrontApplicationConfiguration.php b/src/aphront/applicationconfiguration/AphrontApplicationConfiguration.php index 610f15e3f5..cadaaaa2e3 100644 --- a/src/aphront/applicationconfiguration/AphrontApplicationConfiguration.php +++ b/src/aphront/applicationconfiguration/AphrontApplicationConfiguration.php @@ -86,4 +86,16 @@ abstract class AphrontApplicationConfiguration { final public function willBuildRequest() { } + /** + * Hook for synchronizing account information from OAuth workflows. + * + * @task hook + */ + public function willAuthenticateUserWithOAuth( + PhabricatorUser $user, + PhabricatorUserOAuthInfo $oauth_info, + PhabricatorOAuthProvider $provider) { + return; + } + } diff --git a/src/applications/auth/controller/oauth/PhabricatorOAuthLoginController.php b/src/applications/auth/controller/oauth/PhabricatorOAuthLoginController.php index 3dfcc2d99e..87d6bb9668 100644 --- a/src/applications/auth/controller/oauth/PhabricatorOAuthLoginController.php +++ b/src/applications/auth/controller/oauth/PhabricatorOAuthLoginController.php @@ -138,6 +138,12 @@ class PhabricatorOAuthLoginController extends PhabricatorAuthController { if ($oauth_info->getID()) { $known_user = id(new PhabricatorUser())->load($oauth_info->getUserID()); + + $request->getApplicationConfiguration()->willAuthenticateUserWithOAuth( + $known_user, + $oauth_info, + $provider); + $session_key = $known_user->establishSession('web'); $oauth_info->save(); diff --git a/src/applications/auth/controller/oauthregistration/default/PhabricatorOAuthDefaultRegistrationController.php b/src/applications/auth/controller/oauthregistration/default/PhabricatorOAuthDefaultRegistrationController.php index 2357875df8..a72604cc7f 100644 --- a/src/applications/auth/controller/oauthregistration/default/PhabricatorOAuthDefaultRegistrationController.php +++ b/src/applications/auth/controller/oauthregistration/default/PhabricatorOAuthDefaultRegistrationController.php @@ -71,7 +71,7 @@ class PhabricatorOAuthDefaultRegistrationController } if (!$errors) { - $image = $provider->retreiveUserProfileImage(); + $image = $provider->retrieveUserProfileImage(); if ($image) { $file = PhabricatorFile::newFromFileData( $image, diff --git a/src/applications/files/storage/file/PhabricatorFile.php b/src/applications/files/storage/file/PhabricatorFile.php index c09a559bbd..84a7d19a63 100644 --- a/src/applications/files/storage/file/PhabricatorFile.php +++ b/src/applications/files/storage/file/PhabricatorFile.php @@ -184,7 +184,7 @@ class PhabricatorFile extends PhabricatorFileDAO { $mime_type = $this->getMimeType(); $mime_parts = explode(';', $mime_type); - $mime_type = reset($mime_parts); + $mime_type = trim(reset($mime_parts)); return idx($mime_map, $mime_type); } diff --git a/src/applications/people/controller/settings/PhabricatorUserSettingsController.php b/src/applications/people/controller/settings/PhabricatorUserSettingsController.php index fea4fa4092..eafe26cd18 100644 --- a/src/applications/people/controller/settings/PhabricatorUserSettingsController.php +++ b/src/applications/people/controller/settings/PhabricatorUserSettingsController.php @@ -19,6 +19,7 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController { private $page; + private $accountEditable; public function willProcessRequest(array $data) { $this->page = idx($data, 'page'); @@ -50,9 +51,15 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController { $this->page = key($pages); } + $account_editable = PhabricatorEnv::getEnvConfig('account.editable'); + $this->accountEditable = $account_editable; + if ($request->isFormPost()) { switch ($this->page) { case 'email': + if (!$account_editable) { + return new Aphront400Response(); + } $user->setEmail($request->getStr('email')); $user->save(); return id(new AphrontRedirectResponse()) @@ -87,6 +94,10 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController { return id(new AphrontRedirectResponse()) ->setURI('/settings/page/arcanist/?regenerated=true'); case 'account': + if (!$account_editable) { + return new Aphront400Response(); + } + if (!empty($_FILES['profile'])) { $err = idx($_FILES['profile'], 'error'); if ($err != UPLOAD_ERR_NO_FILE) { @@ -208,6 +219,8 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController { $img_src = PhabricatorFileURI::getViewURIForPHID( $user->getProfileImagePHID()); + $editable = $this->accountEditable; + $form = new AphrontFormView(); $form ->setUser($user) @@ -219,7 +232,8 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController { ->appendChild( id(new AphrontFormTextControl()) ->setLabel('Real Name') - ->setValue($user->getRealName())) + ->setValue($user->getRealName()) + ->setDisabled(!$editable)) ->appendChild( id(new AphrontFormMarkupControl()) ->setValue('
')) @@ -231,18 +245,22 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController { 'img', array( 'src' => $img_src, - )))) - ->appendChild( - id(new AphrontFormFileControl()) - ->setLabel('Change Image') - ->setName('profile') - ->setCaption('Upload a 50x50px image.')) - ->appendChild( - id(new AphrontFormMarkupControl()) - ->setValue('
')) - ->appendChild( - id(new AphrontFormSubmitControl()) - ->setValue('Save')); + )))); + + if ($editable) { + $form + ->appendChild( + id(new AphrontFormFileControl()) + ->setLabel('Change Image') + ->setName('profile') + ->setCaption('Upload a 50x50px image.')) + ->appendChild( + id(new AphrontFormMarkupControl()) + ->setValue('
')) + ->appendChild( + id(new AphrontFormSubmitControl()) + ->setValue('Save')); + } $panel = new AphrontPanelView(); $panel->setHeader('Profile Settings'); @@ -256,6 +274,8 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController { $request = $this->getRequest(); $user = $request->getUser(); + $editable = $this->accountEditable; + if ($request->getStr('saved')) { $notice = new AphrontErrorView(); $notice->setSeverity(AphrontErrorView::SEVERITY_NOTICE); @@ -273,13 +293,18 @@ class PhabricatorUserSettingsController extends PhabricatorPeopleController { id(new AphrontFormTextControl()) ->setLabel('Email') ->setName('email') + ->setDisabled(!$editable) ->setCaption( 'Note: there is no email validation yet; double-check your '. 'typing.') - ->setValue($user->getEmail())) - ->appendChild( - id(new AphrontFormSubmitControl()) - ->setValue('Save')); + ->setValue($user->getEmail())); + + if ($editable) { + $form + ->appendChild( + id(new AphrontFormSubmitControl()) + ->setValue('Save')); + } $panel = new AphrontPanelView(); $panel->setHeader('Email Settings'); diff --git a/src/applications/people/controller/settings/__init__.php b/src/applications/people/controller/settings/__init__.php index 5a6d1c5814..1e8da4987f 100644 --- a/src/applications/people/controller/settings/__init__.php +++ b/src/applications/people/controller/settings/__init__.php @@ -6,6 +6,7 @@ +phutil_require_module('phabricator', 'aphront/response/400'); phutil_require_module('phabricator', 'aphront/response/404'); phutil_require_module('phabricator', 'aphront/response/dialog'); phutil_require_module('phabricator', 'aphront/response/redirect'); @@ -19,8 +20,10 @@ phutil_require_module('phabricator', 'infrastructure/env'); phutil_require_module('phabricator', 'storage/queryfx'); phutil_require_module('phabricator', 'view/dialog'); phutil_require_module('phabricator', 'view/form/base'); +phutil_require_module('phabricator', 'view/form/control/markup'); phutil_require_module('phabricator', 'view/form/control/static'); phutil_require_module('phabricator', 'view/form/control/submit'); +phutil_require_module('phabricator', 'view/form/control/text'); phutil_require_module('phabricator', 'view/form/control/textarea'); phutil_require_module('phabricator', 'view/form/error'); phutil_require_module('phabricator', 'view/layout/panel');