@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix failure to record `pullerPHID` in repository pull logs

Summary:
See PHI305. Ref T13046.

The SSH workflows currently extend `PhabricatorManagementWorkflow` to benefit from sharing all the standard argument parsing code. Sharing the parsing code is good, but it also means they inherit a `getViewer()` method which returns the ommnipotent viewer.

This is appropriate for everything else which extends `ManagementWorkflow` (like `bin/storage`, `bin/auth`, etc.) but not appropriate for SSH workflows, which have a real user.

This caused a bug with the pull logs where `pullerPHID` was not recorded properly. We used `$this->getViewer()->getPHID()` but the correct code was `$this->getUser()->getPHID()`.

To harden this against future mistakes:

- Don't extend `ManagementWorkflow`. Extend `PhutilArgumentWorkflow` instead. We **only** want the argument parsing code.
- Rename `get/setUser()` to `get/setSSHUser()` to make them explicit.

Then, fix the pull log bug by calling `getSSHUser()` instead of `getViewer()`.

Test Plan:
- Pulled and pushed to a repository over SSH.
- Grepped all the SSH stuff for the altered symbols.
- Saw pulls record a valid `pullerPHID` in the pull log.
- Used `echo {} | ssh ... conduit conduit.ping` to test conduit over SSH.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13046

Differential Revision: https://secure.phabricator.com/D18912

