[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/diffusion/controller/ -> DiffusionRepositoryCreateController.php (source)

   1  <?php
   2  
   3  final class DiffusionRepositoryCreateController
   4    extends DiffusionRepositoryEditController {
   5  
   6    private $edit;
   7    private $repository;
   8  
   9    public function willProcessRequest(array $data) {
  10      parent::willProcessRequest($data);
  11      $this->edit = $data['edit'];
  12    }
  13  
  14    public function processRequest() {
  15      $request = $this->getRequest();
  16      $viewer = $request->getUser();
  17  
  18      // NOTE: We can end up here via either "Create Repository", or via
  19      // "Import Repository", or via "Edit Remote", or via "Edit Policies". In
  20      // the latter two cases, we show only a few of the pages.
  21  
  22      $repository = null;
  23      switch ($this->edit) {
  24        case 'remote':
  25        case 'policy':
  26          $repository = $this->getDiffusionRequest()->getRepository();
  27  
  28          // Make sure we have CAN_EDIT.
  29          PhabricatorPolicyFilter::requireCapability(
  30            $viewer,
  31            $repository,
  32            PhabricatorPolicyCapability::CAN_EDIT);
  33  
  34          $this->setRepository($repository);
  35  
  36          $cancel_uri = $this->getRepositoryControllerURI($repository, 'edit/');
  37          break;
  38        case 'import':
  39        case 'create':
  40          $this->requireApplicationCapability(
  41            DiffusionCreateRepositoriesCapability::CAPABILITY);
  42  
  43          $cancel_uri = $this->getApplicationURI('new/');
  44          break;
  45        default:
  46          throw new Exception('Invalid edit operation!');
  47      }
  48  
  49      $form = id(new PHUIPagedFormView())
  50        ->setUser($viewer)
  51        ->setCancelURI($cancel_uri);
  52  
  53      switch ($this->edit) {
  54        case 'remote':
  55          $title = pht('Edit Remote');
  56          $form
  57            ->addPage('remote-uri', $this->buildRemoteURIPage())
  58            ->addPage('auth', $this->buildAuthPage());
  59          break;
  60        case 'policy':
  61          $title = pht('Edit Policies');
  62          $form
  63            ->addPage('policy', $this->buildPolicyPage());
  64          break;
  65        case 'create':
  66          $title = pht('Create Repository');
  67          $form
  68            ->addPage('vcs', $this->buildVCSPage())
  69            ->addPage('name', $this->buildNamePage())
  70            ->addPage('policy', $this->buildPolicyPage())
  71            ->addPage('done', $this->buildDonePage());
  72          break;
  73        case 'import':
  74          $title = pht('Import Repository');
  75          $form
  76            ->addPage('vcs', $this->buildVCSPage())
  77            ->addPage('name', $this->buildNamePage())
  78            ->addPage('remote-uri', $this->buildRemoteURIPage())
  79            ->addPage('auth', $this->buildAuthPage())
  80            ->addPage('policy', $this->buildPolicyPage())
  81            ->addPage('done', $this->buildDonePage());
  82          break;
  83      }
  84  
  85      if ($request->isFormPost()) {
  86        $form->readFromRequest($request);
  87        if ($form->isComplete()) {
  88  
  89          $is_create = ($this->edit === 'import' || $this->edit === 'create');
  90          $is_auth = ($this->edit == 'import' || $this->edit == 'remote');
  91          $is_policy = ($this->edit != 'remote');
  92          $is_init = ($this->edit == 'create');
  93  
  94          if ($is_create) {
  95            $repository = PhabricatorRepository::initializeNewRepository(
  96              $viewer);
  97          }
  98  
  99          $template = id(new PhabricatorRepositoryTransaction());
 100  
 101          $type_name = PhabricatorRepositoryTransaction::TYPE_NAME;
 102          $type_vcs = PhabricatorRepositoryTransaction::TYPE_VCS;
 103          $type_activate = PhabricatorRepositoryTransaction::TYPE_ACTIVATE;
 104          $type_local_path = PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH;
 105          $type_remote_uri = PhabricatorRepositoryTransaction::TYPE_REMOTE_URI;
 106          $type_hosting = PhabricatorRepositoryTransaction::TYPE_HOSTING;
 107          $type_http = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP;
 108          $type_ssh = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH;
 109          $type_credential = PhabricatorRepositoryTransaction::TYPE_CREDENTIAL;
 110          $type_view = PhabricatorTransactions::TYPE_VIEW_POLICY;
 111          $type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY;
 112          $type_push = PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY;
 113  
 114          $xactions = array();
 115  
 116          // If we're creating a new repository, set all this core stuff.
 117          if ($is_create) {
 118            $callsign = $form->getPage('name')
 119              ->getControl('callsign')->getValue();
 120  
 121            // We must set this to a unique value to save the repository
 122            // initially, and it's immutable, so we don't bother using
 123            // transactions to apply this change.
 124            $repository->setCallsign($callsign);
 125  
 126            // Put the repository in "Importing" mode until we finish
 127            // parsing it.
 128            $repository->setDetail('importing', true);
 129  
 130            $xactions[] = id(clone $template)
 131              ->setTransactionType($type_name)
 132              ->setNewValue(
 133                $form->getPage('name')->getControl('name')->getValue());
 134  
 135            $xactions[] = id(clone $template)
 136              ->setTransactionType($type_vcs)
 137              ->setNewValue(
 138                $form->getPage('vcs')->getControl('vcs')->getValue());
 139  
 140            $activate = $form->getPage('done')
 141              ->getControl('activate')->getValue();
 142            $xactions[] = id(clone $template)
 143              ->setTransactionType($type_activate)
 144              ->setNewValue(
 145                ($activate == 'start'));
 146  
 147            $default_local_path = PhabricatorEnv::getEnvConfig(
 148              'repository.default-local-path');
 149  
 150            $default_local_path = rtrim($default_local_path, '/');
 151            $default_local_path = $default_local_path.'/'.$callsign.'/';
 152  
 153            $xactions[] = id(clone $template)
 154              ->setTransactionType($type_local_path)
 155              ->setNewValue($default_local_path);
 156          }
 157  
 158          if ($is_init) {
 159            $xactions[] = id(clone $template)
 160              ->setTransactionType($type_hosting)
 161              ->setNewValue(true);
 162            $vcs = $form->getPage('vcs')->getControl('vcs')->getValue();
 163            if ($vcs != PhabricatorRepositoryType::REPOSITORY_TYPE_SVN) {
 164              if (PhabricatorEnv::getEnvConfig('diffusion.allow-http-auth')) {
 165                $v_http_mode = PhabricatorRepository::SERVE_READWRITE;
 166              } else {
 167                $v_http_mode = PhabricatorRepository::SERVE_OFF;
 168              }
 169              $xactions[] = id(clone $template)
 170                ->setTransactionType($type_http)
 171                ->setNewValue($v_http_mode);
 172            }
 173  
 174            if (PhabricatorEnv::getEnvConfig('diffusion.ssh-user')) {
 175              $v_ssh_mode = PhabricatorRepository::SERVE_READWRITE;
 176            } else {
 177              $v_ssh_mode = PhabricatorRepository::SERVE_OFF;
 178            }
 179            $xactions[] = id(clone $template)
 180              ->setTransactionType($type_ssh)
 181              ->setNewValue($v_ssh_mode);
 182          }
 183  
 184          if ($is_auth) {
 185            $xactions[] = id(clone $template)
 186              ->setTransactionType($type_remote_uri)
 187              ->setNewValue(
 188                $form->getPage('remote-uri')->getControl('remoteURI')
 189                  ->getValue());
 190  
 191            $xactions[] = id(clone $template)
 192              ->setTransactionType($type_credential)
 193              ->setNewValue(
 194                $form->getPage('auth')->getControl('credential')->getValue());
 195          }
 196  
 197          if ($is_policy) {
 198            $xactions[] = id(clone $template)
 199              ->setTransactionType($type_view)
 200              ->setNewValue(
 201                $form->getPage('policy')->getControl('viewPolicy')->getValue());
 202  
 203            $xactions[] = id(clone $template)
 204              ->setTransactionType($type_edit)
 205              ->setNewValue(
 206                $form->getPage('policy')->getControl('editPolicy')->getValue());
 207  
 208            if ($is_init || $repository->isHosted()) {
 209              $xactions[] = id(clone $template)
 210                ->setTransactionType($type_push)
 211                ->setNewValue(
 212                  $form->getPage('policy')->getControl('pushPolicy')->getValue());
 213            }
 214          }
 215  
 216          id(new PhabricatorRepositoryEditor())
 217            ->setContinueOnNoEffect(true)
 218            ->setContentSourceFromRequest($request)
 219            ->setActor($viewer)
 220            ->applyTransactions($repository, $xactions);
 221  
 222          $repo_uri = $this->getRepositoryControllerURI($repository, 'edit/');
 223          return id(new AphrontRedirectResponse())->setURI($repo_uri);
 224        }
 225      } else {
 226        $dict = array();
 227        if ($repository) {
 228          $dict = array(
 229            'remoteURI' => $repository->getRemoteURI(),
 230            'credential' => $repository->getCredentialPHID(),
 231            'viewPolicy' => $repository->getViewPolicy(),
 232            'editPolicy' => $repository->getEditPolicy(),
 233            'pushPolicy' => $repository->getPushPolicy(),
 234          );
 235        }
 236        $form->readFromObject($dict);
 237      }
 238  
 239      $crumbs = $this->buildApplicationCrumbs();
 240      $crumbs->addTextCrumb($title);
 241  
 242      return $this->buildApplicationPage(
 243        array(
 244          $crumbs,
 245          $form,
 246        ),
 247        array(
 248          'title' => $title,
 249        ));
 250    }
 251  
 252  
 253  /* -(  Page: VCS Type  )----------------------------------------------------- */
 254  
 255  
 256    private function buildVCSPage() {
 257  
 258      $is_import = ($this->edit == 'import');
 259  
 260      if ($is_import) {
 261        $git_str = pht(
 262          'Import a Git repository (for example, a repository hosted '.
 263          'on GitHub).');
 264        $hg_str = pht(
 265          'Import a Mercurial repository (for example, a repository '.
 266          'hosted on Bitbucket).');
 267        $svn_str = pht('Import a Subversion repository.');
 268      } else {
 269        $git_str = pht('Create a new, empty Git repository.');
 270        $hg_str = pht('Create a new, empty Mercurial repository.');
 271        $svn_str = pht('Create a new, empty Subversion repository.');
 272      }
 273  
 274      $control = id(new AphrontFormRadioButtonControl())
 275        ->setName('vcs')
 276        ->setLabel(pht('Type'))
 277        ->addButton(
 278          PhabricatorRepositoryType::REPOSITORY_TYPE_GIT,
 279          pht('Git'),
 280          $git_str)
 281        ->addButton(
 282          PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL,
 283          pht('Mercurial'),
 284          $hg_str)
 285        ->addButton(
 286          PhabricatorRepositoryType::REPOSITORY_TYPE_SVN,
 287          pht('Subversion'),
 288          $svn_str);
 289  
 290      if ($is_import) {
 291        $control->addButton(
 292          PhabricatorRepositoryType::REPOSITORY_TYPE_PERFORCE,
 293          pht('Perforce'),
 294          pht(
 295            'Perforce is not directly supported, but you can import '.
 296            'a Perforce repository as a Git repository using %s.',
 297            phutil_tag(
 298              'a',
 299              array(
 300                'href' =>
 301                  'http://www.perforce.com/product/components/git-fusion',
 302                'target' => '_blank',
 303              ),
 304              pht('Perforce Git Fusion'))),
 305          'disabled',
 306          $disabled = true);
 307      }
 308  
 309      return id(new PHUIFormPageView())
 310        ->setPageName(pht('Repository Type'))
 311        ->setUser($this->getRequest()->getUser())
 312        ->setValidateFormPageCallback(array($this, 'validateVCSPage'))
 313        ->addControl($control);
 314    }
 315  
 316    public function validateVCSPage(PHUIFormPageView $page) {
 317      $valid = array(
 318        PhabricatorRepositoryType::REPOSITORY_TYPE_GIT => true,
 319        PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL => true,
 320        PhabricatorRepositoryType::REPOSITORY_TYPE_SVN => true,
 321      );
 322  
 323      $c_vcs = $page->getControl('vcs');
 324      $v_vcs = $c_vcs->getValue();
 325      if (!$v_vcs) {
 326        $c_vcs->setError(pht('Required'));
 327        $page->addPageError(
 328          pht('You must select a version control system.'));
 329      } else if (empty($valid[$v_vcs])) {
 330        $c_vcs->setError(pht('Invalid'));
 331        $page->addPageError(
 332          pht('You must select a valid version control system.'));
 333      }
 334  
 335      return $c_vcs->isValid();
 336    }
 337  
 338  
 339  /* -(  Page: Name and Callsign  )-------------------------------------------- */
 340  
 341  
 342    private function buildNamePage() {
 343      return id(new PHUIFormPageView())
 344        ->setUser($this->getRequest()->getUser())
 345        ->setPageName(pht('Repository Name and Location'))
 346        ->setValidateFormPageCallback(array($this, 'validateNamePage'))
 347        ->addRemarkupInstructions(
 348          pht(
 349            '**Choose a human-readable name for this repository**, like '.
 350            '"CompanyName Mobile App" or "CompanyName Backend Server". You '.
 351            'can change this later.'))
 352        ->addControl(
 353          id(new AphrontFormTextControl())
 354            ->setName('name')
 355            ->setLabel(pht('Name'))
 356            ->setCaption(pht('Human-readable repository name.')))
 357        ->addRemarkupInstructions(
 358          pht(
 359            '**Choose a "Callsign" for the repository.** This is a short, '.
 360            'unique string which identifies commits elsewhere in Phabricator. '.
 361            'For example, you might use `M` for your mobile app repository '.
 362            'and `B` for your backend repository.'.
 363            "\n\n".
 364            '**Callsigns must be UPPERCASE**, and can not be edited after the '.
 365            'repository is created. Generally, you should choose short '.
 366            'callsigns.'))
 367        ->addControl(
 368          id(new AphrontFormTextControl())
 369            ->setName('callsign')
 370            ->setLabel(pht('Callsign'))
 371            ->setCaption(pht('Short UPPERCASE identifier.')));
 372    }
 373  
 374    public function validateNamePage(PHUIFormPageView $page) {
 375      $c_name = $page->getControl('name');
 376      $v_name = $c_name->getValue();
 377      if (!strlen($v_name)) {
 378        $c_name->setError(pht('Required'));
 379        $page->addPageError(
 380          pht('You must choose a name for this repository.'));
 381      }
 382  
 383      $c_call = $page->getControl('callsign');
 384      $v_call = $c_call->getValue();
 385      if (!strlen($v_call)) {
 386        $c_call->setError(pht('Required'));
 387        $page->addPageError(
 388          pht('You must choose a callsign for this repository.'));
 389      } else if (!preg_match('/^[A-Z]+\z/', $v_call)) {
 390        $c_call->setError(pht('Invalid'));
 391        $page->addPageError(
 392          pht('The callsign must contain only UPPERCASE letters.'));
 393      } else {
 394        $exists = false;
 395        try {
 396          $repo = id(new PhabricatorRepositoryQuery())
 397            ->setViewer($this->getRequest()->getUser())
 398            ->withCallsigns(array($v_call))
 399            ->executeOne();
 400          $exists = (bool)$repo;
 401        } catch (PhabricatorPolicyException $ex) {
 402          $exists = true;
 403        }
 404        if ($exists) {
 405          $c_call->setError(pht('Not Unique'));
 406          $page->addPageError(
 407            pht(
 408              'Another repository already uses that callsign. You must choose '.
 409              'a unique callsign.'));
 410        }
 411      }
 412  
 413      return $c_name->isValid() &&
 414             $c_call->isValid();
 415    }
 416  
 417  
 418  /* -(  Page: Remote URI  )--------------------------------------------------- */
 419  
 420  
 421    private function buildRemoteURIPage() {
 422      return id(new PHUIFormPageView())
 423        ->setUser($this->getRequest()->getUser())
 424        ->setPageName(pht('Repository Remote URI'))
 425        ->setValidateFormPageCallback(array($this, 'validateRemoteURIPage'))
 426        ->setAdjustFormPageCallback(array($this, 'adjustRemoteURIPage'))
 427        ->addControl(
 428          id(new AphrontFormTextControl())
 429            ->setName('remoteURI'));
 430    }
 431  
 432    public function adjustRemoteURIPage(PHUIFormPageView $page) {
 433      $form = $page->getForm();
 434  
 435      $is_git = false;
 436      $is_svn = false;
 437      $is_mercurial = false;
 438  
 439      if ($this->getRepository()) {
 440        $vcs = $this->getRepository()->getVersionControlSystem();
 441      } else {
 442        $vcs = $form->getPage('vcs')->getControl('vcs')->getValue();
 443      }
 444  
 445      switch ($vcs) {
 446        case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
 447          $is_git = true;
 448          break;
 449        case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
 450          $is_svn = true;
 451          break;
 452        case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
 453          $is_mercurial = true;
 454          break;
 455        default:
 456          throw new Exception('Unsupported VCS!');
 457      }
 458  
 459      $has_local = ($is_git || $is_mercurial);
 460      if ($is_git) {
 461        $uri_label = pht('Remote URI');
 462        $instructions = pht(
 463          'Enter the URI to clone this Git repository from. It should usually '.
 464          'look like one of these examples:'.
 465          "\n\n".
 466          "| Example Git Remote URIs |\n".
 467          "| ----------------------- |\n".
 468          "| `[email protected]:example/example.git` |\n".
 469          "| `ssh://[email protected]/git/example.git` |\n".
 470          "| `https://example.com/repository.git` |\n");
 471      } else if ($is_mercurial) {
 472        $uri_label = pht('Remote URI');
 473        $instructions = pht(
 474          'Enter the URI to clone this Mercurial repository from. It should '.
 475          'usually look like one of these examples:'.
 476          "\n\n".
 477          "| Example Mercurial Remote URIs |\n".
 478          "| ----------------------- |\n".
 479          "| `ssh://[email protected]/example/repository` |\n".
 480          "| `https://bitbucket.org/example/repository` |\n");
 481      } else if ($is_svn) {
 482        $uri_label = pht('Repository Root');
 483        $instructions = pht(
 484          'Enter the **Repository Root** for this Subversion repository. '.
 485          'You can figure this out by running `svn info` in a working copy '.
 486          'and looking at the value in the `Repository Root` field. It '.
 487          'should be a URI and will usually look like these:'.
 488          "\n\n".
 489          "| Example Subversion Repository Root URIs |\n".
 490          "| ------------------------------ |\n".
 491          "| `http://svn.example.org/svnroot/` |\n".
 492          "| `svn+ssh://svn.example.com/svnroot/` |\n".
 493          "| `svn://svn.example.net/svnroot/` |\n".
 494          "\n\n".
 495          "You **MUST** specify the root of the repository, not a ".
 496          "subdirectory. (If you want to import only part of a Subversion ".
 497          "repository, use the //Import Only// option at the end of this ".
 498          "workflow.)");
 499      } else {
 500        throw new Exception('Unsupported VCS!');
 501      }
 502  
 503      $page->addRemarkupInstructions($instructions, 'remoteURI');
 504      $page->getControl('remoteURI')->setLabel($uri_label);
 505    }
 506  
 507    public function validateRemoteURIPage(PHUIFormPageView $page) {
 508      $c_remote = $page->getControl('remoteURI');
 509      $v_remote = $c_remote->getValue();
 510  
 511      if (!strlen($v_remote)) {
 512        $c_remote->setError(pht('Required'));
 513        $page->addPageError(
 514          pht('You must specify a URI.'));
 515      } else {
 516        try {
 517          PhabricatorRepository::assertValidRemoteURI($v_remote);
 518        } catch (Exception $ex) {
 519          $c_remote->setError(pht('Invalid'));
 520          $page->addPageError($ex->getMessage());
 521        }
 522      }
 523  
 524      return $c_remote->isValid();
 525    }
 526  
 527  
 528  /* -(  Page: Authentication  )----------------------------------------------- */
 529  
 530  
 531    public function buildAuthPage() {
 532      return id(new PHUIFormPageView())
 533        ->setPageName(pht('Authentication'))
 534        ->setUser($this->getRequest()->getUser())
 535        ->setAdjustFormPageCallback(array($this, 'adjustAuthPage'))
 536        ->addControl(
 537          id(new PassphraseCredentialControl())
 538            ->setName('credential'));
 539    }
 540  
 541  
 542    public function adjustAuthPage($page) {
 543      $form = $page->getForm();
 544  
 545      if ($this->getRepository()) {
 546        $vcs = $this->getRepository()->getVersionControlSystem();
 547      } else {
 548        $vcs = $form->getPage('vcs')->getControl('vcs')->getValue();
 549      }
 550  
 551      $remote_uri = $form->getPage('remote-uri')
 552        ->getControl('remoteURI')
 553        ->getValue();
 554  
 555      $proto = PhabricatorRepository::getRemoteURIProtocol($remote_uri);
 556      $remote_user = $this->getRemoteURIUser($remote_uri);
 557  
 558      $c_credential = $page->getControl('credential');
 559      $c_credential->setDefaultUsername($remote_user);
 560  
 561      if ($this->isSSHProtocol($proto)) {
 562        $c_credential->setLabel(pht('SSH Key'));
 563        $c_credential->setCredentialType(
 564          PassphraseCredentialTypeSSHPrivateKeyText::CREDENTIAL_TYPE);
 565        $provides_type = PassphraseCredentialTypeSSHPrivateKey::PROVIDES_TYPE;
 566  
 567        $page->addRemarkupInstructions(
 568          pht(
 569            'Choose or add the SSH credentials to use to connect to the the '.
 570            'repository hosted at:'.
 571            "\n\n".
 572            "  lang=text\n".
 573            "  %s",
 574            $remote_uri),
 575          'credential');
 576      } else if ($this->isUsernamePasswordProtocol($proto)) {
 577        $c_credential->setLabel(pht('Password'));
 578        $c_credential->setAllowNull(true);
 579        $c_credential->setCredentialType(
 580          PassphraseCredentialTypePassword::CREDENTIAL_TYPE);
 581        $provides_type = PassphraseCredentialTypePassword::PROVIDES_TYPE;
 582  
 583        $page->addRemarkupInstructions(
 584          pht(
 585            'Choose the username and password used to connect to the '.
 586            'repository hosted at:'.
 587            "\n\n".
 588            "  lang=text\n".
 589            "  %s".
 590            "\n\n".
 591            "If this repository does not require a username or password, ".
 592            "you can continue to the next step.",
 593            $remote_uri),
 594          'credential');
 595      } else {
 596        throw new Exception('Unknown URI protocol!');
 597      }
 598  
 599      if ($provides_type) {
 600        $viewer = $this->getRequest()->getUser();
 601  
 602        $options = id(new PassphraseCredentialQuery())
 603          ->setViewer($viewer)
 604          ->withIsDestroyed(false)
 605          ->withProvidesTypes(array($provides_type))
 606          ->execute();
 607  
 608        $c_credential->setOptions($options);
 609      }
 610  
 611    }
 612  
 613    public function validateAuthPage(PHUIFormPageView $page) {
 614      $form = $page->getForm();
 615      $remote_uri = $form->getPage('remote')->getControl('remoteURI')->getValue();
 616      $proto = $this->getRemoteURIProtocol($remote_uri);
 617  
 618      $c_credential = $page->getControl('credential');
 619      $v_credential = $c_credential->getValue();
 620  
 621      // NOTE: We're using the omnipotent user here because the viewer might be
 622      // editing a repository they're allowed to edit which uses a credential they
 623      // are not allowed to see. This is fine, as long as they don't change it.
 624      $credential = id(new PassphraseCredentialQuery())
 625        ->setViewer(PhabricatorUser::getOmnipotentUser())
 626        ->withPHIDs(array($v_credential))
 627        ->executeOne();
 628  
 629      if ($this->isSSHProtocol($proto)) {
 630        if (!$credential) {
 631          $c_credential->setError(pht('Required'));
 632          $page->addPageError(
 633            pht('You must choose an SSH credential to connect over SSH.'));
 634        }
 635  
 636        $ssh_type = PassphraseCredentialTypeSSHPrivateKey::PROVIDES_TYPE;
 637        if ($credential->getProvidesType() !== $ssh_type) {
 638          $c_credential->setError(pht('Invalid'));
 639          $page->addPageError(
 640            pht(
 641              'You must choose an SSH credential, not some other type '.
 642              'of credential.'));
 643        }
 644  
 645      } else if ($this->isUsernamePasswordProtocol($proto)) {
 646        if ($credential) {
 647          $password_type = PassphraseCredentialTypePassword::PROVIDES_TYPE;
 648          if ($credential->getProvidesType() !== $password_type) {
 649          $c_credential->setError(pht('Invalid'));
 650          $page->addPageError(
 651            pht(
 652              'You must choose a username/password credential, not some other '.
 653              'type of credential.'));
 654          }
 655        }
 656  
 657        return $c_credential->isValid();
 658      } else {
 659        return true;
 660      }
 661    }
 662  
 663  
 664  /* -(  Page: Policy  )------------------------------------------------------- */
 665  
 666  
 667    private function buildPolicyPage() {
 668      $viewer = $this->getRequest()->getUser();
 669      if ($this->getRepository()) {
 670        $repository = $this->getRepository();
 671      } else {
 672        $repository = PhabricatorRepository::initializeNewRepository($viewer);
 673      }
 674  
 675      $policies = id(new PhabricatorPolicyQuery())
 676        ->setViewer($viewer)
 677        ->setObject($repository)
 678        ->execute();
 679  
 680      $view_policy = id(new AphrontFormPolicyControl())
 681        ->setUser($viewer)
 682        ->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
 683        ->setPolicyObject($repository)
 684        ->setPolicies($policies)
 685        ->setName('viewPolicy');
 686  
 687      $edit_policy = id(new AphrontFormPolicyControl())
 688        ->setUser($viewer)
 689        ->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
 690        ->setPolicyObject($repository)
 691        ->setPolicies($policies)
 692        ->setName('editPolicy');
 693  
 694      $push_policy = id(new AphrontFormPolicyControl())
 695        ->setUser($viewer)
 696        ->setCapability(DiffusionPushCapability::CAPABILITY)
 697        ->setPolicyObject($repository)
 698        ->setPolicies($policies)
 699        ->setName('pushPolicy');
 700  
 701      return id(new PHUIFormPageView())
 702          ->setPageName(pht('Policies'))
 703          ->setValidateFormPageCallback(array($this, 'validatePolicyPage'))
 704          ->setAdjustFormPageCallback(array($this, 'adjustPolicyPage'))
 705          ->setUser($viewer)
 706          ->addRemarkupInstructions(
 707            pht(
 708              'Select access policies for this repository.'))
 709          ->addControl($view_policy)
 710          ->addControl($edit_policy)
 711          ->addControl($push_policy);
 712    }
 713  
 714    public function adjustPolicyPage(PHUIFormPageView $page) {
 715      if ($this->getRepository()) {
 716        $repository = $this->getRepository();
 717        $show_push = $repository->isHosted();
 718      } else {
 719        $show_push = ($this->edit == 'create');
 720      }
 721  
 722      if (!$show_push) {
 723        $c_push = $page->getControl('pushPolicy');
 724        $c_push->setHidden(true);
 725      }
 726    }
 727  
 728    public function validatePolicyPage(PHUIFormPageView $page) {
 729      $form = $page->getForm();
 730      $viewer = $this->getRequest()->getUser();
 731  
 732      $c_view = $page->getControl('viewPolicy');
 733      $c_edit = $page->getControl('editPolicy');
 734      $c_push = $page->getControl('pushPolicy');
 735      $v_view = $c_view->getValue();
 736      $v_edit = $c_edit->getValue();
 737      $v_push = $c_push->getValue();
 738  
 739      if ($this->getRepository()) {
 740        $repository = $this->getRepository();
 741      } else {
 742        $repository = PhabricatorRepository::initializeNewRepository($viewer);
 743      }
 744  
 745      $proxy = clone $repository;
 746      $proxy->setViewPolicy($v_view);
 747      $proxy->setEditPolicy($v_edit);
 748  
 749      $can_view = PhabricatorPolicyFilter::hasCapability(
 750        $viewer,
 751        $proxy,
 752        PhabricatorPolicyCapability::CAN_VIEW);
 753  
 754      $can_edit = PhabricatorPolicyFilter::hasCapability(
 755        $viewer,
 756        $proxy,
 757        PhabricatorPolicyCapability::CAN_EDIT);
 758  
 759      if (!$can_view) {
 760        $c_view->setError(pht('Invalid'));
 761        $page->addPageError(
 762          pht(
 763            'You can not use the selected policy, because you would be unable '.
 764            'to see the repository.'));
 765      }
 766  
 767      if (!$can_edit) {
 768        $c_edit->setError(pht('Invalid'));
 769        $page->addPageError(
 770          pht(
 771            'You can not use the selected edit policy, because you would be '.
 772            'unable to edit the repository.'));
 773      }
 774  
 775      return $c_view->isValid() &&
 776             $c_edit->isValid();
 777    }
 778  
 779  /* -(  Page: Done  )--------------------------------------------------------- */
 780  
 781  
 782    private function buildDonePage() {
 783  
 784      $is_create = ($this->edit == 'create');
 785      if ($is_create) {
 786        $now_label = pht('Create Repository Now');
 787        $now_caption = pht(
 788          'Create the repository right away. This will create the repository '.
 789          'using default settings.');
 790  
 791        $wait_label = pht('Configure More Options First');
 792        $wait_caption = pht(
 793          'Configure more options before creating the repository. '.
 794          'This will let you fine-tune settings. You can create the repository '.
 795          'whenever you are ready.');
 796      } else {
 797        $now_label = pht('Start Import Now');
 798        $now_caption = pht(
 799          'Start importing the repository right away. This will import '.
 800          'the entire repository using default settings.');
 801  
 802        $wait_label = pht('Configure More Options First');
 803        $wait_caption = pht(
 804          'Configure more options before beginning the repository '.
 805          'import. This will let you fine-tune settings. You can '.
 806          'start the import whenever you are ready.');
 807      }
 808  
 809      return id(new PHUIFormPageView())
 810        ->setPageName(pht('Repository Ready!'))
 811        ->setValidateFormPageCallback(array($this, 'validateDonePage'))
 812        ->setUser($this->getRequest()->getUser())
 813        ->addControl(
 814          id(new AphrontFormRadioButtonControl())
 815            ->setName('activate')
 816            ->setLabel(pht('Start Now'))
 817            ->addButton(
 818              'start',
 819              $now_label,
 820              $now_caption)
 821            ->addButton(
 822              'wait',
 823              $wait_label,
 824              $wait_caption));
 825    }
 826  
 827    public function validateDonePage(PHUIFormPageView $page) {
 828      $c_activate = $page->getControl('activate');
 829      $v_activate = $c_activate->getValue();
 830  
 831      if ($v_activate != 'start' && $v_activate != 'wait') {
 832        $c_activate->setError(pht('Required'));
 833        $page->addPageError(
 834          pht('Make a choice about repository activation.'));
 835      }
 836  
 837      return $c_activate->isValid();
 838    }
 839  
 840  
 841  /* -(  Internal  )----------------------------------------------------------- */
 842  
 843    private function getRemoteURIUser($raw_uri) {
 844      $uri = new PhutilURI($raw_uri);
 845      if ($uri->getUser()) {
 846        return $uri->getUser();
 847      }
 848  
 849      $git_uri = new PhutilGitURI($raw_uri);
 850      if (strlen($git_uri->getDomain()) && strlen($git_uri->getPath())) {
 851        return $git_uri->getUser();
 852      }
 853  
 854      return null;
 855    }
 856  
 857    private function isSSHProtocol($proto) {
 858      return ($proto == 'git' || $proto == 'ssh' || $proto == 'svn+ssh');
 859    }
 860  
 861    private function isUsernamePasswordProtocol($proto) {
 862      return ($proto == 'http' || $proto == 'https' || $proto == 'svn');
 863    }
 864  
 865    private function setRepository(PhabricatorRepository $repository) {
 866      $this->repository = $repository;
 867      return $this;
 868    }
 869  
 870    private function getRepository() {
 871      return $this->repository;
 872    }
 873  
 874  }


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