[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/auth/provider/ -> PhabricatorJIRAAuthProvider.php (source)

   1  <?php
   2  
   3  final class PhabricatorJIRAAuthProvider extends PhabricatorOAuth1AuthProvider {
   4  
   5    public function getJIRABaseURI() {
   6      return $this->getProviderConfig()->getProperty(self::PROPERTY_JIRA_URI);
   7    }
   8  
   9    public function getProviderName() {
  10      return pht('JIRA');
  11    }
  12  
  13    public function getDescriptionForCreate() {
  14      return pht('Configure JIRA OAuth. NOTE: Only supports JIRA 6.');
  15    }
  16  
  17    public function getConfigurationHelp() {
  18      return $this->getProviderConfigurationHelp();
  19    }
  20  
  21    protected function getProviderConfigurationHelp() {
  22      if ($this->isSetup()) {
  23        return pht(
  24          "**Step 1 of 2**: Provide the name and URI for your JIRA install.\n\n".
  25          "In the next step, you will configure JIRA.");
  26      } else {
  27        $login_uri = PhabricatorEnv::getURI($this->getLoginURI());
  28        return pht(
  29          "**Step 2 of 2**: In this step, you will configure JIRA.\n\n".
  30          "**Create a JIRA Application**: Log into JIRA and go to ".
  31          "**Administration**, then **Add-ons**, then **Application Links**. ".
  32          "Click the button labeled **Add Application Link**, and use these ".
  33          "settings to create an application:\n\n".
  34          "  - **Server URL**: `%s`\n".
  35          "  - Then, click **Next**. On the second page:\n".
  36          "  - **Application Name**: `Phabricator`\n".
  37          "  - **Application Type**: `Generic Application`\n".
  38          "  - Then, click **Create**.\n\n".
  39          "**Configure Your Application**: Find the application you just ".
  40          "created in the table, and click the **Configure** link under ".
  41          "**Actions**. Select **Incoming Authentication** and click the ".
  42          "**OAuth** tab (it may be selected by default). Then, use these ".
  43          "settings:\n\n".
  44          "  - **Consumer Key**: Set this to the \"Consumer Key\" value in the ".
  45          "form above.\n".
  46          "  - **Consumer Name**: `Phabricator`\n".
  47          "  - **Public Key**: Set this to the \"Public Key\" value in the ".
  48          "form above.\n".
  49          "  - **Consumer Callback URL**: `%s`\n".
  50          "Click **Save** in JIRA. Authentication should now be configured, ".
  51          "and this provider should work correctly.",
  52          PhabricatorEnv::getProductionURI('/'),
  53          $login_uri);
  54      }
  55    }
  56  
  57    protected function newOAuthAdapter() {
  58      $config = $this->getProviderConfig();
  59  
  60      return id(new PhutilJIRAAuthAdapter())
  61        ->setAdapterDomain($config->getProviderDomain())
  62        ->setJIRABaseURI($config->getProperty(self::PROPERTY_JIRA_URI))
  63        ->setPrivateKey(
  64          new PhutilOpaqueEnvelope(
  65            $config->getProperty(self::PROPERTY_PRIVATE_KEY)));
  66    }
  67  
  68    protected function getLoginIcon() {
  69      return 'Jira';
  70    }
  71  
  72    private function isSetup() {
  73      return !$this->getProviderConfig()->getID();
  74    }
  75  
  76    const PROPERTY_JIRA_NAME = 'oauth1:jira:name';
  77    const PROPERTY_JIRA_URI = 'oauth1:jira:uri';
  78    const PROPERTY_PUBLIC_KEY = 'oauth1:jira:key:public';
  79    const PROPERTY_PRIVATE_KEY = 'oauth1:jira:key:private';
  80  
  81  
  82    public function readFormValuesFromProvider() {
  83      $config = $this->getProviderConfig();
  84      $uri = $config->getProperty(self::PROPERTY_JIRA_URI);
  85  
  86      return array(
  87        self::PROPERTY_JIRA_NAME => $this->getProviderDomain(),
  88        self::PROPERTY_JIRA_URI => $uri,
  89      );
  90    }
  91  
  92    public function readFormValuesFromRequest(AphrontRequest $request) {
  93      $is_setup = $this->isSetup();
  94      if ($is_setup) {
  95        $name = $request->getStr(self::PROPERTY_JIRA_NAME);
  96      } else {
  97        $name = $this->getProviderDomain();
  98      }
  99  
 100      return array(
 101        self::PROPERTY_JIRA_NAME => $name,
 102        self::PROPERTY_JIRA_URI => $request->getStr(self::PROPERTY_JIRA_URI),
 103      );
 104    }
 105  
 106    public function processEditForm(
 107      AphrontRequest $request,
 108      array $values) {
 109      $errors = array();
 110      $issues = array();
 111  
 112      $is_setup = $this->isSetup();
 113  
 114      $key_name = self::PROPERTY_JIRA_NAME;
 115      $key_uri = self::PROPERTY_JIRA_URI;
 116  
 117      if (!strlen($values[$key_name])) {
 118        $errors[] = pht('JIRA instance name is required.');
 119        $issues[$key_name] = pht('Required');
 120      } else if (!preg_match('/^[a-z0-9.]+\z/', $values[$key_name])) {
 121        $errors[] = pht(
 122          'JIRA instance name must contain only lowercase letters, digits, and '.
 123          'period.');
 124        $issues[$key_name] = pht('Invalid');
 125      }
 126  
 127      if (!strlen($values[$key_uri])) {
 128        $errors[] = pht('JIRA base URI is required.');
 129        $issues[$key_uri] = pht('Required');
 130      } else {
 131        $uri = new PhutilURI($values[$key_uri]);
 132        if (!$uri->getProtocol()) {
 133          $errors[] = pht(
 134            'JIRA base URI should include protocol (like "https://").');
 135          $issues[$key_uri] = pht('Invalid');
 136        }
 137      }
 138  
 139      if (!$errors && $is_setup) {
 140        $config = $this->getProviderConfig();
 141  
 142        $config->setProviderDomain($values[$key_name]);
 143  
 144        $consumer_key = 'phjira.'.Filesystem::readRandomCharacters(16);
 145        list($public, $private) = PhutilJIRAAuthAdapter::newJIRAKeypair();
 146  
 147        $config->setProperty(self::PROPERTY_PUBLIC_KEY, $public);
 148        $config->setProperty(self::PROPERTY_PRIVATE_KEY, $private);
 149        $config->setProperty(self::PROPERTY_CONSUMER_KEY, $consumer_key);
 150      }
 151  
 152      return array($errors, $issues, $values);
 153    }
 154  
 155    public function extendEditForm(
 156      AphrontRequest $request,
 157      AphrontFormView $form,
 158      array $values,
 159      array $issues) {
 160  
 161      if (!function_exists('openssl_pkey_new')) {
 162        // TODO: This could be a bit prettier.
 163        throw new Exception(
 164          pht(
 165            "The PHP 'openssl' extension is not installed. You must install ".
 166            "this extension in order to add a JIRA authentication provider, ".
 167            "because JIRA OAuth requests use the RSA-SHA1 signing algorithm. ".
 168            "Install the 'openssl' extension, restart your webserver, and try ".
 169            "again."));
 170      }
 171  
 172      $form->appendRemarkupInstructions(
 173        pht(
 174          'NOTE: This provider **only supports JIRA 6**. It will not work with '.
 175          'JIRA 5 or earlier.'));
 176  
 177      $is_setup = $this->isSetup();
 178  
 179      $e_required = $request->isFormPost() ? null : true;
 180  
 181      $v_name = $values[self::PROPERTY_JIRA_NAME];
 182      if ($is_setup) {
 183        $e_name = idx($issues, self::PROPERTY_JIRA_NAME, $e_required);
 184      } else {
 185        $e_name = null;
 186      }
 187  
 188      $v_uri = $values[self::PROPERTY_JIRA_URI];
 189      $e_uri = idx($issues, self::PROPERTY_JIRA_URI, $e_required);
 190  
 191      if ($is_setup) {
 192        $form
 193          ->appendRemarkupInstructions(
 194            pht(
 195              "**JIRA Instance Name**\n\n".
 196              "Choose a permanent name for this instance of JIRA. Phabricator ".
 197              "uses this name internally to keep track of this instance of ".
 198              "JIRA, in case the URL changes later.\n\n".
 199              "Use lowercase letters, digits, and period. For example, ".
 200              "`jira`, `jira.mycompany` or `jira.engineering` are reasonable ".
 201              "names."))
 202          ->appendChild(
 203            id(new AphrontFormTextControl())
 204              ->setLabel(pht('JIRA Instance Name'))
 205              ->setValue($v_name)
 206              ->setName(self::PROPERTY_JIRA_NAME)
 207              ->setError($e_name));
 208      } else {
 209        $form
 210          ->appendChild(
 211            id(new AphrontFormStaticControl())
 212              ->setLabel(pht('JIRA Instance Name'))
 213              ->setValue($v_name));
 214      }
 215  
 216      $form
 217        ->appendChild(
 218          id(new AphrontFormTextControl())
 219            ->setLabel(pht('JIRA Base URI'))
 220            ->setValue($v_uri)
 221            ->setName(self::PROPERTY_JIRA_URI)
 222            ->setCaption(
 223              pht(
 224                'The URI where JIRA is installed. For example: %s',
 225                phutil_tag('tt', array(), 'https://jira.mycompany.com/')))
 226            ->setError($e_uri));
 227  
 228      if (!$is_setup) {
 229        $config = $this->getProviderConfig();
 230  
 231  
 232        $ckey = $config->getProperty(self::PROPERTY_CONSUMER_KEY);
 233        $ckey = phutil_tag('tt', array(), $ckey);
 234  
 235        $pkey = $config->getProperty(self::PROPERTY_PUBLIC_KEY);
 236        $pkey = phutil_escape_html_newlines($pkey);
 237        $pkey = phutil_tag('tt', array(), $pkey);
 238  
 239        $form
 240          ->appendRemarkupInstructions(
 241            pht(
 242              'NOTE: **To complete setup**, copy and paste these keys into JIRA '.
 243              'according to the instructions below.'))
 244          ->appendChild(
 245            id(new AphrontFormStaticControl())
 246              ->setLabel(pht('Consumer Key'))
 247              ->setValue($ckey))
 248          ->appendChild(
 249            id(new AphrontFormStaticControl())
 250              ->setLabel(pht('Public Key'))
 251              ->setValue($pkey));
 252      }
 253  
 254    }
 255  
 256  
 257    /**
 258     * JIRA uses a setup step to generate public/private keys.
 259     */
 260    public function hasSetupStep() {
 261      return true;
 262    }
 263  
 264    public static function getJIRAProvider() {
 265      $providers = self::getAllEnabledProviders();
 266  
 267      foreach ($providers as $provider) {
 268        if ($provider instanceof PhabricatorJIRAAuthProvider) {
 269          return $provider;
 270        }
 271      }
 272  
 273      return null;
 274    }
 275  
 276    public function newJIRAFuture(
 277      PhabricatorExternalAccount $account,
 278      $path,
 279      $method,
 280      $params = array()) {
 281  
 282      $adapter = clone $this->getAdapter();
 283      $adapter->setToken($account->getProperty('oauth1.token'));
 284      $adapter->setTokenSecret($account->getProperty('oauth1.token.secret'));
 285  
 286      return $adapter->newJIRAFuture($path, $method, $params);
 287    }
 288  
 289  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1