diff --git a/phpstan.neon b/phpstan.neon index e1e3faec3..827fd3355 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -54,7 +54,7 @@ parameters: PackageSource: 'array{url: string|null, type: string|null, reference: string|null}|null' AnyJob: 'array' - PackageUpdateJob: 'array{id: int, update_equal_refs: bool, delete_before: bool, force_dump: bool}' + PackageUpdateJob: 'array{id: int, update_equal_refs: bool, delete_before: bool, force_dump: bool, source: string}' GitHubUserMigrateJob: 'array{id: int, old_scope: string, new_scope: string}' SecurityAdvisoryJob: 'array{source: string}' diff --git a/src/Command/UpdatePackagesCommand.php b/src/Command/UpdatePackagesCommand.php index 6472c5173..aa15b826a 100644 --- a/src/Command/UpdatePackagesCommand.php +++ b/src/Command/UpdatePackagesCommand.php @@ -108,7 +108,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $idsGroup = array_splice($ids, 0, 100); foreach ($idsGroup as $id) { - $job = $this->scheduler->scheduleUpdate($id, $updateEqualRefs, $deleteBefore, $randomTimes ? new \DateTime('+'.random_int(1, 600).'seconds') : null); + $job = $this->scheduler->scheduleUpdate($id, 'update cmd', $updateEqualRefs, $deleteBefore, $randomTimes ? new \DateTime('+'.random_int(1, 600).'seconds') : null); if ($verbose) { $output->writeln('Scheduled update job '.$job->getId().' for package '.$id); } diff --git a/src/Controller/ApiController.php b/src/Controller/ApiController.php index fcb9fcf92..192f66aac 100644 --- a/src/Controller/ApiController.php +++ b/src/Controller/ApiController.php @@ -419,6 +419,7 @@ protected function receiveUpdateRequest(Request $request, string $url, string $u $user = null; $autoUpdated = Package::AUTO_MANUAL_HOOK; $receiveType = 'manual'; + $source = 'unknown'; // manual hook set up with user API token as secret if ($match['host'] === 'github.com' && $request->getContent() && $request->query->has('username') && $request->headers->has('X-Hub-Signature')) { @@ -428,8 +429,9 @@ protected function receiveUpdateRequest(Request $request, string $url, string $u if ($sig && $user && $user->isEnabled()) { [$algo, $sig] = explode('=', $sig); $expected = hash_hmac($algo, $request->getContent(), $user->getApiToken()); + $source = 'manual_github_hook'; if (hash_equals($expected, $sig)) { - $packages = $this->findGitHubPackagesByRepository($match['path'], (string) $remoteId, $user); + $packages = $this->findGitHubPackagesByRepository($match['path'], (string) $remoteId, $source, $user); $autoUpdated = Package::AUTO_GITHUB_HOOK; $receiveType = 'github_user_secret'; } else { @@ -443,6 +445,9 @@ protected function receiveUpdateRequest(Request $request, string $url, string $u if (!$user) { // find the user $user = $this->findUser($request, ApiType::Safe); + if ($user) { + $source = 'manual_hook ('.$user->getUsername().' @ '.$request->getPathInfo().')'; + } } if (!$user && $match['host'] === 'github.com' && $request->getContent()) { @@ -450,8 +455,10 @@ protected function receiveUpdateRequest(Request $request, string $url, string $u if ($sig) { [$algo, $sig] = explode('=', $sig); $expected = hash_hmac($algo, $request->getContent(), $githubWebhookSecret); + $source = 'github_official_hook'; + if (hash_equals($expected, $sig)) { - $packages = $this->findGitHubPackagesByRepository($match['path'], (string) $remoteId); + $packages = $this->findGitHubPackagesByRepository($match['path'], (string) $remoteId, $source); $autoUpdated = Package::AUTO_GITHUB_HOOK; $receiveType = 'github_auto'; } @@ -477,7 +484,7 @@ protected function receiveUpdateRequest(Request $request, string $url, string $u foreach ($packages as $package) { $package->setAutoUpdated($autoUpdated); - $job = $this->scheduler->scheduleUpdate($package); + $job = $this->scheduler->scheduleUpdate($package, $source); $jobs[] = $job->getId(); } @@ -566,7 +573,7 @@ protected function findPackagesByUrl(User $user, string $url, string $urlRegex, * @param User|null $user If provided it means the request came with a user's API token and not the packagist-configured secret, so we cannot be sure it is a request coming directly from github * @return Package[] the packages found */ - protected function findGitHubPackagesByRepository(string $path, string $remoteId, ?User $user = null): array + protected function findGitHubPackagesByRepository(string $path, string $remoteId, string $source, ?User $user = null): array { $url = 'https://github.com/'.$path; @@ -617,7 +624,7 @@ protected function findGitHubPackagesByRepository(string $path, string $remoteId $package->setRepository($url); if ($url !== $previousUrl) { // ensure we do a full update of all versions to update the repo URL - $this->scheduler->scheduleUpdate($package, updateEqualRefs: true, forceDump: true); + $this->scheduler->scheduleUpdate($package, $source, updateEqualRefs: true, forceDump: true); } } } diff --git a/src/Controller/PackageController.php b/src/Controller/PackageController.php index 2b698b5e1..229d4879f 100644 --- a/src/Controller/PackageController.php +++ b/src/Controller/PackageController.php @@ -851,7 +851,7 @@ public function updatePackageAction(Request $req, string $name, #[CurrentUser] U } if ($update) { - $job = $this->scheduler->scheduleUpdate($package, $updateEqualRefs, false, null, $manualUpdate); + $job = $this->scheduler->scheduleUpdate($package, 'button/api', $updateEqualRefs, false, null, $manualUpdate); return new JsonResponse(['status' => 'success', 'job' => $job->getId()], 202); } diff --git a/src/Service/Scheduler.php b/src/Service/Scheduler.php index a2c3a2c31..f0049f90b 100644 --- a/src/Service/Scheduler.php +++ b/src/Service/Scheduler.php @@ -31,7 +31,7 @@ public function __construct( * @param Package|int $packageOrId * @return Job */ - public function scheduleUpdate($packageOrId, bool $updateEqualRefs = false, bool $deleteBefore = false, ?\DateTimeInterface $executeAfter = null, bool $forceDump = false): Job + public function scheduleUpdate($packageOrId, string $source, bool $updateEqualRefs = false, bool $deleteBefore = false, ?\DateTimeInterface $executeAfter = null, bool $forceDump = false): Job { if ($packageOrId instanceof Package) { $packageOrId = $packageOrId->getId(); @@ -60,7 +60,7 @@ public function scheduleUpdate($packageOrId, bool $updateEqualRefs = false, bool $this->getEM()->flush(); } - return $this->createJob('package:updates', ['id' => $packageOrId, 'update_equal_refs' => $updateEqualRefs, 'delete_before' => $deleteBefore, 'force_dump' => $forceDump], $packageOrId, $executeAfter); + return $this->createJob('package:updates', ['id' => $packageOrId, 'update_equal_refs' => $updateEqualRefs, 'delete_before' => $deleteBefore, 'force_dump' => $forceDump, 'source' => $source], $packageOrId, $executeAfter); } /**