[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |