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(); |
||
0 ignored issues
–
show
|
|||
52 | return $authenticated; |
||
53 | } |
||
54 | |||
55 | public function repoCreate($org, $project) |
||
56 | { |
||
57 | return $this->api->gitHubAPI()->api('repo')->create( |
||
0 ignored issues
–
show
The property
api does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
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); |
||
0 ignored issues
–
show
It seems like you code against a concrete implementation and not the interface
Github\Api\ApiInterface as the method create() does only exist in the following implementations of said interface: Github\Api\Authorizations , Github\Api\CurrentUser\PublicKeys , Github\Api\Deployment , Github\Api\Gist\Comments , Github\Api\Gists , Github\Api\GitData\Blobs , Github\Api\GitData\Commits , Github\Api\GitData\References , Github\Api\GitData\Tags , Github\Api\GitData\Trees , Github\Api\Issue , Github\Api\Issue\Comments , Github\Api\Issue\Labels , Github\Api\Issue\Milestones , Github\Api\Organization\Hooks , Github\Api\Organization\Projects , Github\Api\Organization\Teams , Github\Api\Project\Cards , Github\Api\Project\Columns , Github\Api\PullRequest , Github\Api\PullRequest\Comments , Github\Api\PullRequest\Review , Github\Api\PullRequest\ReviewRequest , Github\Api\Repo , Github\Api\Repository\Assets , Github\Api\Repository\Checks , Github\Api\Repository\Comments , Github\Api\Repository\Contents , Github\Api\Repository\DeployKeys , Github\Api\Repository\Forks , Github\Api\Repository\Hooks , Github\Api\Repository\Labels , Github\Api\Repository\Projects , Github\Api\Repository\Releases , Github\Api\Repository\Statuses .
Let’s take a look at an example: interface User
{
/** @return string */
public function getPassword();
}
class MyUser implements User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
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']); |
||
0 ignored issues
–
show
It seems like you code against a concrete implementation and not the interface
Github\Api\ApiInterface as the method update() does only exist in the following implementations of said interface: Github\Api\Authorizations , Github\Api\CurrentUser , Github\Api\Gist\Comments , Github\Api\Gists , Github\Api\GitData\References , Github\Api\Issue , Github\Api\Issue\Comments , Github\Api\Issue\Labels , Github\Api\Issue\Milestones , Github\Api\Organization , Github\Api\Organization\Hooks , Github\Api\Organization\Projects , Github\Api\Organization\Teams , Github\Api\Project\AbstractProjectApi , Github\Api\Project\Cards , Github\Api\Project\Columns , Github\Api\PullRequest , Github\Api\PullRequest\Comments , Github\Api\PullRequest\Review , Github\Api\Repo , Github\Api\Repository\Checks , Github\Api\Repository\Comments , Github\Api\Repository\Contents , Github\Api\Repository\DeployKeys , Github\Api\Repository\Hooks , Github\Api\Repository\Labels , Github\Api\Repository\Pages , Github\Api\Repository\Projects , Github\Api\Repository\Protection .
Let’s take a look at an example: interface User
{
/** @return string */
public function getPassword();
}
class MyUser implements User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
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; |
||
0 ignored issues
–
show
$allClean is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
97 | $shas = []; |
||
98 | foreach ($prs->prNumbers() as $n) { |
||
99 | $pullRequest = $this->gitHubAPI()->api('pull_request')->show($org, $project, $n); |
||
0 ignored issues
–
show
It seems like you code against a concrete implementation and not the interface
Github\Api\ApiInterface as the method show() does only exist in the following implementations of said interface: Github\Api\Authorizations , Github\Api\CurrentUser , Github\Api\CurrentUser\Notifications , Github\Api\CurrentUser\PublicKeys , Github\Api\Deployment , Github\Api\Enterprise\License , Github\Api\Enterprise\Stats , Github\Api\Gist\Comments , Github\Api\Gists , Github\Api\GitData\Blobs , Github\Api\GitData\Commits , Github\Api\GitData\References , Github\Api\GitData\Tags , Github\Api\GitData\Trees , Github\Api\Issue , Github\Api\Issue\Comments , Github\Api\Issue\Events , Github\Api\Issue\Labels , Github\Api\Issue\Milestones , Github\Api\Miscellaneous\CodeOfConduct , Github\Api\Miscellaneous\Gitignore , Github\Api\Miscellaneous\Licenses , Github\Api\Organization , Github\Api\Organization\Hooks , Github\Api\Organization\Members , Github\Api\Organization\Projects , Github\Api\Organization\Teams , Github\Api\Project\AbstractProjectApi , Github\Api\Project\Cards , Github\Api\Project\Columns , Github\Api\PullRequest , Github\Api\PullRequest\Comments , Github\Api\PullRequest\Review , Github\Api\Repo , Github\Api\Repository\Assets , Github\Api\Repository\Comments , Github\Api\Repository\Commits , Github\Api\Repository\Contents , Github\Api\Repository\DeployKeys , Github\Api\Repository\Downloads , Github\Api\Repository\Hooks , Github\Api\Repository\Labels , Github\Api\Repository\Pages , Github\Api\Repository\Projects , Github\Api\Repository\Protection , Github\Api\Repository\Releases , Github\Api\Repository\Statuses , Github\Api\User .
Let’s take a look at an example: interface User
{
/** @return string */
public function getPassword();
}
class MyUser implements User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
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); |
||
0 ignored issues
–
show
It seems like you code against a concrete implementation and not the interface
Github\Api\ApiInterface as the method merge() does only exist in the following implementations of said interface: Github\Api\PullRequest , Github\Api\Repo .
Let’s take a look at an example: interface User
{
/** @return string */
public function getPassword();
}
class MyUser implements User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
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
The doc-type
int">[int could not be parsed: Unknown type name "[" at position 0. [(view supported doc-types)
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. ![]() |
|||
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); |
||
0 ignored issues
–
show
It seems like you code against a concrete implementation and not the interface
Github\Api\ApiInterface as the method status() does only exist in the following implementations of said interface: Github\Api\PullRequest .
Let’s take a look at an example: interface User
{
/** @return string */
public function getPassword();
}
class MyUser implements User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
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) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
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); |
||
0 ignored issues
–
show
It seems like you code against a concrete implementation and not the interface
Github\Api\ApiInterface as the method issues() does only exist in the following implementations of said interface: Github\Api\CurrentUser , Github\Api\Enterprise\Stats , Github\Api\Organization , Github\Api\Search .
Let’s take a look at an example: interface User
{
/** @return string */
public function getPassword();
}
class MyUser implements User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
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); |
||
0 ignored issues
–
show
It seems like you code against a concrete implementation and not the interface
Github\Api\ApiInterface as the method issues() does only exist in the following implementations of said interface: Github\Api\CurrentUser , Github\Api\Enterprise\Stats , Github\Api\Organization , Github\Api\Search .
Let’s take a look at an example: interface User
{
/** @return string */
public function getPassword();
}
class MyUser implements User
{
public function getPassword()
{
// return something
}
public function getDisplayName()
{
// return some name.
}
}
class AuthSystem
{
public function authenticate(User $user)
{
$this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
// do something.
}
}
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break. Available Fixes
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types
inside the if block in such a case.
![]() |
|||
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) { |
||
0 ignored issues
–
show
The expression
$token of type string|null is loosely compared to false ; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
|||
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 |
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the interface: