lasthourcloud/bootstrap/helpers/github.php

100 lines
3.8 KiB
PHP
Raw Normal View History

2023-05-24 12:26:50 +00:00
<?php
use App\Models\GithubApp;
2023-05-30 13:52:17 +00:00
use App\Models\GitlabApp;
2023-07-11 09:11:51 +00:00
use Carbon\Carbon;
2023-05-24 12:26:50 +00:00
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
2023-05-24 12:26:50 +00:00
use Lcobucci\JWT\Encoding\ChainedFormatter;
use Lcobucci\JWT\Encoding\JoseEncoder;
use Lcobucci\JWT\Signer\Key\InMemory;
use Lcobucci\JWT\Signer\Rsa\Sha256;
use Lcobucci\JWT\Token\Builder;
function generate_github_installation_token(GithubApp $source)
{
$signingKey = InMemory::plainText($source->privateKey->private_key);
2024-07-24 12:27:21 +00:00
$algorithm = new Sha256;
$tokenBuilder = (new Builder(new JoseEncoder, ChainedFormatter::default()));
$now = new DateTimeImmutable;
2023-05-24 12:26:50 +00:00
$now = $now->setTime($now->format('H'), $now->format('i'));
$issuedToken = $tokenBuilder
->issuedBy($source->app_id)
->issuedAt($now)
->expiresAt($now->modify('+10 minutes'))
->getToken($algorithm, $signingKey)
->toString();
$token = Http::withHeaders([
'Authorization' => "Bearer $issuedToken",
2024-06-10 20:43:34 +00:00
'Accept' => 'application/vnd.github.machine-man-preview+json',
2023-05-24 12:26:50 +00:00
])->post("{$source->api_url}/app/installations/{$source->installation_id}/access_tokens");
if ($token->failed()) {
2024-06-10 20:43:34 +00:00
throw new RuntimeException('Failed to get access token for '.$source->name.' with error: '.data_get($token->json(), 'message', 'no error message found'));
2023-05-24 12:26:50 +00:00
}
2024-06-10 20:43:34 +00:00
2023-05-24 12:26:50 +00:00
return $token->json()['token'];
}
2023-05-24 12:26:50 +00:00
function generate_github_jwt_token(GithubApp $source)
{
$signingKey = InMemory::plainText($source->privateKey->private_key);
2024-07-24 12:27:21 +00:00
$algorithm = new Sha256;
$tokenBuilder = (new Builder(new JoseEncoder, ChainedFormatter::default()));
$now = new DateTimeImmutable;
2023-05-24 12:26:50 +00:00
$now = $now->setTime($now->format('H'), $now->format('i'));
$issuedToken = $tokenBuilder
->issuedBy($source->app_id)
->issuedAt($now->modify('-1 minute'))
->expiresAt($now->modify('+10 minutes'))
->getToken($algorithm, $signingKey)
->toString();
2024-06-10 20:43:34 +00:00
2023-05-24 12:26:50 +00:00
return $issuedToken;
}
2023-05-30 13:52:17 +00:00
2024-06-10 20:43:34 +00:00
function githubApi(GithubApp|GitlabApp|null $source, string $endpoint, string $method = 'get', ?array $data = null, bool $throwError = true)
2023-05-30 13:52:17 +00:00
{
if (is_null($source)) {
throw new \Exception('Not implemented yet.');
}
2023-05-30 13:52:17 +00:00
if ($source->getMorphClass() == 'App\Models\GithubApp') {
if ($source->is_public) {
2023-06-13 13:01:11 +00:00
$response = Http::github($source->api_url)->$method($endpoint);
} else {
$github_access_token = generate_github_installation_token($source);
if ($data && ($method === 'post' || $method === 'patch' || $method === 'put')) {
$response = Http::github($source->api_url, $github_access_token)->$method($endpoint, $data);
} else {
$response = Http::github($source->api_url, $github_access_token)->$method($endpoint);
}
2023-05-30 13:52:17 +00:00
}
}
$json = $response->json();
2023-06-13 13:01:11 +00:00
if ($response->failed() && $throwError) {
2024-01-26 17:46:50 +00:00
ray($json);
2024-06-10 20:43:34 +00:00
throw new \Exception("Failed to get data from {$source->name} with error:<br><br>".$json['message'].'<br><br>Rate Limit resets at: '.Carbon::parse((int) $response->header('X-RateLimit-Reset'))->format('Y-m-d H:i:s').'UTC');
2023-05-30 13:52:17 +00:00
}
2024-06-10 20:43:34 +00:00
2023-05-30 13:52:17 +00:00
return [
'rate_limit_remaining' => $response->header('X-RateLimit-Remaining'),
'rate_limit_reset' => $response->header('X-RateLimit-Reset'),
2024-06-10 20:43:34 +00:00
'data' => collect($json),
2023-05-30 13:52:17 +00:00
];
}
2023-06-14 09:03:54 +00:00
function get_installation_path(GithubApp $source)
{
$github = GithubApp::where('uuid', $source->uuid)->first();
$name = str(Str::kebab($github->name));
2023-06-14 09:03:54 +00:00
$installation_path = $github->html_url === 'https://github.com' ? 'apps' : 'github-apps';
2024-06-10 20:43:34 +00:00
2023-06-14 09:03:54 +00:00
return "$github->html_url/$installation_path/$name/installations/new";
}
2024-06-10 20:43:34 +00:00
function get_permissions_path(GithubApp $source)
{
$github = GithubApp::where('uuid', $source->uuid)->first();
$name = str(Str::kebab($github->name));
2024-06-10 20:43:34 +00:00
return "$github->html_url/settings/apps/$name/permissions";
}