1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-14 10:52:41 +01:00
phorge-phorge/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php
epriestley 9a2e45ef12 Serve Git reads over SSH
Summary: Like D7423, but for SSH.

Test Plan: Ran `git clone ssh://...`, got a clone.

Reviewers: btrahan

Reviewed By: btrahan

CC: hach-que, aran

Maniphest Tasks: T2230

Differential Revision: https://secure.phabricator.com/D7424
2013-10-29 15:32:40 -07:00

89 lines
2.3 KiB
PHP

<?php
abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow {
private $args;
public function getArgs() {
return $this->args;
}
abstract protected function isReadOnly();
abstract protected function getRequestPath();
abstract protected function executeRepositoryOperations(
PhabricatorRepository $repository);
protected function writeError($message) {
$this->getErrorChannel()->write($message);
return $this;
}
final public function execute(PhutilArgumentParser $args) {
$this->args = $args;
try {
$repository = $this->loadRepository();
return $this->executeRepositoryOperations($repository);
} catch (Exception $ex) {
$this->writeError(get_class($ex).': '.$ex->getMessage());
return 1;
}
}
private function loadRepository() {
$viewer = $this->getUser();
$path = $this->getRequestPath();
$regex = '@^/?diffusion/(?P<callsign>[A-Z]+)(?:/|$)@';
$matches = null;
if (!preg_match($regex, $path, $matches)) {
throw new Exception(
pht(
'Unrecognized repository path "%s". Expected a path like '.
'"%s".',
$path,
"/diffusion/X/"));
}
$callsign = $matches[1];
$repository = id(new PhabricatorRepositoryQuery())
->setViewer($viewer)
->withCallsigns(array($callsign))
->executeOne();
if (!$repository) {
throw new Exception(
pht('No repository "%s" exists!', $callsign));
}
$is_push = !$this->isReadOnly();
switch ($repository->getServeOverSSH()) {
case PhabricatorRepository::SERVE_READONLY:
if ($is_push) {
throw new Exception(
pht('This repository is read-only over SSH.'));
}
break;
case PhabricatorRepository::SERVE_READWRITE:
if ($is_push) {
$can_push = PhabricatorPolicyFilter::hasCapability(
$viewer,
$repository,
DiffusionCapabilityPush::CAPABILITY);
if (!$can_push) {
throw new Exception(
pht('You do not have permission to push to this repository.'));
}
}
break;
case PhabricatorRepository::SERVE_OFF:
default:
throw new Exception(
pht('This repository is not available over SSH.'));
}
return $repository;
}
}