public function handleRequest(AphrontRequest $request)
 {
     $this->requireApplicationCapability(AuthManageProvidersCapability::CAPABILITY);
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $providers = PhabricatorAuthProvider::getAllBaseProviders();
     $e_provider = null;
     $errors = array();
     if ($request->isFormPost()) {
         $provider_string = $request->getStr('provider');
         if (!strlen($provider_string)) {
             $e_provider = pht('Required');
             $errors[] = pht('You must select an authentication provider.');
         } else {
             $found = false;
             foreach ($providers as $provider) {
                 if (get_class($provider) === $provider_string) {
                     $found = true;
                     break;
                 }
             }
             if (!$found) {
                 $e_provider = pht('Invalid');
                 $errors[] = pht('You must select a valid provider.');
             }
         }
         if (!$errors) {
             return id(new AphrontRedirectResponse())->setURI($this->getApplicationURI('/config/new/' . $provider_string . '/'));
         }
     }
     $options = id(new AphrontFormRadioButtonControl())->setLabel(pht('Provider'))->setName('provider')->setError($e_provider);
     $configured = PhabricatorAuthProvider::getAllProviders();
     $configured_classes = array();
     foreach ($configured as $configured_provider) {
         $configured_classes[get_class($configured_provider)] = true;
     }
     // Sort providers by login order, and move disabled providers to the
     // bottom.
     $providers = msort($providers, 'getLoginOrder');
     $providers = array_diff_key($providers, $configured_classes) + $providers;
     foreach ($providers as $provider) {
         if (isset($configured_classes[get_class($provider)])) {
             $disabled = true;
             $description = pht('This provider is already configured.');
         } else {
             $disabled = false;
             $description = $provider->getDescriptionForCreate();
         }
         $options->addButton(get_class($provider), $provider->getNameForCreate(), $description, $disabled ? 'disabled' : null, $disabled);
     }
     $form = id(new AphrontFormView())->setUser($viewer)->appendChild($options)->appendChild(id(new AphrontFormSubmitControl())->addCancelButton($this->getApplicationURI())->setValue(pht('Continue')));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Provider'))->setFormErrors($errors)->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)->setForm($form);
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('Add Provider'));
     $crumbs->setBorder(true);
     $title = pht('Add Auth Provider');
     $header = id(new PHUIHeaderView())->setHeader($title)->setHeaderIcon('fa-plus-square');
     $view = id(new PHUITwoColumnView())->setHeader($header)->setFooter(array($form_box));
     return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->appendChild($view);
 }
 public function getProvider()
 {
     if (!$this->provider) {
         $base = PhabricatorAuthProvider::getAllBaseProviders();
         $found = null;
         foreach ($base as $provider) {
             if (get_class($provider) == $this->providerClass) {
                 $found = $provider;
                 break;
             }
         }
         if ($found) {
             $this->provider = id(clone $found)->attachProviderConfig($this);
         }
     }
     return $this->provider;
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $viewer = $request->getUser();
     if ($this->configID) {
         $config = id(new PhabricatorAuthProviderConfigQuery())->setViewer($viewer)->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->withIDs(array($this->configID))->executeOne();
         if (!$config) {
             return new Aphront404Response();
         }
         $provider = $config->getProvider();
         if (!$provider) {
             return new Aphront404Response();
         }
         $is_new = false;
     } else {
         $providers = PhabricatorAuthProvider::getAllBaseProviders();
         foreach ($providers as $candidate_provider) {
             if (get_class($candidate_provider) === $this->providerClass) {
                 $provider = $candidate_provider;
                 break;
             }
         }
         if (!$provider) {
             return new Aphront404Response();
         }
         // TODO: When we have multi-auth providers, support them here.
         $configs = id(new PhabricatorAuthProviderConfigQuery())->setViewer($viewer)->withProviderClasses(array(get_class($provider)))->execute();
         if ($configs) {
             $id = head($configs)->getID();
             $dialog = id(new AphrontDialogView())->setUser($viewer)->setMethod('GET')->setSubmitURI($this->getApplicationURI('config/edit/' . $id . '/'))->setTitle(pht('Provider Already Configured'))->appendChild(pht('This provider ("%s") already exists, and you can not add more ' . 'than one instance of it. You can edit the existing provider, ' . 'or you can choose a different provider.', $provider->getProviderName()))->addCancelButton($this->getApplicationURI('config/new/'))->addSubmitButton(pht('Edit Existing Provider'));
             return id(new AphrontDialogResponse())->setDialog($dialog);
         }
         $config = $provider->getDefaultProviderConfig();
         $provider->attachProviderConfig($config);
         $is_new = true;
     }
     $errors = array();
     $v_registration = $config->getShouldAllowRegistration();
     $v_link = $config->getShouldAllowLink();
     $v_unlink = $config->getShouldAllowUnlink();
     $v_trust_email = $config->getShouldTrustEmails();
     if ($request->isFormPost()) {
         $properties = $provider->readFormValuesFromRequest($request);
         list($errors, $issues, $properties) = $provider->processEditForm($request, $properties);
         $xactions = array();
         if (!$errors) {
             if ($is_new) {
                 if (!strlen($config->getProviderType())) {
                     $config->setProviderType($provider->getProviderType());
                 }
                 if (!strlen($config->getProviderDomain())) {
                     $config->setProviderDomain($provider->getProviderDomain());
                 }
             }
             $xactions[] = id(new PhabricatorAuthProviderConfigTransaction())->setTransactionType(PhabricatorAuthProviderConfigTransaction::TYPE_REGISTRATION)->setNewValue($request->getInt('allowRegistration', 0));
             $xactions[] = id(new PhabricatorAuthProviderConfigTransaction())->setTransactionType(PhabricatorAuthProviderConfigTransaction::TYPE_LINK)->setNewValue($request->getInt('allowLink', 0));
             $xactions[] = id(new PhabricatorAuthProviderConfigTransaction())->setTransactionType(PhabricatorAuthProviderConfigTransaction::TYPE_UNLINK)->setNewValue($request->getInt('allowUnlink', 0));
             $xactions[] = id(new PhabricatorAuthProviderConfigTransaction())->setTransactionType(PhabricatorAuthProviderConfigTransaction::TYPE_TRUST_EMAILS)->setNewValue($request->getInt('trustEmails', 0));
             foreach ($properties as $key => $value) {
                 $xactions[] = id(new PhabricatorAuthProviderConfigTransaction())->setTransactionType(PhabricatorAuthProviderConfigTransaction::TYPE_PROPERTY)->setMetadataValue('auth:property', $key)->setNewValue($value);
             }
             if ($is_new) {
                 $config->save();
             }
             $editor = id(new PhabricatorAuthProviderConfigEditor())->setActor($viewer)->setContentSourceFromRequest($request)->setContinueOnNoEffect(true)->applyTransactions($config, $xactions);
             if ($provider->hasSetupStep() && $is_new) {
                 $id = $config->getID();
                 $next_uri = $this->getApplicationURI('config/edit/' . $id . '/');
             } else {
                 $next_uri = $this->getApplicationURI();
             }
             return id(new AphrontRedirectResponse())->setURI($next_uri);
         }
     } else {
         $properties = $provider->readFormValuesFromProvider();
         $issues = array();
     }
     if ($is_new) {
         $button = pht('Add Provider');
         $crumb = pht('Add Provider');
         $title = pht('Add Authentication Provider');
         $cancel_uri = $this->getApplicationURI('/config/new/');
     } else {
         $button = pht('Save');
         $crumb = pht('Edit Provider');
         $title = pht('Edit Authentication Provider');
         $cancel_uri = $this->getApplicationURI();
     }
     $config_name = 'auth.email-domains';
     $config_href = '/config/edit/' . $config_name . '/';
     $email_domains = PhabricatorEnv::getEnvConfig($config_name);
     if ($email_domains) {
         $registration_warning = pht('Users will only be able to register with a verified email address ' . 'at one of the configured [[ %s | %s ]] domains: **%s**', $config_href, $config_name, implode(', ', $email_domains));
     } else {
         $registration_warning = pht("NOTE: Any user who can browse to this install's login page will be " . "able to register a Phabricator account. To restrict who can register " . "an account, configure [[ %s | %s ]].", $config_href, $config_name);
     }
     $str_registration = array(phutil_tag('strong', array(), pht('Allow Registration:')), ' ', pht('Allow users to register new Phabricator accounts using this ' . 'provider. If you disable registration, users can still use this ' . 'provider to log in to existing accounts, but will not be able to ' . 'create new accounts.'));
     $str_link = hsprintf('<strong>%s:</strong> %s', pht('Allow Linking Accounts'), pht('Allow users to link account credentials for this provider to ' . 'existing Phabricator accounts. There is normally no reason to ' . 'disable this unless you are trying to move away from a provider ' . 'and want to stop users from creating new account links.'));
     $str_unlink = hsprintf('<strong>%s:</strong> %s', pht('Allow Unlinking Accounts'), pht('Allow users to unlink account credentials for this provider from ' . 'existing Phabricator accounts. If you disable this, Phabricator ' . 'accounts will be permanently bound to provider accounts.'));
     $str_trusted_email = hsprintf('<strong>%s:</strong> %s', pht('Trust Email Addresses'), pht('Phabricator will skip email verification for accounts registered ' . 'through this provider.'));
     $status_tag = id(new PHUITagView())->setType(PHUITagView::TYPE_STATE);
     if ($is_new) {
         $status_tag->setName(pht('New Provider'))->setBackgroundColor('blue');
     } else {
         if ($config->getIsEnabled()) {
             $status_tag->setName(pht('Enabled'))->setBackgroundColor('green');
         } else {
             $status_tag->setName(pht('Disabled'))->setBackgroundColor('red');
         }
     }
     $form = id(new AphrontFormView())->setUser($viewer)->appendChild(id(new AphrontFormStaticControl())->setLabel(pht('Provider'))->setValue($provider->getProviderName()))->appendChild(id(new AphrontFormStaticControl())->setLabel(pht('Status'))->setValue($status_tag))->appendChild(id(new AphrontFormCheckboxControl())->setLabel(pht('Allow'))->addCheckbox('allowRegistration', 1, $str_registration, $v_registration))->appendRemarkupInstructions($registration_warning)->appendChild(id(new AphrontFormCheckboxControl())->addCheckbox('allowLink', 1, $str_link, $v_link))->appendChild(id(new AphrontFormCheckboxControl())->addCheckbox('allowUnlink', 1, $str_unlink, $v_unlink));
     if ($provider->shouldAllowEmailTrustConfiguration()) {
         $form->appendChild(id(new AphrontFormCheckboxControl())->addCheckbox('trustEmails', 1, $str_trusted_email, $v_trust_email));
     }
     $provider->extendEditForm($request, $form, $properties, $issues);
     $form->appendChild(id(new AphrontFormSubmitControl())->addCancelButton($cancel_uri)->setValue($button));
     $help = $provider->getConfigurationHelp();
     if ($help) {
         $form->appendChild(id(new PHUIFormDividerControl()));
         $form->appendRemarkupInstructions($help);
     }
     $footer = $provider->renderConfigurationFooter();
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb($crumb);
     $xaction_view = null;
     if (!$is_new) {
         $xactions = id(new PhabricatorAuthProviderConfigTransactionQuery())->withObjectPHIDs(array($config->getPHID()))->setViewer($viewer)->execute();
         foreach ($xactions as $xaction) {
             $xaction->setProvider($provider);
         }
         $xaction_view = id(new PhabricatorApplicationTransactionView())->setUser($viewer)->setObjectPHID($config->getPHID())->setTransactions($xactions);
     }
     $form_box = id(new PHUIObjectBoxView())->setHeaderText($title)->setFormErrors($errors)->setForm($form);
     return $this->buildApplicationPage(array($crumbs, $form_box, $footer, $xaction_view), array('title' => $title));
 }