- Add CloudronStack/output/CloudronPackages-Artifacts/tirreno/ directory and its contents - Includes package manifest, Dockerfile, source code, documentation, and build artifacts - Add tirreno-1761840148.tar.gz as a build artifact - Add tirreno-cloudron-package-1761841304.tar.gz as the Cloudron package - Include all necessary files for the tirreno Cloudron package This adds the complete tirreno Cloudron package artifacts to the repository.
		
			
				
	
	
		
			143 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			143 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
/**
 | 
						|
 * Tirreno ~ Open source user analytics
 | 
						|
 * Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
 | 
						|
 *
 | 
						|
 * Licensed under GNU Affero General Public License version 3 of the or any later version.
 | 
						|
 * For full copyright and license information, please see the LICENSE
 | 
						|
 * Redistributions of files must retain the above copyright notice.
 | 
						|
 *
 | 
						|
 * @copyright     Copyright (c) Tirreno Technologies Sàrl (https://www.tirreno.com)
 | 
						|
 * @license       https://opensource.org/licenses/AGPL-3.0 AGPL License
 | 
						|
 * @link          https://www.tirreno.com Tirreno(tm)
 | 
						|
 */
 | 
						|
 | 
						|
namespace Controllers\Api;
 | 
						|
 | 
						|
abstract class Endpoint {
 | 
						|
    use \Traits\Db;
 | 
						|
    use \Traits\Debug;
 | 
						|
 | 
						|
    public const API_KEY = 'Api-Key';
 | 
						|
 | 
						|
    protected $f3;
 | 
						|
 | 
						|
    protected \Views\Json $response;
 | 
						|
    protected \Type\ResponseType $responseType;
 | 
						|
    protected int $error;
 | 
						|
    protected array $validationErrors = [];
 | 
						|
 | 
						|
    private string $apiKeyString;
 | 
						|
    protected \Models\ApiKeys $apiKey;
 | 
						|
    protected \Interfaces\ApiKeyAccessAuthorizationInterface $authorizationModel;
 | 
						|
 | 
						|
    private array $body = [];
 | 
						|
 | 
						|
    protected array|null $data = null;
 | 
						|
 | 
						|
    public function __construct() {
 | 
						|
        $this->f3 = \Base::instance();
 | 
						|
        $this->f3->set('ONERROR', function (): void {
 | 
						|
            $this->handleInternalServerError();
 | 
						|
        });
 | 
						|
        $this->connectToDb(false);
 | 
						|
 | 
						|
        $this->response = new \Views\Json();
 | 
						|
        $this->responseType = new \Type\ResponseType(\Type\ResponseType::SINGLE);
 | 
						|
    }
 | 
						|
 | 
						|
    public function beforeRoute(): void {
 | 
						|
        $this->identify();
 | 
						|
        $this->authenticate();
 | 
						|
        $this->parseBody();
 | 
						|
    }
 | 
						|
 | 
						|
    public function afterRoute(): void {
 | 
						|
        if (isset($this->error)) {
 | 
						|
            $errorI18nCode = sprintf('error_%s', $this->error);
 | 
						|
            $errorMessage = $this->f3->get($errorI18nCode);
 | 
						|
            $this->response->data = [
 | 
						|
                'code' => $this->error,
 | 
						|
                'message' => $errorMessage,
 | 
						|
            ];
 | 
						|
            $this->data = null;
 | 
						|
        }
 | 
						|
 | 
						|
        if (($this->data !== null)) {
 | 
						|
            $this->response->data = $this->data;
 | 
						|
        }
 | 
						|
 | 
						|
        echo $this->response->render();
 | 
						|
    }
 | 
						|
 | 
						|
    protected function identify(): void {
 | 
						|
        $headers = $this->f3->get('HEADERS') ?? [];
 | 
						|
 | 
						|
        if (array_key_exists(self::API_KEY, $headers) && is_string($headers[self::API_KEY])) {
 | 
						|
            $this->apiKeyString = $headers[self::API_KEY];
 | 
						|
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        $this->setError(400, \Utils\ErrorCodes::REST_API_KEY_DOES_NOT_EXIST);
 | 
						|
    }
 | 
						|
 | 
						|
    protected function authenticate(): void {
 | 
						|
        $model = new \Models\ApiKeys();
 | 
						|
        $apiKey = $model->getKeyIdByHash($this->apiKeyString);
 | 
						|
 | 
						|
        if ($apiKey) {
 | 
						|
            $this->apiKey = $apiKey;
 | 
						|
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        $this->setError(401, \Utils\ErrorCodes::REST_API_KEY_IS_NOT_CORRECT);
 | 
						|
    }
 | 
						|
 | 
						|
    protected function authorize(string $subjectId): void {
 | 
						|
        if (!isset($this->apiKey) || isset($this->error)) {
 | 
						|
            exit;
 | 
						|
        }
 | 
						|
 | 
						|
        $apiKeyId = $this->apiKey->id;
 | 
						|
        $hasAccess = $this->authorizationModel->checkAccessByExternalId($subjectId, $apiKeyId);
 | 
						|
 | 
						|
        if ($hasAccess) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        $this->setError(403, \Utils\ErrorCodes::REST_API_NOT_AUTHORIZED);
 | 
						|
    }
 | 
						|
 | 
						|
    protected function getBodyProp(string $key, string $paramType = 'string'): string|int|array|null {
 | 
						|
        $value = $this->body[$key] ?? null;
 | 
						|
 | 
						|
        if (isset($value)) {
 | 
						|
            settype($value, $paramType);
 | 
						|
        }
 | 
						|
 | 
						|
        return $value;
 | 
						|
    }
 | 
						|
 | 
						|
    protected function setError(int $statusCode, int $errorCode): void {
 | 
						|
        $this->f3->status($statusCode);
 | 
						|
        $this->error = $errorCode;
 | 
						|
        $this->afterRoute();
 | 
						|
        exit;
 | 
						|
    }
 | 
						|
 | 
						|
    private function parseBody(): void {
 | 
						|
        $body = $this->f3->get('BODY');
 | 
						|
        $this->body = json_decode($body, true) ?? [];
 | 
						|
    }
 | 
						|
 | 
						|
    private function handleInternalServerError(): void {
 | 
						|
        $errorData = \Utils\ErrorHandler::getErrorDetails($this->f3);
 | 
						|
        \Utils\ErrorHandler::saveErrorInformation($this->f3, $errorData);
 | 
						|
 | 
						|
        $this->setError(500, 500);
 | 
						|
    }
 | 
						|
}
 |