diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index e9872ea819..0d8f66607c 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1456,6 +1456,7 @@ phutil_register_library_map(array( 'PhabricatorSettingsPanelSearchPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelSearchPreferences.php', 'PhabricatorSetupCheck' => 'applications/config/check/PhabricatorSetupCheck.php', 'PhabricatorSetupCheckAPC' => 'applications/config/check/PhabricatorSetupCheckAPC.php', + 'PhabricatorSetupCheckAuth' => 'applications/config/check/PhabricatorSetupCheckAuth.php', 'PhabricatorSetupCheckBaseURI' => 'applications/config/check/PhabricatorSetupCheckBaseURI.php', 'PhabricatorSetupCheckBinaries' => 'applications/config/check/PhabricatorSetupCheckBinaries.php', 'PhabricatorSetupCheckDatabase' => 'applications/config/check/PhabricatorSetupCheckDatabase.php', @@ -3324,6 +3325,7 @@ phutil_register_library_map(array( 'PhabricatorSettingsPanelSSHKeys' => 'PhabricatorSettingsPanel', 'PhabricatorSettingsPanelSearchPreferences' => 'PhabricatorSettingsPanel', 'PhabricatorSetupCheckAPC' => 'PhabricatorSetupCheck', + 'PhabricatorSetupCheckAuth' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckBaseURI' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckBinaries' => 'PhabricatorSetupCheck', 'PhabricatorSetupCheckDatabase' => 'PhabricatorSetupCheck', diff --git a/src/applications/auth/controller/PhabricatorAuthController.php b/src/applications/auth/controller/PhabricatorAuthController.php index 182a210e4a..aa23034a4b 100644 --- a/src/applications/auth/controller/PhabricatorAuthController.php +++ b/src/applications/auth/controller/PhabricatorAuthController.php @@ -29,6 +29,28 @@ abstract class PhabricatorAuthController extends PhabricatorController { } + /** + * Returns true if this install is newly setup (i.e., there are no user + * accounts yet). In this case, we enter a special mode to permit creation + * of the first account form the web UI. + */ + protected function isFirstTimeSetup() { + // If there are any auth providers, this isn't first time setup, even if + // we don't have accounts. + if (PhabricatorAuthProvider::getAllEnabledProviders()) { + return false; + } + + // Otherwise, check if there are any user accounts. If not, we're in first + // time setup. + $any_users = id(new PhabricatorPeopleQuery()) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->setLimit(1) + ->execute(); + + return !$any_users; + } + /** * Log a user into a web session and return an @{class:AphrontResponse} which diff --git a/src/applications/auth/controller/PhabricatorAuthRegisterController.php b/src/applications/auth/controller/PhabricatorAuthRegisterController.php index 86c509576f..85324ae090 100644 --- a/src/applications/auth/controller/PhabricatorAuthRegisterController.php +++ b/src/applications/auth/controller/PhabricatorAuthRegisterController.php @@ -20,10 +20,15 @@ final class PhabricatorAuthRegisterController return $this->renderError(pht('You are already logged in.')); } + $is_setup = false; if (strlen($this->accountKey)) { $result = $this->loadAccountForRegistrationOrLinking($this->accountKey); list($account, $provider, $response) = $result; $is_default = false; + } else if ($this->isFirstTimeSetup()) { + list($account, $provider, $response) = $this->loadSetupAccount(); + $is_default = true; + $is_setup = true; } else { list($account, $provider, $response) = $this->loadDefaultAccount(); $is_default = true; @@ -213,6 +218,10 @@ final class PhabricatorAuthRegisterController $editor->changePassword($user, $envelope); } + if ($is_setup) { + $editor->makeAdminUser($user, true); + } + $account->setUserPHID($user->getPHID()); $provider->willRegisterAccount($account); $account->save(); @@ -319,24 +328,53 @@ final class PhabricatorAuthRegisterController ->setError($e_realname)); } - $form->appendChild( - id(new AphrontFormSubmitControl()) - ->addCancelButton($this->getApplicationURI('start/')) - ->setValue(pht('Register Phabricator Account'))); + $submit = id(new AphrontFormSubmitControl()); - $title = pht('Phabricator Registration'); + if ($is_setup) { + $submit + ->setValue(pht('Create Admin Account')); + } else { + $submit + ->addCancelButton($this->getApplicationURI('start/')) + ->setValue(pht('Register Phabricator Account')); + } + + + $form->appendChild($submit); $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addCrumb( - id(new PhabricatorCrumbView()) - ->setName(pht('Register'))); - $crumbs->addCrumb( - id(new PhabricatorCrumbView()) - ->setName($provider->getProviderName())); + + if ($is_setup) { + $crumbs->addCrumb( + id(new PhabricatorCrumbView()) + ->setName(pht('Setup Admin Account'))); + $title = pht('Welcome to Phabricator'); + } else { + $crumbs->addCrumb( + id(new PhabricatorCrumbView()) + ->setName(pht('Register'))); + $crumbs->addCrumb( + id(new PhabricatorCrumbView()) + ->setName($provider->getProviderName())); + $title = pht('Phabricator Registration'); + } + + $welcome_view = null; + if ($is_setup) { + $welcome_view = id(new AphrontErrorView()) + ->setSeverity(AphrontErrorView::SEVERITY_NOTICE) + ->setTitle(pht('Welcome to Phabricator')) + ->appendChild( + pht( + 'Installation is complete. Register your administrator account '. + 'below to log in. You will be able to configure options and add '. + 'other authentication mechanisms (like LDAP or OAuth) later on.')); + } return $this->buildApplicationPage( array( $crumbs, + $welcome_view, $error_view, $form, ), @@ -381,6 +419,13 @@ final class PhabricatorAuthRegisterController return array($account, $provider, $response); } + private function loadSetupAccount() { + $provider = new PhabricatorAuthProviderPassword(); + $account = $provider->getDefaultExternalAccount(); + $response = null; + return array($account, $provider, $response); + } + private function loadProfilePicture(PhabricatorExternalAccount $account) { $phid = $account->getProfileImagePHID(); if (!$phid) { diff --git a/src/applications/auth/controller/PhabricatorAuthStartController.php b/src/applications/auth/controller/PhabricatorAuthStartController.php index 7e605174c1..d6cde983c1 100644 --- a/src/applications/auth/controller/PhabricatorAuthStartController.php +++ b/src/applications/auth/controller/PhabricatorAuthStartController.php @@ -44,6 +44,13 @@ final class PhabricatorAuthStartController } if (!$providers) { + if ($this->isFirstTimeSetup()) { + // If this is a fresh install, let the user register their admin + // account. + return id(new AphrontRedirectResponse()) + ->setURI($this->getApplicationURI('/register/')); + } + return $this->renderError( pht( "This Phabricator install is not configured with any enabled ". diff --git a/src/applications/config/check/PhabricatorSetupCheckAuth.php b/src/applications/config/check/PhabricatorSetupCheckAuth.php new file mode 100644 index 0000000000..9cc2348aa6 --- /dev/null +++ b/src/applications/config/check/PhabricatorSetupCheckAuth.php @@ -0,0 +1,27 @@ + '/auth/', + ), + pht('using the "Auth" application'))); + + $this + ->newIssue('auth.noproviders') + ->setShortName(pht('No Auth Providers')) + ->setName(pht('No Authentication Providers Configured')) + ->setMessage($message); + } + } +}