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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

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;
}
}