diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 29b9592360..3ddd775253 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2122,6 +2122,7 @@ phutil_register_library_map(array( 'PhabricatorPeopleUserPHIDType' => 'applications/people/phid/PhabricatorPeopleUserPHIDType.php', 'PhabricatorPeopleWelcomeController' => 'applications/people/controller/PhabricatorPeopleWelcomeController.php', 'PhabricatorPersonaAuthProvider' => 'applications/auth/provider/PhabricatorPersonaAuthProvider.php', + 'PhabricatorPhabricatorAuthProvider' => 'applications/auth/provider/PhabricatorPhabricatorAuthProvider.php', 'PhabricatorPhameApplication' => 'applications/phame/application/PhabricatorPhameApplication.php', 'PhabricatorPhameBlogPHIDType' => 'applications/phame/phid/PhabricatorPhameBlogPHIDType.php', 'PhabricatorPhameConfigOptions' => 'applications/phame/config/PhabricatorPhameConfigOptions.php', @@ -5321,6 +5322,7 @@ phutil_register_library_map(array( 'PhabricatorPeopleUserPHIDType' => 'PhabricatorPHIDType', 'PhabricatorPeopleWelcomeController' => 'PhabricatorPeopleController', 'PhabricatorPersonaAuthProvider' => 'PhabricatorAuthProvider', + 'PhabricatorPhabricatorAuthProvider' => 'PhabricatorOAuth2AuthProvider', 'PhabricatorPhameApplication' => 'PhabricatorApplication', 'PhabricatorPhameBlogPHIDType' => 'PhabricatorPHIDType', 'PhabricatorPhameConfigOptions' => 'PhabricatorApplicationConfigOptions', diff --git a/src/applications/auth/controller/config/PhabricatorAuthEditController.php b/src/applications/auth/controller/config/PhabricatorAuthEditController.php index 325a39489a..aff66ec6e9 100644 --- a/src/applications/auth/controller/config/PhabricatorAuthEditController.php +++ b/src/applications/auth/controller/config/PhabricatorAuthEditController.php @@ -159,7 +159,11 @@ final class PhabricatorAuthEditController } if ($is_new) { - $button = pht('Add Provider'); + if ($provider->hasSetupStep()) { + $button = pht('Next Step'); + } else { + $button = pht('Add Provider'); + } $crumb = pht('Add Provider'); $title = pht('Add Authentication Provider'); $cancel_uri = $this->getApplicationURI('/config/new/'); diff --git a/src/applications/auth/provider/PhabricatorPhabricatorAuthProvider.php b/src/applications/auth/provider/PhabricatorPhabricatorAuthProvider.php new file mode 100644 index 0000000000..b7ba0b6a73 --- /dev/null +++ b/src/applications/auth/provider/PhabricatorPhabricatorAuthProvider.php @@ -0,0 +1,203 @@ +isCreate()) { + return pht( + '**Step 1 of 2** - Name Phabricator OAuth Instance'. + 'Choose a permanent name for the OAuth server instance of '. + 'Phabricator. //This// instance of Phabricator uses this name '. + 'internally to keep track of the OAuth server instance of '. + 'Phabricator, in case the URL changes later.'); + } + + return parent::getConfigurationHelp(); + } + protected function getProviderConfigurationHelp() { + $config = $this->getProviderConfig(); + $base_uri = rtrim( + $config->getProperty(self::PROPERTY_PHABRICATOR_URI), '/'); + $login_uri = PhabricatorEnv::getURI($this->getLoginURI()); + + return pht( + "**Step 2 of 2 - Configure Phabricator OAuth Instance**". + "To configure Phabricator OAuth, create a new application here:". + "\n\n". + "%s/oauthserver/client/create/". + "\n\n". + "When creating your application, use these settings:". + "\n\n". + " - **Redirect URI:** Set this to: `%s`". + "\n\n". + "After completing configuration, copy the **Client ID** and ". + "**Client Secret** to the fields above. (You may need to generate the ". + "client secret by clicking 'New Secret' first.)", + $base_uri, + $login_uri); + } + + protected function newOAuthAdapter() { + $config = $this->getProviderConfig(); + return id(new PhutilPhabricatorAuthAdapter()) + ->setAdapterDomain($config->getProviderDomain()) + ->setPhabricatorBaseURI( + $config->getProperty(self::PROPERTY_PHABRICATOR_URI)); + } + + protected function getLoginIcon() { + return 'Phabricator'; + } + + private function isCreate() { + return !$this->getProviderConfig()->getID(); + } + + public function readFormValuesFromProvider() { + $config = $this->getProviderConfig(); + $uri = $config->getProperty(self::PROPERTY_PHABRICATOR_URI); + + return parent::readFormValuesFromProvider() + array( + self::PROPERTY_PHABRICATOR_NAME => $this->getProviderDomain(), + self::PROPERTY_PHABRICATOR_URI => $uri, + ); + } + + public function readFormValuesFromRequest(AphrontRequest $request) { + $is_setup = $this->isCreate(); + if ($is_setup) { + $parent_values = array(); + $name = $request->getStr(self::PROPERTY_PHABRICATOR_NAME); + } else { + $parent_values = parent::readFormValuesFromRequest($request); + $name = $this->getProviderDomain(); + } + + return $parent_values + array( + self::PROPERTY_PHABRICATOR_NAME => $name, + self::PROPERTY_PHABRICATOR_URI => + $request->getStr(self::PROPERTY_PHABRICATOR_URI), + ); + } + + public function processEditForm( + AphrontRequest $request, + array $values) { + + $is_setup = $this->isCreate(); + + if (!$is_setup) { + list($errors, $issues, $values) = + parent::processEditForm($request, $values); + } else { + $errors = array(); + $issues = array(); + } + + $key_name = self::PROPERTY_PHABRICATOR_NAME; + $key_uri = self::PROPERTY_PHABRICATOR_URI; + + if (!strlen($values[$key_name])) { + $errors[] = pht('Phabricator instance name is required.'); + $issues[$key_name] = pht('Required'); + } else if (!preg_match('/^[a-z0-9.]+\z/', $values[$key_name])) { + $errors[] = pht( + 'Phabricator instance name must contain only lowercase letters, '. + 'digits, and periods.'); + $issues[$key_name] = pht('Invalid'); + } + + if (!strlen($values[$key_uri])) { + $errors[] = pht('Phabricator base URI is required.'); + $issues[$key_uri] = pht('Required'); + } else { + $uri = new PhutilURI($values[$key_uri]); + if (!$uri->getProtocol()) { + $errors[] = pht( + 'Phabricator base URI should include protocol (like "https://").'); + $issues[$key_uri] = pht('Invalid'); + } + } + + if (!$errors && $is_setup) { + $config = $this->getProviderConfig(); + + $config->setProviderDomain($values[$key_name]); + } + + return array($errors, $issues, $values); + } + + public function extendEditForm( + AphrontRequest $request, + AphrontFormView $form, + array $values, + array $issues) { + + $is_setup = $this->isCreate(); + + $e_required = $request->isFormPost() ? null : true; + + $v_name = $values[self::PROPERTY_PHABRICATOR_NAME]; + if ($is_setup) { + $e_name = idx($issues, self::PROPERTY_PHABRICATOR_NAME, $e_required); + } else { + $e_name = null; + } + + $v_uri = $values[self::PROPERTY_PHABRICATOR_URI]; + $e_uri = idx($issues, self::PROPERTY_PHABRICATOR_URI, $e_required); + + if ($is_setup) { + $form + ->appendChild( + id(new AphrontFormTextControl()) + ->setLabel(pht('Phabricator Instance Name')) + ->setValue($v_name) + ->setName(self::PROPERTY_PHABRICATOR_NAME) + ->setError($e_name) + ->setCaption(pht( + 'Use lowercase letters, digits, and periods. For example: %s', + phutil_tag( + 'tt', + array(), + '`phabricator.oauthserver`')))); + } else { + $form + ->appendChild( + id(new AphrontFormStaticControl()) + ->setLabel(pht('Phabricator Instance Name')) + ->setValue($v_name)); + } + + $form + ->appendChild( + id(new AphrontFormTextControl()) + ->setLabel(pht('Phabricator Base URI')) + ->setValue($v_uri) + ->setName(self::PROPERTY_PHABRICATOR_URI) + ->setCaption( + pht( + 'The URI where the OAuth server instance of Phabricator is '. + 'installed. For example: %s', + phutil_tag('tt', array(), 'https://phabricator.mycompany.com/'))) + ->setError($e_uri)); + + if (!$is_setup) { + parent::extendEditForm($request, $form, $values, $issues); + } + } + + public function hasSetupStep() { + return true; + } + +}