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.
102 lines
3.6 KiB
PHP
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;
|
|
}
|
|
} |