@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<?php
2
3final class DiffusionGitLFSAuthenticateWorkflow
4 extends DiffusionGitSSHWorkflow {
5
6 protected function didConstruct() {
7 $this->setName('git-lfs-authenticate');
8 $this->setArguments(
9 array(
10 array(
11 'name' => 'argv',
12 'wildcard' => true,
13 ),
14 ));
15 }
16
17 protected function identifyRepository() {
18 return $this->loadRepositoryWithPath(
19 $this->getLFSPathArgument(),
20 PhabricatorRepositoryType::REPOSITORY_TYPE_GIT);
21 }
22
23 private function getLFSPathArgument() {
24 return $this->getLFSArgument(0);
25 }
26
27 private function getLFSOperationArgument() {
28 return $this->getLFSArgument(1);
29 }
30
31 private function getLFSArgument($position) {
32 $args = $this->getArgs();
33 $argv = $args->getArg('argv');
34
35 if (!isset($argv[$position])) {
36 throw new Exception(
37 pht(
38 'Expected `git-lfs-authenticate <path> <operation>`, but received '.
39 'too few arguments.'));
40 }
41
42 return $argv[$position];
43 }
44
45 protected function executeRepositoryOperations() {
46 $operation = $this->getLFSOperationArgument();
47
48 // NOTE: We aren't checking write access here, even for "upload". The
49 // HTTP endpoint should be able to do that for us.
50
51 switch ($operation) {
52 case 'upload':
53 case 'download':
54 break;
55 default:
56 throw new Exception(
57 pht(
58 'Git LFS operation "%s" is not supported by this server.',
59 $operation));
60 }
61
62 $repository = $this->getRepository();
63
64 if (!$repository->isGit()) {
65 throw new Exception(
66 pht(
67 'Repository "%s" is not a Git repository. Git LFS is only '.
68 'supported for Git repositories.',
69 $repository->getDisplayName()));
70 }
71
72 if (!$repository->canUseGitLFS()) {
73 throw new Exception(
74 pht('Git LFS is not enabled for this repository.'));
75 }
76
77 // NOTE: This is usually the same as the default URI (which does not
78 // need to be specified in the response), but the protocol or domain may
79 // differ in some situations.
80
81 $lfs_uri = $repository->getGitLFSURI('info/lfs');
82
83 // Generate a temporary token to allow the user to access LFS over HTTP.
84 // This works even if normal HTTP repository operations are not available
85 // on this host, and does not require the user to have a VCS password.
86
87 $user = $this->getSSHUser();
88
89 $authorization = DiffusionGitLFSTemporaryTokenType::newHTTPAuthorization(
90 $repository,
91 $user,
92 $operation);
93
94 $headers = array(
95 'authorization' => $authorization['header'],
96 );
97
98 $result = array(
99 'header' => $headers,
100 'href' => $lfs_uri,
101 'expires_in' => $authorization['ttl'],
102 );
103 $result = phutil_json_encode($result);
104
105 $this->writeIO($result);
106 $this->waitForGitClient();
107
108 return 0;
109 }
110
111}