This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Hubph; |
||
4 | |||
5 | use Consolidation\Config\ConfigInterface; |
||
6 | use Hubph\Internal\EventLogger; |
||
7 | |||
8 | class HubphAPI |
||
9 | { |
||
10 | protected $config; |
||
11 | protected $token; |
||
12 | protected $gitHubAPI; |
||
13 | protected $eventLogger; |
||
14 | protected $as = 'default'; |
||
15 | |||
16 | /** |
||
17 | * HubphAPI constructor |
||
18 | */ |
||
19 | public function __construct(ConfigInterface $config) |
||
20 | { |
||
21 | $this->config = $config; |
||
22 | } |
||
23 | |||
24 | public function startLogging($filename) |
||
25 | { |
||
26 | $this->stopLogging(); |
||
27 | $this->eventLogger = new EventLogger($filename); |
||
28 | $this->eventLogger->start(); |
||
29 | } |
||
30 | |||
31 | public function stopLogging() |
||
32 | { |
||
33 | if ($this->eventLogger) { |
||
34 | $this->eventLogger->stop(); |
||
35 | } |
||
36 | $this->eventLogger = null; |
||
37 | } |
||
38 | |||
39 | public function setAs($as) |
||
40 | { |
||
41 | if ($as != $this->as) { |
||
42 | $this->as = $as; |
||
43 | $this->token = false; |
||
44 | $this->gitHubAPI = false; |
||
45 | } |
||
46 | } |
||
47 | |||
48 | public function whoami() |
||
49 | { |
||
50 | $gitHubAPI = $this->gitHubAPI(); |
||
51 | $authenticated = $gitHubAPI->api('current_user')->show(); |
||
52 | return $authenticated; |
||
53 | } |
||
54 | |||
55 | public function repoCreate($org, $project) |
||
56 | { |
||
57 | return $this->api->gitHubAPI()->api('repo')->create( |
||
58 | $project, |
||
59 | '', |
||
60 | '', |
||
61 | true, |
||
62 | $org |
||
63 | ); |
||
64 | } |
||
65 | |||
66 | public function repoDelete($org, $project) |
||
67 | { |
||
68 | return $this->api->gitHubAPI()->api('repo')->remove($org, $project); |
||
69 | } |
||
70 | |||
71 | public function prCreate($org, $project, $title, $body, $base, $head) |
||
72 | { |
||
73 | $params = [ |
||
74 | 'title' => $title, |
||
75 | 'body' => $body, |
||
76 | 'base' => $base, |
||
77 | 'head' => $head, |
||
78 | ]; |
||
79 | $response = $this->gitHubAPI()->api('pull_request')->create($org, $project, $params); |
||
80 | $this->logEvent(__FUNCTION__, [$org, $project], $params, $response); |
||
81 | return $this; |
||
82 | } |
||
83 | |||
84 | public function prClose($org, $project, PullRequests $prs) |
||
85 | { |
||
86 | foreach ($prs->prNumbers() as $n) { |
||
87 | $gitHubAPI = $this->gitHubAPI(); |
||
88 | $gitHubAPI->api('pull_request')->update($org, $project, $n, ['state' => 'closed']); |
||
89 | } |
||
90 | } |
||
91 | |||
92 | public function prMerge($org, $project, PullRequests $prs, $message, $mergeMethod = 'squash', $title = null) |
||
93 | { |
||
94 | // First, check to see if all of the pull requests can be merged, |
||
95 | // and collect the sha hash of the head of the branch. |
||
96 | $allClean = true; |
||
97 | $shas = []; |
||
98 | foreach ($prs->prNumbers() as $n) { |
||
99 | $pullRequest = $this->gitHubAPI()->api('pull_request')->show($org, $project, $n); |
||
100 | $is_clean = $pullRequest['mergeable'] && $pullRequest['mergeable_state'] == 'clean'; |
||
101 | if (!$is_clean) { |
||
102 | return false; |
||
103 | } |
||
104 | $shas[$n] = $pullRequest['head']['sha']; |
||
105 | } |
||
106 | |||
107 | // Merge all of the pull requests |
||
108 | foreach ($shas as $n => $sha) { |
||
109 | $response = $this->gitHubAPI()->api('pull_request')->merge($org, $project, $n, $message, $sha, $mergeMethod, $title); |
||
110 | $this->logEvent(__FUNCTION__, [$org, $project], [$n, $message, $sha, $mergeMethod, $title], $response); |
||
111 | } |
||
112 | return true; |
||
113 | } |
||
114 | |||
115 | /** |
||
116 | * prCheck determines whether there are any open PRs that already exist |
||
117 | * that satisfy any of the provided $vids. |
||
118 | * |
||
119 | * @param string $projectWithOrg org/project to check |
||
120 | * @param VersionIdentifiers $vids |
||
121 | * @return [int $status, PullRequests $prs] status of PRs, and a list of PR numbers |
||
0 ignored issues
–
show
|
|||
122 | * - If $status is 0, then the caller should go ahead and create a new PR. |
||
123 | * The existing pull requests that would be superceded by the new PR are |
||
124 | * returned in the second parameter. These PRs could all be closed. |
||
125 | * - If $status is >0, then there is no need to create a new PR, as there |
||
126 | * are already existing PRs that are equivalent to the one that would |
||
127 | * be open. The equivalent PRs are returned in the second parameter. |
||
128 | */ |
||
129 | public function prCheck($projectWithOrg, VersionIdentifiers $vids) |
||
130 | { |
||
131 | // Find all of the PRs that contain any vid |
||
132 | $existingPRs = $this->existingPRs($projectWithOrg, $vids); |
||
133 | |||
134 | // Check to see if there are PRs matching all of the vids/vvals. |
||
135 | $titles = $existingPRs->titles(); |
||
136 | $status = $vids->allExist($titles); |
||
137 | |||
138 | return [$status, $existingPRs]; |
||
139 | } |
||
140 | |||
141 | public function prStatuses($projectWithOrg, $number) |
||
142 | { |
||
143 | list($org, $project) = explode('/', $projectWithOrg, 2); |
||
144 | $pullRequestStatus = $this->gitHubAPI()->api('pull_request')->status($org, $project, $number); |
||
145 | |||
146 | // Filter out the results based on 'target_url' |
||
147 | $filteredResults = []; |
||
148 | foreach (array_reverse($pullRequestStatus) as $id => $item) { |
||
149 | $filteredResults[$item['target_url']] = $item; |
||
150 | } |
||
151 | $pullRequestStatus = []; |
||
152 | foreach ($filteredResults as $target_url => $item) { |
||
153 | $pullRequestStatus[$item['id']] = $item; |
||
154 | } |
||
155 | |||
156 | // Put the most recently updated statuses at the top of the list |
||
157 | uasort( |
||
158 | |||
159 | $pullRequestStatus, |
||
160 | function ($lhs, $rhs) { |
||
161 | return abs(strtotime($lhs['updated_at']) - strtotime($rhs['updated_at'])); |
||
162 | } |
||
163 | ); |
||
164 | |||
165 | return $pullRequestStatus; |
||
166 | } |
||
167 | |||
168 | public function addTokenAuthentication($url) |
||
169 | { |
||
170 | $token = $this->gitHubToken(); |
||
171 | if (!$token) { |
||
172 | return $url; |
||
173 | } |
||
174 | if (!preg_match('#github\.com[/:]#', $url)) { |
||
175 | return $url; |
||
176 | } |
||
177 | $projectAndOrg = $this->projectAndOrgFromUrl($url); |
||
178 | return "https://{$token}:[email protected]/{$projectAndOrg}.git"; |
||
179 | } |
||
180 | |||
181 | View Code Duplication | protected function projectAndOrgFromUrl($remote) |
|
182 | { |
||
183 | $remote = preg_replace('#^git@[^:]*:#', '', $remote); |
||
184 | $remote = preg_replace('#^[^:]*://[^/]*/#', '', $remote); |
||
185 | $remote = preg_replace('#\.git$#', '', $remote); |
||
186 | |||
187 | return $remote; |
||
188 | } |
||
189 | |||
190 | protected function existingPRs($projectWithOrg, VersionIdentifiers $vids) |
||
191 | { |
||
192 | return $this->matchingPRs($projectWithOrg, $vids->getPreamble(), $vids->pattern()); |
||
193 | } |
||
194 | |||
195 | public function matchingPRs($projectWithOrg, $preamble, $pattern = '') |
||
196 | { |
||
197 | $q = "repo:$projectWithOrg in:title is:pr state:open $preamble"; |
||
198 | $result = new PullRequests(); |
||
199 | $gitHubAPI = $this->gitHubAPI(); |
||
200 | $searchResults = $gitHubAPI->api('search')->issues($q); |
||
201 | $result->addSearchResults($searchResults, $pattern); |
||
202 | |||
203 | return $result; |
||
204 | } |
||
205 | |||
206 | public function allPRs($projectWithOrg) |
||
207 | { |
||
208 | $q = "repo:$projectWithOrg in:title is:pr state:open"; |
||
209 | $result = new PullRequests(); |
||
210 | $searchResults = $this->gitHubAPI()->api('search')->issues($q); |
||
211 | $result->addSearchResults($searchResults); |
||
212 | |||
213 | return $result; |
||
214 | } |
||
215 | |||
216 | /** |
||
217 | * Pass an event of note to the event logger |
||
218 | * @param string $event_name |
||
219 | * @param array $args |
||
220 | * @param array $params |
||
221 | * @param array $response |
||
222 | */ |
||
223 | protected function logEvent($event_name, $args, $params, $response) |
||
224 | { |
||
225 | if ($this->eventLogger) { |
||
226 | $this->eventLogger->log($event_name, $args, $params, $response); |
||
227 | } |
||
228 | } |
||
229 | |||
230 | /** |
||
231 | * Authenticate and then return the gitHub API object. |
||
232 | */ |
||
233 | public function gitHubAPI() |
||
234 | { |
||
235 | if (!$this->gitHubAPI) { |
||
236 | $token = $this->gitHubToken(); |
||
237 | |||
238 | $this->gitHubAPI = new \Github\Client(); |
||
239 | $this->gitHubAPI->authenticate($token, null, \Github\Client::AUTH_HTTP_TOKEN); |
||
240 | } |
||
241 | return $this->gitHubAPI; |
||
242 | } |
||
243 | |||
244 | /** |
||
245 | * Return a result pager object using our cached GitHub API client. |
||
246 | */ |
||
247 | public function resultPager() |
||
248 | { |
||
249 | return new \Github\ResultPager($this->gitHubAPI()); |
||
250 | } |
||
251 | |||
252 | /** |
||
253 | * Look up the GitHub token set either via environment variable or in the |
||
254 | * auth-token cache directory. |
||
255 | */ |
||
256 | public function gitHubToken() |
||
257 | { |
||
258 | if (!$this->token) { |
||
259 | $this->token = $this->getGitHubToken(); |
||
260 | } |
||
261 | return $this->token; |
||
262 | } |
||
263 | |||
264 | protected function getGitHubToken() |
||
265 | { |
||
266 | $as = $this->as; |
||
267 | $token = null; |
||
268 | if ($as == 'default') { |
||
269 | $as = $this->getConfig()->get("github.default-user"); |
||
270 | } |
||
271 | |||
272 | // First preference: There is a 'path' component in preferences |
||
273 | // pointing to a file containing the token. |
||
274 | $github_token_cache = $this->getConfig()->get("github.personal-auth-token.$as.path"); |
||
275 | if (file_exists($github_token_cache)) { |
||
276 | $token = trim(file_get_contents($github_token_cache)); |
||
277 | } |
||
278 | |||
279 | // Second preference: There is an environment variable that begins |
||
280 | // with an uppercased version of the 'as' string followed by '_TOKEN' |
||
281 | if (!$token) { |
||
282 | $env_name = strtoupper(str_replace('-', '_', $as)) . '_TOKEN'; |
||
283 | $token = getenv($env_name); |
||
284 | } |
||
285 | |||
286 | // If we read in a token from one of the preferred locations, then |
||
287 | // set the GITHUB_TOKEN environment variable and return it. |
||
288 | if ($token) { |
||
289 | putenv("GITHUB_TOKEN=$token"); |
||
290 | return $token; |
||
291 | } |
||
292 | |||
293 | // Fallback: authenticate to whatever 'GITHUB_TOKEN' is already set to. |
||
294 | return getenv('GITHUB_TOKEN'); |
||
295 | } |
||
296 | |||
297 | protected function getConfig() |
||
298 | { |
||
299 | return $this->config; |
||
300 | } |
||
301 | } |
||
302 |
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.