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.

102 lines
3.6 KiB
PHP

<?php
namespace SiteWeb;
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: ' . $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 payload');
}
$payloadSignatureExpected = $_SERVER['HTTP_X_GITEA_SIGNATURE'] ?? '';
if (empty($payloadSignatureExpected)) {
$this->exitError('No payload signature');
}
$payloadSignature = hash_hmac('sha256', $payload, $packagist->apiToken, false);
if ($payloadSignatureExpected !== $payloadSignature) {
$this->exitError('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 payload (JSON decoding failed): ' . $e->getMessage());
}
//endregion
//region Build Packagist data
$packagistData = new stdClass();
$packagistData->repository = new stdClass();
$packagistData->repository->url = 'https://git.jrosset.ovh/' . $giteaData->full_name;
//endregion
//region Send data to Packagist
$cUrl = curl_init('https://packagist.org/api/update-package?username=' . $packagist->username . '&apiToken=' . $packagist->apiToken);
curl_setopt($cUrl, CURLOPT_POST, 1);
curl_setopt($cUrl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($cUrl, CURLOPT_HEADER, 1);
curl_setopt($cUrl, CURLOPT_POSTFIELDS, $packagistData);
curl_setopt($cUrl, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($cUrl, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($cUrl, CURLOPT_FORBID_REUSE, 1);
if (($response = curl_exec($cUrl)) === false) {
$this->exitError('Failed to send data: cUrl failed');
}
//endregion
//region Treat response
$responseCode = curl_getinfo($cUrl, CURLINFO_RESPONSE_CODE);
$responseHeadersSize = curl_getinfo($cUrl, CURLINFO_HEADER_SIZE);
$responseHeaders = preg_split('/\r?\n/', substr($response, 0, $responseHeadersSize));
foreach ($responseHeaders as $responseHeader) {
header($responseHeader, true, $responseCode);
}
echo substr($response, $responseHeadersSize); // Response body
exit;
//endregion
}
private function exitError (string $msg) {
header('Content-Type: text/plain; charset=UTF-8', true, 500);
echo $msg;
exit;
}
}