You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
3.8 KiB
PHP
114 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace SiteWeb;
|
|
|
|
use GuzzleHttp\Client;
|
|
use GuzzleHttp\RequestOptions;
|
|
use stdClass;
|
|
use Throwable;
|
|
|
|
/**
|
|
* A connector between Gitea and Packagist for auto-update
|
|
*/
|
|
class Connector {
|
|
/**
|
|
* Treat queries
|
|
*/
|
|
public function proceed (): void {
|
|
//region Check environment
|
|
$packagist = new stdClass();
|
|
try {
|
|
$packagist->username = Env::getInstance()->getProperty(Env::PROPERTY_PACKAGIST_USERNAME);
|
|
$packagist->apiToken = Env::getInstance()->getProperty(Env::PROPERTY_PACKAGIST_APITOKEN);
|
|
}
|
|
catch (Throwable $e) {
|
|
$this->exitError('Invalid environment: [' . get_class($e) . '] ' . $e->getMessage());
|
|
}
|
|
//endregion
|
|
//region Check request method and content type
|
|
$requestMethod = mb_strtoupper(trim($_SERVER['REQUEST_METHOD'] ?? ''));
|
|
if ($requestMethod !== 'POST') {
|
|
$this->exitError('Invalid request method: ' . $requestMethod);
|
|
}
|
|
|
|
$contentType = mb_strtolower(trim($_SERVER['CONTENT_TYPE'] ?? ''));
|
|
if ($contentType != 'application/json') {
|
|
$this->exitError('Invalid content type: ' . $contentType);
|
|
}
|
|
//endregion
|
|
//region Check payload
|
|
$payload = trim(file_get_contents("php://input"));
|
|
if (empty($payload)) {
|
|
$this->exitError('No Gitea payload');
|
|
}
|
|
|
|
$payloadSignatureExpected = $_SERVER['HTTP_X_GITEA_SIGNATURE'] ?? '';
|
|
if (empty($payloadSignatureExpected)) {
|
|
$this->exitError('No Gitea payload signature');
|
|
}
|
|
|
|
$payloadSignature = hash_hmac('sha256', $payload, $packagist->apiToken, false);
|
|
|
|
if ($payloadSignatureExpected !== $payloadSignature) {
|
|
$this->exitError('Gitea payload signatures don\'t match');
|
|
}
|
|
|
|
$giteaData = new stdClass();
|
|
try {
|
|
$giteaData = json_decode($payload, false, 512, JSON_THROW_ON_ERROR);
|
|
}
|
|
catch (Throwable $e) {
|
|
$this->exitError('Invalid Gitea payload (JSON decoding failed): [' . get_class($e) . '] ' . $e->getMessage());
|
|
}
|
|
//endregion
|
|
|
|
//region Build Packagist data
|
|
$packagistData = new stdClass();
|
|
$packagistData->repository = new stdClass();
|
|
$packagistData->repository->url = $giteaData->repository->html_url;
|
|
|
|
$packagistDataJSON = null;
|
|
try {
|
|
$packagistDataJSON = json_encode($packagistData, JSON_THROW_ON_ERROR);
|
|
}
|
|
catch (Throwable $e) {
|
|
$this->exitError('Invalid Packagist payload (JSON encoding failed): [' . get_class($e) . '] ' . $e->getMessage());
|
|
}
|
|
//endregion
|
|
|
|
//region Send data to Packagist
|
|
$response = null;
|
|
try {
|
|
$request = new Client();
|
|
$response = $request->post(
|
|
'https://packagist.org/api/update-package',
|
|
[
|
|
RequestOptions::QUERY => [
|
|
'username' => $packagist->username,
|
|
'apiToken' => $packagist->apiToken,
|
|
],
|
|
RequestOptions::HTTP_ERRORS => false,
|
|
RequestOptions::HEADERS => [
|
|
'Content-Type' => 'application/json',
|
|
],
|
|
RequestOptions::BODY => $packagistDataJSON,
|
|
]
|
|
);
|
|
}
|
|
catch (Throwable $e) {
|
|
$this->exitError('Failed to send data: ' . $e->getMessage());
|
|
}
|
|
//endregion
|
|
//region Return the Packagist response
|
|
header('Content-Type: application/json', true, $response->getStatusCode());
|
|
echo $response->getBody();
|
|
exit;
|
|
//endregion
|
|
}
|
|
|
|
private function exitError (string $msg) {
|
|
header('Content-Type: text/plain; charset=UTF-8', true, 500);
|
|
echo $msg;
|
|
exit;
|
|
}
|
|
} |