%PDF- %PDF-
Direktori : /home1/lightco1/www/components/com_akeeba/Model/ |
Current File : //home1/lightco1/www/components/com_akeeba/Model/Json.php |
<?php /** * @package AkeebaBackup * @copyright Copyright (c)2006-2017 Nicholas K. Dionysopoulos / Akeeba Ltd * @license GNU General Public License version 3, or later */ namespace Akeeba\Backup\Site\Model; // Protect from unauthorized access defined('_JEXEC') or die(); use Akeeba\Backup\Site\Model\Json\Encapsulation; use Akeeba\Backup\Site\Model\Json\Task; use Akeeba\Engine\Platform; use Akeeba\Engine\Util\Complexify; use FOF30\Container\Container; use FOF30\Model\Model; // JSON API version number define('AKEEBA_JSON_API_VERSION', '350'); /* * Short API version history: * 300 First draft. Basic backup working. Encryption semi-broken. * 316 Fixed download feature. * 320 Minor bug fixes * 330 Introduction of Akeeba Solo * 335 Configuration overrides in startBackup * 340 Advanced API allows full configuration * 341 exportConfiguration, importConfiguration */ if (!defined('AKEEBA_BACKUP_ORIGIN')) { define('AKEEBA_BACKUP_ORIGIN', 'json'); } /** * JSON API model. Handles remote API calls through our JSON API. */ class Json extends Model { const COM_AKEEBA_CPANEL_LBL_STATUS_OK = 200; // Normal reply const STATUS_NOT_AUTH = 401; // Invalid credentials const STATUS_NOT_ALLOWED = 403; // Not enough privileges const STATUS_NOT_FOUND = 404; // Requested resource not found const STATUS_INVALID_METHOD = 405; // Unknown JSON method const COM_AKEEBA_CPANEL_LBL_STATUS_ERROR = 500; // An error occurred const STATUS_NOT_IMPLEMENTED = 501; // Not implemented feature const STATUS_NOT_AVAILABLE = 503; // Remote service not activated /** @var int Data encapsulation format */ private $encapsulationType = 1; /** @var Encapsulation */ private $encapsulation; /** @var string A password passed to us by the caller */ private $password = null; /** * Overridden constructor * * Sets up the encapsulation. * * @param Container $container The configuration variables to this model * @param array $config Configuration values for this model */ public function __construct(Container $container, array $config) { parent::__construct($container, $config); $this->encapsulation = new Encapsulation($this->serverKey()); } /** * Parses the JSON data sent by the client and executes the appropriate JSON API task * * @param string $json The raw JSON data received from the remote client * * @return string The JSON-encoded, fully encapsulated response */ public function execute($json) { // Check if we're activated $enabled = Platform::getInstance()->get_platform_configuration_option('frontend_enable', 0); // Is the Secret Key strong enough? $validKey = $this->serverKey(); if (!Complexify::isStrongEnough($validKey, false)) { $enabled = false; } $rawEncapsulation = $this->encapsulation->getEncapsulationByCode('ENCAPSULATION_RAW'); if (!$enabled) { return $this->getResponse('Access denied', 503); } // Try to JSON-decode the request's input first $request = @json_decode($json, true); if (is_null($request)) { return $this->getResponse('JSON decoding error', 500); } // Transform legacy requests if (!is_array($request)) { $request = array( 'encapsulation' => $rawEncapsulation, 'body' => $request ); } // Transform partial requests if (!isset($request['encapsulation'])) { $request['encapsulation'] = $rawEncapsulation; } // Make sure we have a request body if (!isset($request['body'])) { $request['body'] = ''; } try { $request['body'] = $this->encapsulation->decode($request['encapsulation'], $request['body']); } catch (\Exception $e) { return $this->getResponse($e->getMessage(), $e->getCode()); } // Replicate the encapsulation preferences of the client for our own output $this->encapsulationType = $request['encapsulation']; // Store the client-specified key, or use the server key if none specified and the request // came encrypted. $this->password = isset($request['body']['key']) ? $request['body']['key'] : $this->serverKey(); // Run the method $params = array(); if (isset($request['body']['data'])) { $params = (array)$request['body']['data']; } try { $taskHandler = new Task($this->container); $data = $taskHandler->execute($request['body']['method'], $params); } catch (\RuntimeException $e) { return $this->getResponse($e->getMessage(), $e->getCode()); } return $this->getResponse($data); } /** * Packages the response to a JSON-encoded object, optionally encrypting the data part with a caller-supplied * password. * * @param mixed $data The response to encapsulate * @param int $status The status code to return. 200 = Success, anything else is treated as an error. * * @return string The JSON-encoded response */ private function getResponse($data, $status = 200) { // Initialize the response $response = array( 'encapsulation' => $this->encapsulationType, 'body' => array( 'status' => $status, 'data' => null ) ); if ($status != 200) { $response['encapsulation'] = $this->encapsulation->getEncapsulationByCode('ENCAPSULATION_RAW'); } try { $response['body']['data'] = $this->encapsulation->encode($response['encapsulation'], $data, $this->password); } catch (\Exception $e) { $response['encapsulation'] = $this->encapsulation->getEncapsulationByCode('ENCAPSULATION_RAW'); $response['body'] = array( 'status' => $e->getCode(), 'data' => $e->getMessage(), ); } return '###' . json_encode($response) . '###'; } /** * Get the server key, i.e. the Secret Word for the front-end backups and JSON API * * @return mixed */ private function serverKey() { static $key = null; if (is_null($key)) { $key = Platform::getInstance()->get_platform_configuration_option('frontend_secret_word', ''); } return $key; } }