[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/diffusion/ssh/ -> DiffusionSSHWorkflow.php (source)

   1  <?php
   2  
   3  abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow {
   4  
   5    private $args;
   6    private $repository;
   7    private $hasWriteAccess;
   8  
   9    public function getRepository() {
  10      if (!$this->repository) {
  11        throw new Exception('Call loadRepository() before getRepository()!');
  12      }
  13      return $this->repository;
  14    }
  15  
  16    public function getArgs() {
  17      return $this->args;
  18    }
  19  
  20    public function getEnvironment() {
  21      $env = array(
  22        DiffusionCommitHookEngine::ENV_USER => $this->getUser()->getUsername(),
  23        DiffusionCommitHookEngine::ENV_REMOTE_PROTOCOL => 'ssh',
  24      );
  25  
  26      $ssh_client = getenv('SSH_CLIENT');
  27      if ($ssh_client) {
  28        // This has the format "<ip> <remote-port> <local-port>". Grab the IP.
  29        $remote_address = head(explode(' ', $ssh_client));
  30        $env[DiffusionCommitHookEngine::ENV_REMOTE_ADDRESS] = $remote_address;
  31      }
  32  
  33      return $env;
  34    }
  35  
  36    abstract protected function executeRepositoryOperations();
  37  
  38    protected function writeError($message) {
  39      $this->getErrorChannel()->write($message);
  40      return $this;
  41    }
  42  
  43    final public function execute(PhutilArgumentParser $args) {
  44      $this->args = $args;
  45  
  46      try {
  47        return $this->executeRepositoryOperations();
  48      } catch (Exception $ex) {
  49        $this->writeError(get_class($ex).': '.$ex->getMessage());
  50        return 1;
  51      }
  52    }
  53  
  54    protected function loadRepository($path) {
  55      $viewer = $this->getUser();
  56  
  57      $regex = '@^/?diffusion/(?P<callsign>[A-Z]+)(?:/|\z)@';
  58      $matches = null;
  59      if (!preg_match($regex, $path, $matches)) {
  60        throw new Exception(
  61          pht(
  62            'Unrecognized repository path "%s". Expected a path like '.
  63            '"%s".',
  64            $path,
  65            '/diffusion/X/'));
  66      }
  67  
  68      $callsign = $matches[1];
  69      $repository = id(new PhabricatorRepositoryQuery())
  70        ->setViewer($viewer)
  71        ->withCallsigns(array($callsign))
  72        ->executeOne();
  73  
  74      if (!$repository) {
  75        throw new Exception(
  76          pht('No repository "%s" exists!', $callsign));
  77      }
  78  
  79      switch ($repository->getServeOverSSH()) {
  80        case PhabricatorRepository::SERVE_READONLY:
  81        case PhabricatorRepository::SERVE_READWRITE:
  82          // If we have read or read/write access, proceed for now. We will
  83          // check write access when the user actually issues a write command.
  84          break;
  85        case PhabricatorRepository::SERVE_OFF:
  86        default:
  87          throw new Exception(
  88            pht('This repository is not available over SSH.'));
  89      }
  90  
  91      $this->repository = $repository;
  92  
  93      return $repository;
  94    }
  95  
  96    protected function requireWriteAccess($protocol_command = null) {
  97      if ($this->hasWriteAccess === true) {
  98        return;
  99      }
 100  
 101      $repository = $this->getRepository();
 102      $viewer = $this->getUser();
 103  
 104      switch ($repository->getServeOverSSH()) {
 105        case PhabricatorRepository::SERVE_READONLY:
 106          if ($protocol_command !== null) {
 107            throw new Exception(
 108              pht(
 109                'This repository is read-only over SSH (tried to execute '.
 110                'protocol command "%s").',
 111                $protocol_command));
 112          } else {
 113            throw new Exception(
 114              pht('This repository is read-only over SSH.'));
 115          }
 116          break;
 117        case PhabricatorRepository::SERVE_READWRITE:
 118          $can_push = PhabricatorPolicyFilter::hasCapability(
 119            $viewer,
 120            $repository,
 121            DiffusionPushCapability::CAPABILITY);
 122          if (!$can_push) {
 123            throw new Exception(
 124              pht('You do not have permission to push to this repository.'));
 125          }
 126          break;
 127        case PhabricatorRepository::SERVE_OFF:
 128        default:
 129          // This shouldn't be reachable because we don't get this far if the
 130          // repository isn't enabled, but kick them out anyway.
 131          throw new Exception(
 132            pht('This repository is not available over SSH.'));
 133      }
 134  
 135      $this->hasWriteAccess = true;
 136      return $this->hasWriteAccess;
 137    }
 138  
 139  }


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