+26 -20
+1 -1
scripts/ssh/ssh-exec.php
··· 245 245 } 246 246 247 247 $workflow = $parsed_args->parseWorkflows($workflows); 248 - $workflow->setUser($user); 248 + $workflow->setSSHUser($user); 249 249 $workflow->setOriginalArguments($original_argv); 250 250 $workflow->setIsClusterRequest($is_cluster_request); 251 251
+1 -1
src/__phutil_library_map__.php
··· 9620 9620 'PhabricatorSSHKeysSettingsPanel' => 'PhabricatorSettingsPanel', 9621 9621 'PhabricatorSSHLog' => 'Phobject', 9622 9622 'PhabricatorSSHPassthruCommand' => 'Phobject', 9623 - 'PhabricatorSSHWorkflow' => 'PhabricatorManagementWorkflow', 9623 + 'PhabricatorSSHWorkflow' => 'PhutilArgumentWorkflow', 9624 9624 'PhabricatorSavedQuery' => array( 9625 9625 'PhabricatorSearchDAO', 9626 9626 'PhabricatorPolicyInterface',
+2 -2
src/applications/conduit/ssh/ConduitSSHWorkflow.php
··· 46 46 47 47 try { 48 48 $call = new ConduitCall($method, $params); 49 - $call->setUser($this->getUser()); 49 + $call->setUser($this->getSSHUser()); 50 50 51 51 $result = $call->execute(); 52 52 } catch (ConduitException $ex) { ··· 77 77 78 78 $connection_id = idx($metadata, 'connectionID'); 79 79 $log = id(new PhabricatorConduitMethodCallLog()) 80 - ->setCallerPHID($this->getUser()->getPHID()) 80 + ->setCallerPHID($this->getSSHUser()->getPHID()) 81 81 ->setConnectionID($connection_id) 82 82 ->setMethod($method) 83 83 ->setError((string)$error_code)
+1 -1
src/applications/diffusion/ssh/DiffusionGitReceivePackSSHWorkflow.php
··· 15 15 16 16 protected function executeRepositoryOperations() { 17 17 $repository = $this->getRepository(); 18 - $viewer = $this->getUser(); 18 + $viewer = $this->getSSHUser(); 19 19 $device = AlmanacKeys::getLiveDevice(); 20 20 21 21 // This is a write, and must have write access.
+1 -1
src/applications/diffusion/ssh/DiffusionGitUploadPackSSHWorkflow.php
··· 15 15 16 16 protected function executeRepositoryOperations() { 17 17 $repository = $this->getRepository(); 18 - $viewer = $this->getUser(); 18 + $viewer = $this->getSSHUser(); 19 19 $device = AlmanacKeys::getLiveDevice(); 20 20 21 21 $skip_sync = $this->shouldSkipReadSynchronization();
+7 -7
src/applications/diffusion/ssh/DiffusionSSHWorkflow.php
··· 26 26 27 27 public function getEnvironment() { 28 28 $env = array( 29 - DiffusionCommitHookEngine::ENV_USER => $this->getUser()->getUsername(), 29 + DiffusionCommitHookEngine::ENV_USER => $this->getSSHUser()->getUsername(), 30 30 DiffusionCommitHookEngine::ENV_REMOTE_PROTOCOL => 'ssh', 31 31 ); 32 32 ··· 122 122 $key_path, 123 123 $port, 124 124 $host, 125 - '@'.$this->getUser()->getUsername(), 125 + '@'.$this->getSSHUser()->getUsername(), 126 126 $this->getOriginalArguments()); 127 127 } 128 128 129 129 final public function execute(PhutilArgumentParser $args) { 130 130 $this->args = $args; 131 131 132 - $viewer = $this->getUser(); 132 + $viewer = $this->getSSHUser(); 133 133 $have_diffusion = PhabricatorApplication::isClassInstalledForViewer( 134 134 'PhabricatorDiffusionApplication', 135 135 $viewer); ··· 164 164 } 165 165 166 166 protected function loadRepositoryWithPath($path, $vcs) { 167 - $viewer = $this->getUser(); 167 + $viewer = $this->getSSHUser(); 168 168 169 169 $info = PhabricatorRepository::parseRepositoryServicePath($path, $vcs); 170 170 if ($info === null) { ··· 214 214 } 215 215 216 216 $repository = $this->getRepository(); 217 - $viewer = $this->getUser(); 217 + $viewer = $this->getSSHUser(); 218 218 219 219 if ($viewer->isOmnipotent()) { 220 220 throw new Exception( ··· 252 252 } 253 253 254 254 protected function shouldSkipReadSynchronization() { 255 - $viewer = $this->getUser(); 255 + $viewer = $this->getSSHUser(); 256 256 257 257 // Currently, the only case where devices interact over SSH without 258 258 // assuming user credentials is when synchronizing before a read. These ··· 265 265 } 266 266 267 267 protected function newPullEvent() { 268 - $viewer = $this->getViewer(); 268 + $viewer = $this->getSSHUser(); 269 269 $repository = $this->getRepository(); 270 270 $remote_address = $this->getSSHRemoteAddress(); 271 271
+1 -1
src/applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php
··· 154 154 } else { 155 155 $command = csprintf( 156 156 'svnserve -t --tunnel-user=%s', 157 - $this->getUser()->getUsername()); 157 + $this->getSSHUser()->getUsername()); 158 158 $cwd = PhabricatorEnv::getEmptyCWD(); 159 159 } 160 160
+12 -6
src/infrastructure/ssh/PhabricatorSSHWorkflow.php
··· 1 1 <?php 2 2 3 - abstract class PhabricatorSSHWorkflow extends PhabricatorManagementWorkflow { 3 + abstract class PhabricatorSSHWorkflow 4 + extends PhutilArgumentWorkflow { 4 5 5 - private $user; 6 + // NOTE: We are explicitly extending "PhutilArgumentWorkflow", not 7 + // "PhabricatorManagementWorkflow". We want to avoid inheriting "getViewer()" 8 + // and other methods which assume workflows are administrative commands 9 + // like `bin/storage`. 10 + 11 + private $sshUser; 6 12 private $iochannel; 7 13 private $errorChannel; 8 14 private $isClusterRequest; ··· 21 27 return $this->errorChannel; 22 28 } 23 29 24 - public function setUser(PhabricatorUser $user) { 25 - $this->user = $user; 30 + public function setSSHUser(PhabricatorUser $ssh_user) { 31 + $this->sshUser = $ssh_user; 26 32 return $this; 27 33 } 28 34 29 - public function getUser() { 30 - return $this->user; 35 + public function getSSHUser() { 36 + return $this->sshUser; 31 37 } 32 38 33 39 public function setIOChannel(PhutilChannel $channel) {