feat(deployed): add Akeeba site component (completeness)
components/com_akeeba (frontend) — the admin side was added earlier; this completes the module. Signed-off-by: LÁZÁR Imre <imre@illusion.hu> Assisted-by: claude-code@claude-opus-4-8
This commit is contained in:
parent
190c3ab0af
commit
e9d0295acf
195
deployed/akeeba/components/com_akeeba/Controller/Backup.php
Normal file
195
deployed/akeeba/components/com_akeeba/Controller/Backup.php
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Controller;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Admin\Controller\Mixin\PredefinedTaskList;
|
||||||
|
use Akeeba\Backup\Site\Controller\Mixin\ActivateProfile;
|
||||||
|
use Akeeba\Backup\Site\Controller\Mixin\CustomRedirection;
|
||||||
|
use Akeeba\Backup\Site\Controller\Mixin\FrontEndPermissions;
|
||||||
|
use Akeeba\Engine\Factory;
|
||||||
|
use FOF30\Container\Container;
|
||||||
|
use FOF30\Controller\Controller;
|
||||||
|
use FOF30\Date\Date;
|
||||||
|
use JLoader;
|
||||||
|
use JRoute;
|
||||||
|
use JText;
|
||||||
|
use JUri;
|
||||||
|
|
||||||
|
if (!defined('AKEEBA_BACKUP_ORIGIN'))
|
||||||
|
{
|
||||||
|
define('AKEEBA_BACKUP_ORIGIN', 'frontend');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for the front-end backup feature.
|
||||||
|
*
|
||||||
|
* The Traits used by this class offer most of the features you don't see, especially those pertaining to security:
|
||||||
|
* PredefinedTaskList Only allows certain tasks to be called.
|
||||||
|
* FrontEndPermissions Validates the secret word before running a task through checkPermissions.
|
||||||
|
* ActivateProfile Finds the profile specified in the URL and loads it through setProfile.
|
||||||
|
* CustomRedirection Provides customRedirect for HTTP redirects without dealing with CMS inconsistencies.
|
||||||
|
*/
|
||||||
|
class Backup extends Controller
|
||||||
|
{
|
||||||
|
use PredefinedTaskList, FrontEndPermissions, ActivateProfile, CustomRedirection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overridden constructor
|
||||||
|
*
|
||||||
|
* @param Container $container The application container
|
||||||
|
* @param array $config The configuration array
|
||||||
|
*/
|
||||||
|
public function __construct(Container $container, array $config)
|
||||||
|
{
|
||||||
|
parent::__construct($container, $config);
|
||||||
|
|
||||||
|
$this->setPredefinedTaskList(['main', 'step']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a front-end legacy backup
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function main()
|
||||||
|
{
|
||||||
|
$this->checkPermissions();
|
||||||
|
$this->setProfile();
|
||||||
|
|
||||||
|
// Get the backup ID
|
||||||
|
$backupId = $this->input->get('backupid', null, 'cmd');
|
||||||
|
|
||||||
|
if (empty($backupId))
|
||||||
|
{
|
||||||
|
$backupId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var \Akeeba\Backup\Site\Model\Backup $model */
|
||||||
|
$model = $this->container->factory->model('Backup')->tmpInstance();
|
||||||
|
|
||||||
|
JLoader::import('joomla.utilities.date');
|
||||||
|
$dateNow = new Date();
|
||||||
|
|
||||||
|
$model->setState('tag', AKEEBA_BACKUP_ORIGIN);
|
||||||
|
$model->setState('backupid', $backupId);
|
||||||
|
$model->setState('description', JText::_('COM_AKEEBA_BACKUP_DEFAULT_DESCRIPTION') . ' ' . $dateNow->format(JText::_('DATE_FORMAT_LC2'), true));
|
||||||
|
$model->setState('comment', '');
|
||||||
|
|
||||||
|
$array = $model->startBackup();
|
||||||
|
|
||||||
|
$backupId = $model->getState('backupid', null, 'cmd');
|
||||||
|
|
||||||
|
$this->processEngineReturnArray($array, $backupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Step through a front-end legacy backup
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function step()
|
||||||
|
{
|
||||||
|
// Setup
|
||||||
|
$this->checkPermissions();
|
||||||
|
$this->setProfile();
|
||||||
|
|
||||||
|
// Get the backup ID
|
||||||
|
$backupId = $this->input->get('backupid', null, 'cmd');
|
||||||
|
|
||||||
|
if (empty($backupId))
|
||||||
|
{
|
||||||
|
$backupId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var \Akeeba\Backup\Site\Model\Backup $model */
|
||||||
|
$model = $this->container->factory->model('Backup')->tmpInstance();
|
||||||
|
|
||||||
|
$model->setState('tag', AKEEBA_BACKUP_ORIGIN);
|
||||||
|
$model->setState('backupid', $backupId);
|
||||||
|
|
||||||
|
$array = $model->stepBackup();
|
||||||
|
|
||||||
|
$backupId = $model->getState('backupid', null, 'cmd');
|
||||||
|
|
||||||
|
$this->processEngineReturnArray($array, $backupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by the tasks to process Akeeba Engine's return array. Depending on the result and the component options we
|
||||||
|
* may throw text output or send an HTTP redirection header.
|
||||||
|
*
|
||||||
|
* @param array $array The return array to process
|
||||||
|
* @param string $backupId The backup ID (used to step the backup process)
|
||||||
|
*/
|
||||||
|
private function processEngineReturnArray($array, $backupId)
|
||||||
|
{
|
||||||
|
if ($array['Error'] != '')
|
||||||
|
{
|
||||||
|
@ob_end_clean();
|
||||||
|
echo '500 ERROR -- ' . $array['Error'];
|
||||||
|
flush();
|
||||||
|
|
||||||
|
$this->container->platform->closeApplication();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($array['HasRun'] == 1)
|
||||||
|
{
|
||||||
|
// All done
|
||||||
|
Factory::nuke();
|
||||||
|
Factory::getFactoryStorage()->reset();
|
||||||
|
@ob_end_clean();
|
||||||
|
header('Content-type: text/plain');
|
||||||
|
header('Connection: close');
|
||||||
|
echo '200 OK';
|
||||||
|
flush();
|
||||||
|
|
||||||
|
$this->container->platform->closeApplication();
|
||||||
|
}
|
||||||
|
|
||||||
|
$noredirect = $this->input->get('noredirect', 0, 'int');
|
||||||
|
|
||||||
|
if ($noredirect != 0)
|
||||||
|
{
|
||||||
|
@ob_end_clean();
|
||||||
|
header('Content-type: text/plain');
|
||||||
|
header('Connection: close');
|
||||||
|
echo "301 More work required -- BACKUPID ###$backupId###";
|
||||||
|
flush();
|
||||||
|
|
||||||
|
$this->container->platform->closeApplication();
|
||||||
|
}
|
||||||
|
|
||||||
|
$curUri = JUri::getInstance();
|
||||||
|
$ssl = $curUri->isSSL() ? 1 : 0;
|
||||||
|
$tempURL = JRoute::_('index.php?option=com_akeeba', false, $ssl);
|
||||||
|
$uri = new JUri($tempURL);
|
||||||
|
|
||||||
|
$uri->setVar('view', 'Backup');
|
||||||
|
$uri->setVar('task', 'step');
|
||||||
|
$uri->setVar('key', $this->input->get('key', '', 'none', 2));
|
||||||
|
$uri->setVar('profile', $this->input->get('profile', 1, 'int'));
|
||||||
|
|
||||||
|
if (!empty($backupId))
|
||||||
|
{
|
||||||
|
$uri->setVar('backupid', $backupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maybe we have a multilingual site?
|
||||||
|
$language = $this->container->platform->getLanguage();
|
||||||
|
$languageTag = $language->getTag();
|
||||||
|
|
||||||
|
$uri->setVar('lang', $languageTag);
|
||||||
|
|
||||||
|
$redirectionUrl = $uri->toString();
|
||||||
|
|
||||||
|
$this->customRedirect($redirectionUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
62
deployed/akeeba/components/com_akeeba/Controller/Check.php
Normal file
62
deployed/akeeba/components/com_akeeba/Controller/Check.php
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Controller;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Admin\Controller\Mixin\PredefinedTaskList;
|
||||||
|
use Akeeba\Backup\Site\Controller\Mixin\FrontEndPermissions;
|
||||||
|
use Akeeba\Backup\Site\Model\Statistics;
|
||||||
|
use FOF30\Container\Container;
|
||||||
|
use FOF30\Controller\Controller;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for the front-end Check Backups features
|
||||||
|
*/
|
||||||
|
class Check extends Controller
|
||||||
|
{
|
||||||
|
use PredefinedTaskList, FrontEndPermissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overridden constructor
|
||||||
|
*
|
||||||
|
* @param Container $container The application container
|
||||||
|
* @param array $config The configuration array
|
||||||
|
*/
|
||||||
|
public function __construct(Container $container, array $config)
|
||||||
|
{
|
||||||
|
parent::__construct($container, $config);
|
||||||
|
|
||||||
|
$this->setPredefinedTaskList(['main']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for failed backups and sends out any notification emails
|
||||||
|
*/
|
||||||
|
public function main()
|
||||||
|
{
|
||||||
|
// Check permissions
|
||||||
|
$this->checkPermissions();
|
||||||
|
|
||||||
|
/** @var Statistics $model */
|
||||||
|
$model = $this->container->factory->model('Statistics')->tmpInstance();
|
||||||
|
$result = $model->notifyFailed();
|
||||||
|
|
||||||
|
$message = $result['result'] ? '200 ' : '500 ';
|
||||||
|
$message .= implode(', ', $result['message']);
|
||||||
|
|
||||||
|
@ob_end_clean();
|
||||||
|
header('Content-type: text/plain');
|
||||||
|
header('Connection: close');
|
||||||
|
echo $message;
|
||||||
|
flush();
|
||||||
|
|
||||||
|
$this->container->platform->closeApplication();
|
||||||
|
}
|
||||||
|
}
|
||||||
67
deployed/akeeba/components/com_akeeba/Controller/Json.php
Normal file
67
deployed/akeeba/components/com_akeeba/Controller/Json.php
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Controller;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Admin\Controller\Mixin\PredefinedTaskList;
|
||||||
|
use FOF30\Container\Container;
|
||||||
|
use FOF30\Controller\Controller;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for the JSON API
|
||||||
|
*/
|
||||||
|
class Json extends Controller
|
||||||
|
{
|
||||||
|
use PredefinedTaskList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overridden constructor
|
||||||
|
*
|
||||||
|
* @param Container $container The application container
|
||||||
|
* @param array $config The configuration array
|
||||||
|
*/
|
||||||
|
public function __construct(Container $container, array $config)
|
||||||
|
{
|
||||||
|
parent::__construct($container, $config);
|
||||||
|
|
||||||
|
$this->setPredefinedTaskList(['json']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles API calls
|
||||||
|
*/
|
||||||
|
public function json()
|
||||||
|
{
|
||||||
|
// Use the model to parse the JSON message
|
||||||
|
if (function_exists('ob_start'))
|
||||||
|
{
|
||||||
|
@ob_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
$sourceJSON = $this->input->get('json', null, 'raw', 2);
|
||||||
|
|
||||||
|
/** @var \Akeeba\Backup\Site\Model\Json $model */
|
||||||
|
$model = $this->getModel();
|
||||||
|
$json = $model->execute($sourceJSON);
|
||||||
|
|
||||||
|
if (function_exists('ob_end_clean'))
|
||||||
|
{
|
||||||
|
@ob_end_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just dump the JSON and tear down the application, without plugins executing
|
||||||
|
header('Content-type: text/plain');
|
||||||
|
header('Connection: close');
|
||||||
|
echo $json;
|
||||||
|
|
||||||
|
$this->container->platform->closeApplication();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Controller\Mixin;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the method to set the current backup profile from the request variables
|
||||||
|
*/
|
||||||
|
trait ActivateProfile
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Set the active profile from the input parameters
|
||||||
|
*/
|
||||||
|
protected function setProfile()
|
||||||
|
{
|
||||||
|
$profile = $this->input->get('profile', 1, 'int');
|
||||||
|
$profile = max(1, $profile);
|
||||||
|
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile, 'akeeba');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DO NOT REMOVE!
|
||||||
|
*
|
||||||
|
* The Model will only try to load the configuration after nuking the factory. This causes Profile 1 to be
|
||||||
|
* loaded first. Then it figures out it needs to load a different profile and it does – but the protected keys
|
||||||
|
* are NOT replaced, meaning that certain configuration parameters are not replaced. Most notably, the chain.
|
||||||
|
* This causes backups to behave weirdly. So, DON'T REMOVE THIS UNLESS WE REFACTOR THE MODEL.
|
||||||
|
*/
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Controller\Mixin;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the method to send custom HTTP redirection headers
|
||||||
|
*/
|
||||||
|
trait CustomRedirection
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Sends custom HTTP redirection headers
|
||||||
|
*
|
||||||
|
* @param string $url The URL to redirect to
|
||||||
|
* @param string $header The HTTP header to send, default 302 Found
|
||||||
|
*/
|
||||||
|
protected function customRedirect($url, $header = '302 Found')
|
||||||
|
{
|
||||||
|
header('HTTP/1.1 ' . $header);
|
||||||
|
header('Location: ' . $url);
|
||||||
|
header('Content-Type: text/plain');
|
||||||
|
header('Connection: close');
|
||||||
|
|
||||||
|
$this->container->platform->closeApplication();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Controller\Mixin;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
use Akeeba\Engine\Util\Complexify;
|
||||||
|
use JText;
|
||||||
|
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the method to check whether front-end backup is enabled and weather the key is correct
|
||||||
|
*/
|
||||||
|
trait FrontEndPermissions
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check that the user has sufficient permissions to access the front-end backup feature.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function checkPermissions()
|
||||||
|
{
|
||||||
|
// Is frontend backup enabled?
|
||||||
|
$febEnabled = Platform::getInstance()->get_platform_configuration_option('frontend_enable', 0) != 0;
|
||||||
|
|
||||||
|
// Is the Secret Key strong enough?
|
||||||
|
$validKey = Platform::getInstance()->get_platform_configuration_option('frontend_secret_word', '');
|
||||||
|
$validKeyTrim = trim($validKey);
|
||||||
|
|
||||||
|
if (!Complexify::isStrongEnough($validKey, false))
|
||||||
|
{
|
||||||
|
$febEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is the key good?
|
||||||
|
$key = $this->input->get('key', '', 'none', 2);
|
||||||
|
|
||||||
|
if (!$febEnabled || ($key != $validKey) || (empty($validKeyTrim)))
|
||||||
|
{
|
||||||
|
@ob_end_clean();
|
||||||
|
echo '403 ' . JText::_('COM_AKEEBA_COMMON_ERR_NOT_ENABLED');
|
||||||
|
flush();
|
||||||
|
|
||||||
|
$this->container->platform->closeApplication();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
<html><head><title></title></head><body></body></html>
|
||||||
117
deployed/akeeba/components/com_akeeba/Dispatcher/Dispatcher.php
Normal file
117
deployed/akeeba/components/com_akeeba/Dispatcher/Dispatcher.php
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Dispatcher;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Admin\Dispatcher\Dispatcher as AdminDispatcher;
|
||||||
|
use Akeeba\Backup\Admin\Helper\SecretWord;
|
||||||
|
use Akeeba\Engine\Factory;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
use FOF30\Container\Container;
|
||||||
|
use FOF30\Dispatcher\Mixin\ViewAliases;
|
||||||
|
use JFactory;
|
||||||
|
|
||||||
|
class Dispatcher extends AdminDispatcher
|
||||||
|
{
|
||||||
|
/** @var string The name of the default view, in case none is specified */
|
||||||
|
public $defaultView = 'Backup';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatcher constructor. Overridden to set up a different default view and migrated views map than the back-end.
|
||||||
|
*
|
||||||
|
* @param Container $container The component's container
|
||||||
|
* @param array $config Optional configuration overrides
|
||||||
|
*/
|
||||||
|
public function __construct(Container $container, array $config)
|
||||||
|
{
|
||||||
|
parent::__construct($container, $config);
|
||||||
|
|
||||||
|
$this->defaultView = 'Backup';
|
||||||
|
|
||||||
|
$this->viewNameAliases = [
|
||||||
|
'backup' => 'Backup',
|
||||||
|
'backups' => 'Backup',
|
||||||
|
'check' => 'Check',
|
||||||
|
'checks' => 'Check',
|
||||||
|
'json' => 'Json',
|
||||||
|
'jsons' => 'Json',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes before dispatching the request to the appropriate controller
|
||||||
|
*/
|
||||||
|
public function onBeforeDispatch()
|
||||||
|
{
|
||||||
|
$this->onBeforeDispatchViewAliases();
|
||||||
|
|
||||||
|
// Load the FOF language
|
||||||
|
$lang = $this->container->platform->getLanguage();
|
||||||
|
$lang->load('lib_fof30', JPATH_SITE, 'en-GB', true, true);
|
||||||
|
$lang->load('lib_fof30', JPATH_SITE, null, true, false);
|
||||||
|
|
||||||
|
// Necessary defines for Akeeba Engine
|
||||||
|
if ( !defined('AKEEBAENGINE'))
|
||||||
|
{
|
||||||
|
define('AKEEBAENGINE', 1);
|
||||||
|
define('AKEEBAROOT', $this->container->backEndPath . '/BackupEngine');
|
||||||
|
define('ALICEROOT', $this->container->backEndPath . '/AliceEngine');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we have a profile set throughout the component's lifetime
|
||||||
|
$profile_id = $this->container->platform->getSessionVar('profile', null, 'akeeba');
|
||||||
|
|
||||||
|
if (is_null($profile_id))
|
||||||
|
{
|
||||||
|
$this->container->platform->setSessionVar('profile', 1, 'akeeba');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load Akeeba Engine
|
||||||
|
$basePath = $this->container->backEndPath;
|
||||||
|
require_once $basePath . '/BackupEngine/Factory.php';
|
||||||
|
|
||||||
|
// Load the Akeeba Engine configuration
|
||||||
|
Platform::addPlatform('joomla3x', JPATH_COMPONENT_ADMINISTRATOR . '/BackupPlatform/Joomla3x');
|
||||||
|
$akeebaEngineConfig = Factory::getConfiguration();
|
||||||
|
Platform::getInstance()->load_configuration();
|
||||||
|
unset($akeebaEngineConfig);
|
||||||
|
|
||||||
|
// Prevents the "SQLSTATE[HY000]: General error: 2014" due to resource sharing with Akeeba Engine
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// !!!!! WARNING: ALWAYS GO THROUGH JFactory; DO NOT GO THROUGH $this->container->db !!!!!
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
$jDbo = JFactory::getDbo();
|
||||||
|
|
||||||
|
if ($jDbo->name == 'pdomysql')
|
||||||
|
{
|
||||||
|
@JFactory::getDbo()->disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the utils helper library
|
||||||
|
Platform::getInstance()->load_version_defines();
|
||||||
|
|
||||||
|
// Make sure the front-end backup Secret Word is stored encrypted
|
||||||
|
$params = $this->container->params;
|
||||||
|
SecretWord::enforceEncryption($params, 'frontend_secret_word');
|
||||||
|
|
||||||
|
// Make sure we have a version loaded
|
||||||
|
@include_once($this->container->backEndPath . '/version.php');
|
||||||
|
|
||||||
|
if (!defined('AKEEBA_VERSION'))
|
||||||
|
{
|
||||||
|
define('AKEEBA_VERSION', 'dev');
|
||||||
|
define('AKEEBA_DATE', date('Y-m-d'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a media file versioning tag
|
||||||
|
$this->container->mediaVersion = md5(AKEEBA_VERSION . AKEEBA_DATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
15
deployed/akeeba/components/com_akeeba/Model/Backup.php
Normal file
15
deployed/akeeba/components/com_akeeba/Model/Backup.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model;
|
||||||
|
|
||||||
|
use Akeeba\Backup\Admin\Model\Backup as AdminModel;
|
||||||
|
|
||||||
|
class Backup extends AdminModel
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
17
deployed/akeeba/components/com_akeeba/Model/Browser.php
Normal file
17
deployed/akeeba/components/com_akeeba/Model/Browser.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 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\Admin\Model\Browser as AdminModel;
|
||||||
|
|
||||||
|
class Browser extends AdminModel
|
||||||
|
{
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 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\Admin\Model\DatabaseFilters as AdminModel;
|
||||||
|
|
||||||
|
class DatabaseFilters extends AdminModel
|
||||||
|
{
|
||||||
|
}
|
||||||
17
deployed/akeeba/components/com_akeeba/Model/FileFilters.php
Normal file
17
deployed/akeeba/components/com_akeeba/Model/FileFilters.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 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\Admin\Model\FileFilters as AdminModel;
|
||||||
|
|
||||||
|
class FileFilters extends AdminModel
|
||||||
|
{
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 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\Admin\Model\IncludeFolders as AdminModel;
|
||||||
|
|
||||||
|
class IncludeFolders extends AdminModel
|
||||||
|
{
|
||||||
|
}
|
||||||
227
deployed/akeeba/components/com_akeeba/Model/Json.php
Normal file
227
deployed/akeeba/components/com_akeeba/Model/Json.php
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,267 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles data encapsulation
|
||||||
|
*/
|
||||||
|
class Encapsulation
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Known encapsulation handlers
|
||||||
|
*
|
||||||
|
* @var EncapsulationInterface[]
|
||||||
|
*/
|
||||||
|
protected $handlers = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of encapsulation types
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $encapsulations = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server key used to decrypt / encrypt data and check the authorisation
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $serverKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public constructor
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key used for data encyrption/decryption and authorisation checks
|
||||||
|
*/
|
||||||
|
public function __construct($serverKey)
|
||||||
|
{
|
||||||
|
$this->serverKey = $serverKey;
|
||||||
|
|
||||||
|
// Populate the list of encapsulation handlers
|
||||||
|
$this->initialiseHandlers();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the encapsulation ID given its code. For example given $code == 'ENCAPSULATION_AESCTR256' it will return
|
||||||
|
* the ID integer 3.
|
||||||
|
*
|
||||||
|
* @param string $code The encapsulation code, e.g. ENCAPSULATION_AESCTR256
|
||||||
|
*
|
||||||
|
* @return int The numeric ID, e.g. 3
|
||||||
|
*/
|
||||||
|
public function getEncapsulationByCode($code)
|
||||||
|
{
|
||||||
|
$info = $this->getEncapsulationInfoByCode($code);
|
||||||
|
|
||||||
|
return $info['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the encapsulation information array given its code. For example given $code == 'ENCAPSULATION_AESCTR256'
|
||||||
|
* it will return the information for the data in AES-256 stream (CTR) mode encrypted JSON type.
|
||||||
|
*
|
||||||
|
* @param string $code The encapsulation code, e.g. ENCAPSULATION_AESCTR256
|
||||||
|
*
|
||||||
|
* @return array The information of the encapsulation handler
|
||||||
|
*/
|
||||||
|
public function getEncapsulationInfoByCode($code)
|
||||||
|
{
|
||||||
|
// Normalise the code
|
||||||
|
$code = strtoupper($code);
|
||||||
|
|
||||||
|
// If we have no idea what the encapsulation should be revert to raw (plain text)
|
||||||
|
if (!isset($this->encapsulations[$code]))
|
||||||
|
{
|
||||||
|
return $this->encapsulations['ENCAPSULATION_RAW'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->encapsulations[$code];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes the data. For encrypted encapsulations this means base64-decoding the data, decrypting it and then JSON-
|
||||||
|
* decoding the result. If any error occurs along the way the appropriate exception is thrown.
|
||||||
|
*
|
||||||
|
* The data being decoded corresponds to the Request Body described in the API documentation
|
||||||
|
*
|
||||||
|
* @param int $encapsulation The encapsulation type
|
||||||
|
* @param string $data Encoded data
|
||||||
|
*
|
||||||
|
* @return array The decoded data.
|
||||||
|
*
|
||||||
|
* @throw \RuntimeException When the server capabilities don't match the requested encapsulation
|
||||||
|
* @throw \InvalidArgumentException When $data cannot be decoded successfully
|
||||||
|
*
|
||||||
|
* @see https://www.akeebabackup.com/documentation/json-api/ar01s02.html
|
||||||
|
*/
|
||||||
|
public function decode($encapsulation, $data)
|
||||||
|
{
|
||||||
|
$body = null;
|
||||||
|
|
||||||
|
// Find the suitable handler and encode the data
|
||||||
|
foreach ($this->handlers as $handler)
|
||||||
|
{
|
||||||
|
if ($handler->isSupported($encapsulation))
|
||||||
|
{
|
||||||
|
$body = $handler->decode($this->serverKey, $data);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the data cannot be encoded throw an exception
|
||||||
|
if (!isset($handler) || is_null($body))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('The requested encapsulation type is not supported', 503);
|
||||||
|
}
|
||||||
|
|
||||||
|
$authorised = true;
|
||||||
|
$body = rtrim($body, chr(0));
|
||||||
|
|
||||||
|
// Make sure it looks like a valid JSON string and is at least 12 characters (minimum valid message length)
|
||||||
|
if ((strlen($body) < 12) || (substr($body, 0, 1) != '{') || (substr($body, -1) != '}'))
|
||||||
|
{
|
||||||
|
$authorised = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to JSON decode the body
|
||||||
|
if ($authorised)
|
||||||
|
{
|
||||||
|
$body = json_decode($body, true);
|
||||||
|
|
||||||
|
if (is_null($body))
|
||||||
|
{
|
||||||
|
$authorised = false;
|
||||||
|
}
|
||||||
|
elseif (!is_array($body))
|
||||||
|
{
|
||||||
|
$authorised = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure there is a requested method
|
||||||
|
if ($authorised)
|
||||||
|
{
|
||||||
|
if (!isset($body['method']) || empty($body['method']))
|
||||||
|
{
|
||||||
|
$authorised = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($authorised)
|
||||||
|
{
|
||||||
|
$authorised = $handler->isAuthorised($this->serverKey, $body);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$authorised)
|
||||||
|
{
|
||||||
|
throw new \InvalidArgumentException('Authentication failed', 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (array)$body;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes the data. The data is JSON encoded by this method before encapsulation takes place. Encrypted
|
||||||
|
* encapsulations will then encrypt the data and base64-encode it before returning it.
|
||||||
|
*
|
||||||
|
* The data being encoded correspond to the body > data structure described in the API documentation
|
||||||
|
*
|
||||||
|
* @param int $encapsulation The encapsulation type
|
||||||
|
* @param mixed $data The data to encode, typically a string, array or object
|
||||||
|
* @param string $key Key to use for encoding. If not provided we revert to $this->serverKey
|
||||||
|
*
|
||||||
|
* @return string The encapsulated data
|
||||||
|
*
|
||||||
|
* @see https://www.akeebabackup.com/documentation/json-api/ar01s02s02.html
|
||||||
|
*
|
||||||
|
* @throw \RuntimeException When the server capabilities don't match the requested encapsulation
|
||||||
|
* @throw \InvalidArgumentException When $data cannot be converted to JSON
|
||||||
|
*/
|
||||||
|
public function encode($encapsulation, $data, $key = null)
|
||||||
|
{
|
||||||
|
// Try to JSON-encode the data
|
||||||
|
$data = json_encode($data);
|
||||||
|
|
||||||
|
// If the data cannot be JSON-encoded throw an exception
|
||||||
|
if ($data === false)
|
||||||
|
{
|
||||||
|
throw new \InvalidArgumentException('Empty data cannot be encapsulated', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we have a valid key
|
||||||
|
if (empty($key))
|
||||||
|
{
|
||||||
|
$key = $this->serverKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the suitable handler and encode the data
|
||||||
|
foreach ($this->handlers as $handler)
|
||||||
|
{
|
||||||
|
if ($handler->isSupported($encapsulation))
|
||||||
|
{
|
||||||
|
return $handler->encode($key, $data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the data cannot be encoded throw an exception
|
||||||
|
$format = print_r($encapsulation, true);
|
||||||
|
throw new \RuntimeException("Data cannot be encapsulated in the requested format ($format)", 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialises the encapsulation handlers
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function initialiseHandlers()
|
||||||
|
{
|
||||||
|
// Reset the arrays
|
||||||
|
$this->handlers = array();
|
||||||
|
$this->encapsulations = array();
|
||||||
|
|
||||||
|
// Look all files in the Encapsulation handlers' directory
|
||||||
|
$dh = new \DirectoryIterator(__DIR__ . '/Encapsulation');
|
||||||
|
|
||||||
|
/** @var \DirectoryIterator $entry */
|
||||||
|
foreach ($dh as $entry)
|
||||||
|
{
|
||||||
|
$fileName = $entry->getFilename();
|
||||||
|
|
||||||
|
// Ignore non-PHP files
|
||||||
|
if (substr($fileName, -4) != '.php')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore the Base class
|
||||||
|
if ($fileName == 'Base.php')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the class name
|
||||||
|
$className = '\\Akeeba\\Backup\\Site\\Model\\Json\\Encapsulation\\' . substr($fileName, 0, -4);
|
||||||
|
|
||||||
|
// Check if the class really exists
|
||||||
|
if (!class_exists($className, true))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var EncapsulationInterface $o */
|
||||||
|
$o = new $className;
|
||||||
|
$info = $o->getInformation();
|
||||||
|
$this->encapsulations[$info['code']] = $info;
|
||||||
|
$this->handlers[] = $o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Encapsulation;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Engine\Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES CBC 128 encapsulation
|
||||||
|
*/
|
||||||
|
class AesCbc128 extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Constructs the encapsulation handler object
|
||||||
|
*/
|
||||||
|
function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct(4, 'ENCAPSULATION_AESCBC128', ' Data in AES-128 standard (CBC) mode encrypted JSON');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes the data. For encrypted encapsulations this means base64-decoding the data, decrypting it and then JSON-
|
||||||
|
* decoding the result. If any error occurs along the way the appropriate exception is thrown.
|
||||||
|
*
|
||||||
|
* The data being decoded corresponds to the Request Body described in the API documentation
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key we need to decode data
|
||||||
|
* @param string $data Encoded data
|
||||||
|
*
|
||||||
|
* @return string The decoded data.
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When the server capabilities don't match the requested encapsulation
|
||||||
|
* @throws \InvalidArgumentException When $data cannot be decoded successfully
|
||||||
|
*
|
||||||
|
* @see https://www.akeebabackup.com/documentation/json-api/ar01s02.html
|
||||||
|
*/
|
||||||
|
public function decode($serverKey, $data)
|
||||||
|
{
|
||||||
|
$data = base64_decode($data);
|
||||||
|
return $this->getEncryption()->AESDecryptCBC($data, $serverKey, 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes the data. The data is JSON encoded by this method before encapsulation takes place. Encrypted
|
||||||
|
* encapsulations will then encrypt the data and base64-encode it before returning it.
|
||||||
|
*
|
||||||
|
* The data being encoded correspond to the body > data structure described in the API documentation
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key we need to encode data
|
||||||
|
* @param mixed $data The data to encode, typically a string, array or object
|
||||||
|
*
|
||||||
|
* @return string The encapsulated data
|
||||||
|
*
|
||||||
|
* @see https://www.akeebabackup.com/documentation/json-api/ar01s02s02.html
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When the server capabilities don't match the requested encapsulation
|
||||||
|
* @throws \InvalidArgumentException When $data cannot be converted to JSON
|
||||||
|
*/
|
||||||
|
public function encode($serverKey, $data)
|
||||||
|
{
|
||||||
|
return base64_encode($this->getEncryption()->AESEncryptCBC($data, $serverKey, 128));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Encapsulation;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Engine\Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES CBC 256 encapsulation
|
||||||
|
*/
|
||||||
|
class AesCbc256 extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Constructs the encapsulation handler object
|
||||||
|
*/
|
||||||
|
function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct(5, 'ENCAPSULATION_AESCBC256', ' Data in AES-256 standard (CBC) mode encrypted JSON');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes the data. For encrypted encapsulations this means base64-decoding the data, decrypting it and then JSON-
|
||||||
|
* decoding the result. If any error occurs along the way the appropriate exception is thrown.
|
||||||
|
*
|
||||||
|
* The data being decoded corresponds to the Request Body described in the API documentation
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key we need to decode data
|
||||||
|
* @param string $data Encoded data
|
||||||
|
*
|
||||||
|
* @return string The decoded data.
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When the server capabilities don't match the requested encapsulation
|
||||||
|
* @throws \InvalidArgumentException When $data cannot be decoded successfully
|
||||||
|
*
|
||||||
|
* @see https://www.akeebabackup.com/documentation/json-api/ar01s02.html
|
||||||
|
*/
|
||||||
|
public function decode($serverKey, $data)
|
||||||
|
{
|
||||||
|
$data = base64_decode($data);
|
||||||
|
return $this->getEncryption()->AESDecryptCBC($data, $serverKey, 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes the data. The data is JSON encoded by this method before encapsulation takes place. Encrypted
|
||||||
|
* encapsulations will then encrypt the data and base64-encode it before returning it.
|
||||||
|
*
|
||||||
|
* The data being encoded correspond to the body > data structure described in the API documentation
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key we need to encode data
|
||||||
|
* @param mixed $data The data to encode, typically a string, array or object
|
||||||
|
*
|
||||||
|
* @return string The encapsulated data
|
||||||
|
*
|
||||||
|
* @see https://www.akeebabackup.com/documentation/json-api/ar01s02s02.html
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When the server capabilities don't match the requested encapsulation
|
||||||
|
* @throws \InvalidArgumentException When $data cannot be converted to JSON
|
||||||
|
*/
|
||||||
|
public function encode($serverKey, $data)
|
||||||
|
{
|
||||||
|
return base64_encode($this->getEncryption()->AESEncryptCBC($data, $serverKey, 256));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Encapsulation;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Engine\Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES CTR 128 encapsulation
|
||||||
|
*/
|
||||||
|
class AesCtr128 extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Constructs the encapsulation handler object
|
||||||
|
*/
|
||||||
|
function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct(2, 'ENCAPSULATION_AESCTR128', 'Data in AES-128 stream (CTR) mode encrypted JSON');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes the data. For encrypted encapsulations this means base64-decoding the data, decrypting it and then JSON-
|
||||||
|
* decoding the result. If any error occurs along the way the appropriate exception is thrown.
|
||||||
|
*
|
||||||
|
* The data being decoded corresponds to the Request Body described in the API documentation
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key we need to decode data
|
||||||
|
* @param string $data Encoded data
|
||||||
|
*
|
||||||
|
* @return string The decoded data.
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When the server capabilities don't match the requested encapsulation
|
||||||
|
* @throws \InvalidArgumentException When $data cannot be decoded successfully
|
||||||
|
*
|
||||||
|
* @see https://www.akeebabackup.com/documentation/json-api/ar01s02.html
|
||||||
|
*/
|
||||||
|
public function decode($serverKey, $data)
|
||||||
|
{
|
||||||
|
return $this->getEncryption()->AESDecryptCtr($data, $serverKey, 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes the data. The data is JSON encoded by this method before encapsulation takes place. Encrypted
|
||||||
|
* encapsulations will then encrypt the data and base64-encode it before returning it.
|
||||||
|
*
|
||||||
|
* The data being encoded correspond to the body > data structure described in the API documentation
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key we need to encode data
|
||||||
|
* @param mixed $data The data to encode, typically a string, array or object
|
||||||
|
*
|
||||||
|
* @return string The encapsulated data
|
||||||
|
*
|
||||||
|
* @see https://www.akeebabackup.com/documentation/json-api/ar01s02s02.html
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When the server capabilities don't match the requested encapsulation
|
||||||
|
* @throws \InvalidArgumentException When $data cannot be converted to JSON
|
||||||
|
*/
|
||||||
|
public function encode($serverKey, $data)
|
||||||
|
{
|
||||||
|
return $this->getEncryption()->AESEncryptCtr($data, $serverKey, 128);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Encapsulation;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Engine\Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES CTR 256 encapsulation
|
||||||
|
*/
|
||||||
|
class AesCtr256 extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Constructs the encapsulation handler object
|
||||||
|
*/
|
||||||
|
function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct(3, 'ENCAPSULATION_AESCTR256', 'Data in AES-256 stream (CTR) mode encrypted JSON');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes the data. For encrypted encapsulations this means base64-decoding the data, decrypting it and then JSON-
|
||||||
|
* decoding the result. If any error occurs along the way the appropriate exception is thrown.
|
||||||
|
*
|
||||||
|
* The data being decoded corresponds to the Request Body described in the API documentation
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key we need to decode data
|
||||||
|
* @param string $data Encoded data
|
||||||
|
*
|
||||||
|
* @return string The decoded data.
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When the server capabilities don't match the requested encapsulation
|
||||||
|
* @throws \InvalidArgumentException When $data cannot be decoded successfully
|
||||||
|
*
|
||||||
|
* @see https://www.akeebabackup.com/documentation/json-api/ar01s02.html
|
||||||
|
*/
|
||||||
|
public function decode($serverKey, $data)
|
||||||
|
{
|
||||||
|
return $this->getEncryption()->AESDecryptCtr($data, $serverKey, 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes the data. The data is JSON encoded by this method before encapsulation takes place. Encrypted
|
||||||
|
* encapsulations will then encrypt the data and base64-encode it before returning it.
|
||||||
|
*
|
||||||
|
* The data being encoded correspond to the body > data structure described in the API documentation
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key we need to encode data
|
||||||
|
* @param mixed $data The data to encode, typically a string, array or object
|
||||||
|
*
|
||||||
|
* @return string The encapsulated data
|
||||||
|
*
|
||||||
|
* @see https://www.akeebabackup.com/documentation/json-api/ar01s02s02.html
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When the server capabilities don't match the requested encapsulation
|
||||||
|
* @throws \InvalidArgumentException When $data cannot be converted to JSON
|
||||||
|
*/
|
||||||
|
public function encode($serverKey, $data)
|
||||||
|
{
|
||||||
|
return $this->getEncryption()->AESEncryptCtr($data, $serverKey, 256);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,165 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Encapsulation;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\Json\EncapsulationInterface;
|
||||||
|
use Akeeba\Engine\Factory;
|
||||||
|
use Akeeba\Engine\Util\Encrypt;
|
||||||
|
|
||||||
|
abstract class Base implements EncapsulationInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The numeric ID of this encapsulation
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $id = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The code of this encapsulation
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $code = 'ENCAPSULATION_VOID';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The description of this encapsulation
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Invalid encapsulation';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The encryption object which is set up for use with the JSON API
|
||||||
|
*
|
||||||
|
* @var Encrypt
|
||||||
|
*/
|
||||||
|
private $encryption;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public constructor. Called by children to customise the encapsulation handler object
|
||||||
|
*
|
||||||
|
* @param int $id Numeric ID
|
||||||
|
* @param string $code Code
|
||||||
|
* @param string $description Human readable description
|
||||||
|
*/
|
||||||
|
function __construct($id, $code, $description)
|
||||||
|
{
|
||||||
|
$this->id = $id;
|
||||||
|
$this->code = strtoupper($code);
|
||||||
|
$this->description = $description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns information about the encapsulation supported by this class. The return array has the following keys:
|
||||||
|
* id: The numeric ID of the encapsulation, e.g. 3
|
||||||
|
* code: The short code of the encapsulation, e.g. ENCAPSULATION_AESCTR256
|
||||||
|
* description: A human readable descriptions, e.g. "Data in AES-256 stream (CTR) mode encrypted JSON"
|
||||||
|
*
|
||||||
|
* @return array See above
|
||||||
|
*/
|
||||||
|
public function getInformation()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'id' => $this->id,
|
||||||
|
'code' => $this->code,
|
||||||
|
'description' => $this->description,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the request body authorises the user to use the API. Each encapsulation can implement its own
|
||||||
|
* authorisation method. This method is only called after the request body has been successfully decoded, therefore
|
||||||
|
* encrypted encapsulations can simply return true.
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key we need to check the authorisation
|
||||||
|
* @param array $body The decoded body (as returned by the decode() method)
|
||||||
|
*
|
||||||
|
* @return bool True if authorised
|
||||||
|
*/
|
||||||
|
public function isAuthorised($serverKey, $body)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the provided encapsulation type supported by this class?
|
||||||
|
*
|
||||||
|
* @param int $encapsulation Encapsulation type
|
||||||
|
*
|
||||||
|
* @return bool True if supported
|
||||||
|
*/
|
||||||
|
public function isSupported($encapsulation)
|
||||||
|
{
|
||||||
|
return $encapsulation == $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes the data. For encrypted encapsulations this means base64-decoding the data, decrypting it and then JSON-
|
||||||
|
* decoding the result. If any error occurs along the way the appropriate exception is thrown.
|
||||||
|
*
|
||||||
|
* The data being decoded corresponds to the Request Body described in the API documentation
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key we need to decode data
|
||||||
|
* @param string $data Encoded data
|
||||||
|
*
|
||||||
|
* @return string The decoded data.
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When the server capabilities don't match the requested encapsulation
|
||||||
|
* @throws \InvalidArgumentException When $data cannot be decoded successfully
|
||||||
|
*
|
||||||
|
* @see https://www.akeebabackup.com/documentation/json-api/ar01s02.html
|
||||||
|
*/
|
||||||
|
public function decode($serverKey, $data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes the data. The data is JSON encoded by this method before encapsulation takes place. Encrypted
|
||||||
|
* encapsulations will then encrypt the data and base64-encode it before returning it.
|
||||||
|
*
|
||||||
|
* The data being encoded correspond to the body > data structure described in the API documentation
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key we need to encode data
|
||||||
|
* @param mixed $data The data to encode, typically a string, array or object
|
||||||
|
*
|
||||||
|
* @return string The encapsulated data
|
||||||
|
*
|
||||||
|
* @see https://www.akeebabackup.com/documentation/json-api/ar01s02s02.html
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When the server capabilities don't match the requested encapsulation
|
||||||
|
* @throws \InvalidArgumentException When $data cannot be converted to JSON
|
||||||
|
*/
|
||||||
|
public function encode($serverKey, $data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an encryption object normalized for use in the JSON API: PBKDF2 uses a dynamic salt with SHA1 algorithm.
|
||||||
|
* This is necessary when we are running a backup against a profile which uses a static salt. In this case the
|
||||||
|
* static salt is not included in the ciphertext, making it impossible for the remote side to decipher our message,
|
||||||
|
* leading to backup failure.
|
||||||
|
*
|
||||||
|
* @return Encrypt
|
||||||
|
*/
|
||||||
|
protected function getEncryption()
|
||||||
|
{
|
||||||
|
if (is_null($this->encryption))
|
||||||
|
{
|
||||||
|
$encryption = Factory::getEncryption();
|
||||||
|
$this->encryption = clone $encryption;
|
||||||
|
$this->encryption->setPbkdf2UseStaticSalt(false);
|
||||||
|
$this->encryption->setPbkdf2Algorithm('sha1');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->encryption;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,92 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Encapsulation;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Raw (plain text) encapsulation
|
||||||
|
*/
|
||||||
|
class Raw extends Base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Constructs the encapsulation handler object
|
||||||
|
*/
|
||||||
|
function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct(1, 'ENCAPSULATION_RAW', 'Data in plain-text JSON');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes the data. For encrypted encapsulations this means base64-decoding the data, decrypting it and then JSON-
|
||||||
|
* decoding the result. If any error occurs along the way the appropriate exception is thrown.
|
||||||
|
*
|
||||||
|
* The data being decoded corresponds to the Request Body described in the API documentation
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key we need to decode data
|
||||||
|
* @param string $data Encoded data
|
||||||
|
*
|
||||||
|
* @return string The decoded data.
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When the server capabilities don't match the requested encapsulation
|
||||||
|
* @throws \InvalidArgumentException When $data cannot be decoded successfully
|
||||||
|
*
|
||||||
|
* @see https://www.akeebabackup.com/documentation/json-api/ar01s02.html
|
||||||
|
*/
|
||||||
|
public function decode($serverKey, $data)
|
||||||
|
{
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes the data. The data is JSON encoded by this method before encapsulation takes place. Encrypted
|
||||||
|
* encapsulations will then encrypt the data and base64-encode it before returning it.
|
||||||
|
*
|
||||||
|
* The data being encoded correspond to the body > data structure described in the API documentation
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key we need to encode data
|
||||||
|
* @param mixed $data The data to encode, typically a string, array or object
|
||||||
|
*
|
||||||
|
* @return string The encapsulated data
|
||||||
|
*
|
||||||
|
* @see https://www.akeebabackup.com/documentation/json-api/ar01s02s02.html
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When the server capabilities don't match the requested encapsulation
|
||||||
|
* @throws \InvalidArgumentException When $data cannot be converted to JSON
|
||||||
|
*/
|
||||||
|
public function encode($serverKey, $data)
|
||||||
|
{
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the request body authorises the user to use the API. Each encapsulation can implement its own
|
||||||
|
* authorisation method. This method is only called after the request body has been successfully decoded, therefore
|
||||||
|
* encrypted encapsulations can simply return true.
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key we need to check the authorisation
|
||||||
|
* @param array $body The decoded body (as returned by the decode() method)
|
||||||
|
*
|
||||||
|
* @return bool True if authorised
|
||||||
|
*/
|
||||||
|
public function isAuthorised($serverKey, $body)
|
||||||
|
{
|
||||||
|
$authenticated = false;
|
||||||
|
|
||||||
|
if (isset($body['challenge']) && (strpos($body['challenge'], ':') >= 2) && (strlen($body['challenge']) >= 3))
|
||||||
|
{
|
||||||
|
list ($challengeData, $providedHash) = explode(':', $body['challenge']);
|
||||||
|
$computedHash = strtolower(md5($challengeData . $serverKey));
|
||||||
|
$authenticated = ($computedHash == $providedHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $authenticated;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for Encapsulation data handlers
|
||||||
|
*/
|
||||||
|
interface EncapsulationInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Is the provided encapsulation type supported by this class?
|
||||||
|
*
|
||||||
|
* @param int $encapsulation Encapsulation type
|
||||||
|
*
|
||||||
|
* @return bool True if supported
|
||||||
|
*/
|
||||||
|
public function isSupported($encapsulation);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns information about the encapsulation supported by this class. The return array has the following keys:
|
||||||
|
* id: The numeric ID of the encapsulation, e.g. 3
|
||||||
|
* code: The short code of the encapsulation, e.g. ENCAPSULATION_AESCTR256
|
||||||
|
* description: A human readable descriptions, e.g. "Data in AES-256 stream (CTR) mode encrypted JSON"
|
||||||
|
*
|
||||||
|
* @return array See above
|
||||||
|
*/
|
||||||
|
public function getInformation();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decodes the data. For encrypted encapsulations this means base64-decoding the data, decrypting it but *NOT* JSON-
|
||||||
|
* decoding the result. If any error occurs along the way the appropriate exception is thrown.
|
||||||
|
*
|
||||||
|
* The data being decoded corresponds to the Request Body described in the API documentation
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key we need to decode data
|
||||||
|
* @param string $data Encoded data
|
||||||
|
*
|
||||||
|
* @return string The decoded data.
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When the server capabilities don't match the requested encapsulation
|
||||||
|
* @throws \InvalidArgumentException When $data cannot be decoded successfully
|
||||||
|
*
|
||||||
|
* @see https://www.akeebabackup.com/documentation/json-api/ar01s02.html
|
||||||
|
*/
|
||||||
|
public function decode($serverKey, $data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes the data. The data is JSON encoded by this method before encapsulation takes place. Encrypted
|
||||||
|
* encapsulations will then encrypt the data and base64-encode it before returning it.
|
||||||
|
*
|
||||||
|
* The data being encoded correspond to the body > data structure described in the API documentation
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key we need to encode data
|
||||||
|
* @param mixed $data The data to encode, typically a string, array or object
|
||||||
|
*
|
||||||
|
* @return string The encapsulated data
|
||||||
|
*
|
||||||
|
* @see https://www.akeebabackup.com/documentation/json-api/ar01s02s02.html
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When the server capabilities don't match the requested encapsulation
|
||||||
|
* @throws \InvalidArgumentException When $data cannot be converted to JSON
|
||||||
|
*/
|
||||||
|
public function encode($serverKey, $data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the request body authorises the user to use the API. Each encapsulation can implement its own
|
||||||
|
* authorisation method. This method is only called after the request body has been successfully decoded, therefore
|
||||||
|
* encrypted encapsulations can simply return true.
|
||||||
|
*
|
||||||
|
* @param string $serverKey The server key we need to check the authorisation
|
||||||
|
* @param array $body The decoded body (as returned by the decode() method)
|
||||||
|
*
|
||||||
|
* @return bool True if authorised
|
||||||
|
*/
|
||||||
|
public function isAuthorised($serverKey, $body);
|
||||||
|
}
|
||||||
124
deployed/akeeba/components/com_akeeba/Model/Json/Task.php
Normal file
124
deployed/akeeba/components/com_akeeba/Model/Json/Task.php
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use FOF30\Container\Container;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles task execution
|
||||||
|
*/
|
||||||
|
class Task
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The component's container
|
||||||
|
*
|
||||||
|
* @var Container
|
||||||
|
*/
|
||||||
|
protected $container = null;
|
||||||
|
|
||||||
|
/** @var TaskInterface[] The task handlers known to us */
|
||||||
|
protected $handlers = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public constructor. Populates the list of task handlers.
|
||||||
|
*/
|
||||||
|
public function __construct(Container $container)
|
||||||
|
{
|
||||||
|
$this->container = $container;
|
||||||
|
|
||||||
|
// Populate the list of task handlers
|
||||||
|
$this->initialiseHandlers();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do I have a specific task handling method?
|
||||||
|
*
|
||||||
|
* @param string $method The method to check for
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasMethod($method)
|
||||||
|
{
|
||||||
|
$method = strtolower($method);
|
||||||
|
|
||||||
|
return isset($this->handlers[$method]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute a JSON API method
|
||||||
|
*
|
||||||
|
* @param string $method The method's name
|
||||||
|
* @param array $parameters The parameters to the method (optional)
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When the method requested is not known to us
|
||||||
|
*/
|
||||||
|
public function execute($method, $parameters = array())
|
||||||
|
{
|
||||||
|
if (!$this->hasMethod($method))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException("Invalid method $method", 405);
|
||||||
|
}
|
||||||
|
|
||||||
|
$method = strtolower($method);
|
||||||
|
|
||||||
|
return $this->handlers[$method]->execute($parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialises the encapsulation handlers
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function initialiseHandlers()
|
||||||
|
{
|
||||||
|
// Reset the array
|
||||||
|
$this->handlers = array();
|
||||||
|
|
||||||
|
// Look all files in the Task handlers' directory
|
||||||
|
$dh = new \DirectoryIterator(__DIR__ . '/Task');
|
||||||
|
|
||||||
|
/** @var \DirectoryIterator $entry */
|
||||||
|
foreach ($dh as $entry)
|
||||||
|
{
|
||||||
|
$fileName = $entry->getFilename();
|
||||||
|
|
||||||
|
// Ignore non-PHP files
|
||||||
|
if (substr($fileName, -4) != '.php')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore the Base class
|
||||||
|
if ($fileName == 'AbstractTask.php')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the class name
|
||||||
|
$className = '\\Akeeba\\Backup\\Site\\Model\\Json\\Task\\' . substr($fileName, 0, -4);
|
||||||
|
|
||||||
|
// Check if the class really exists
|
||||||
|
if (!class_exists($className, true))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var TaskInterface $o */
|
||||||
|
$o = new $className($this->container);
|
||||||
|
$name = $o->getMethodName();
|
||||||
|
$name = strtolower($name);
|
||||||
|
$this->handlers[$name] = $o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
use Akeeba\Backup\Site\Model\Json\TaskInterface;
|
||||||
|
use FOF30\Container\Container;
|
||||||
|
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
class AbstractTask implements TaskInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The container of the component we belong to
|
||||||
|
*
|
||||||
|
* @var Container
|
||||||
|
*/
|
||||||
|
protected $container = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The method name
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $methodName = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public constructor
|
||||||
|
*
|
||||||
|
* @param Container $container The container of the component we belong to
|
||||||
|
*/
|
||||||
|
public function __construct(Container $container)
|
||||||
|
{
|
||||||
|
$this->container = $container;
|
||||||
|
|
||||||
|
$path = explode('\\', get_class($this));
|
||||||
|
$shortName = array_pop($path);
|
||||||
|
$this->methodName = lcfirst($shortName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the JSON API task's name ("method" name). Remote clients will use it to call us.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getMethodName()
|
||||||
|
{
|
||||||
|
return $this->methodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
throw new \LogicException(__CLASS__ . ' has not implemented its execute() method yet.');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\Browser;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return folder browser results
|
||||||
|
*/
|
||||||
|
class Browse extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'folder' => '',
|
||||||
|
'processfolder' => 0
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$folder = $filter->clean($defConfig['folder'], 'string');
|
||||||
|
$processFolder = $filter->clean($defConfig['processfolder'], 'bool');
|
||||||
|
|
||||||
|
/** @var Browser $model */
|
||||||
|
$model = $this->container->factory->model('Browser')->tmpInstance();
|
||||||
|
$model->setState('folder', $folder);
|
||||||
|
$model->setState('processfolder', $processFolder);
|
||||||
|
$model->makeListing();
|
||||||
|
|
||||||
|
$ret = array(
|
||||||
|
'folder' => $model->getState('folder'),
|
||||||
|
'folder_raw' => $model->getState('folder_raw'),
|
||||||
|
'parent' => $model->getState('parent'),
|
||||||
|
'exists' => $model->getState('exists'),
|
||||||
|
'inRoot' => $model->getState('inRoot'),
|
||||||
|
'openbasedirRestricted' => $model->getState('openbasedirRestricted'),
|
||||||
|
'writable' => $model->getState('writable'),
|
||||||
|
'subfolders' => $model->getState('subfolders'),
|
||||||
|
'breadcrumbs' => $model->getState('breadcrumbs'),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\Statistics;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a backup record
|
||||||
|
*/
|
||||||
|
class Delete extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'backup_id' => 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$backup_id = (int)$defConfig['backup_id'];
|
||||||
|
|
||||||
|
/** @var Statistics $model */
|
||||||
|
$model = $this->container->factory->model('Statistics')->tmpInstance();
|
||||||
|
$model->setState('id', $backup_id);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$model->delete();
|
||||||
|
}
|
||||||
|
catch (\Exception $e)
|
||||||
|
{
|
||||||
|
throw new \RuntimeException($e->getMessage(), 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\Statistics;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete the backup archives of a backup record
|
||||||
|
*/
|
||||||
|
class DeleteFiles extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'backup_id' => 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$backup_id = (int)$defConfig['backup_id'];
|
||||||
|
|
||||||
|
/** @var Statistics $model */
|
||||||
|
$model = $this->container->factory->model('Statistics')->tmpInstance();
|
||||||
|
$model->setState('id', $backup_id);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$model->deleteFile();
|
||||||
|
}
|
||||||
|
catch (\Exception $e)
|
||||||
|
{
|
||||||
|
throw new \RuntimeException($e->getMessage(), 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\Profiles;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a backup profile
|
||||||
|
*/
|
||||||
|
class DeleteProfile extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = (int)$defConfig['profile'];
|
||||||
|
|
||||||
|
// You need to specify the profile
|
||||||
|
if (empty($profile))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Invalid profile ID', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($profile == 1)
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('You cannot delete the default backup profile', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a profile model
|
||||||
|
/** @var Profiles $profileModel */
|
||||||
|
$profileModel = $this->container->factory->model('Profiles')->tmpInstance();
|
||||||
|
$profileModel->findOrFail($profile);
|
||||||
|
$profileModel->delete();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,101 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Engine\Factory;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download a chunk of a backup archive over HTTP
|
||||||
|
*/
|
||||||
|
class Download extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'backup_id' => 0,
|
||||||
|
'part_id' => 1,
|
||||||
|
'segment' => 1,
|
||||||
|
'chunk_size' => 1
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$backup_id = (int)$defConfig['backup_id'];
|
||||||
|
$part_id = (int)$defConfig['part_id'];
|
||||||
|
$segment = (int)$defConfig['segment'];
|
||||||
|
$chunk_size = (int)$defConfig['chunk_size'];
|
||||||
|
|
||||||
|
$backup_stats = Platform::getInstance()->get_statistics($backup_id);
|
||||||
|
|
||||||
|
if (empty($backup_stats))
|
||||||
|
{
|
||||||
|
// Backup record doesn't exist
|
||||||
|
throw new \RuntimeException('Invalid backup record identifier', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
$files = Factory::getStatistics()->get_all_filenames($backup_stats);
|
||||||
|
|
||||||
|
if ((count($files) < $part_id) || ($part_id <= 0))
|
||||||
|
{
|
||||||
|
// Invalid part
|
||||||
|
throw new \RuntimeException('Invalid backup part', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $files[ $part_id - 1 ];
|
||||||
|
|
||||||
|
$filesize = @filesize($file);
|
||||||
|
$seekPos = $chunk_size * 1048576 * ($segment - 1);
|
||||||
|
|
||||||
|
if ($seekPos > $filesize)
|
||||||
|
{
|
||||||
|
// Trying to seek past end of file
|
||||||
|
throw new \RuntimeException('Invalid segment', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
$fp = fopen($file, 'rb');
|
||||||
|
|
||||||
|
if ($fp === false)
|
||||||
|
{
|
||||||
|
// Could not read file
|
||||||
|
throw new \RuntimeException('Error reading backup archive', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
rewind($fp);
|
||||||
|
if (fseek($fp, $seekPos, SEEK_SET) === -1)
|
||||||
|
{
|
||||||
|
// Could not seek to position
|
||||||
|
throw new \RuntimeException('Error reading specified segment', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
$buffer = fread($fp, 1048576);
|
||||||
|
|
||||||
|
if ($buffer === false)
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Error reading specified segment', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose($fp);
|
||||||
|
|
||||||
|
return base64_encode($buffer);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,161 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Engine\Factory;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download an entire backup archive directly over HTTP
|
||||||
|
*/
|
||||||
|
class DownloadDirect extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'backup_id' => 0,
|
||||||
|
'part_id' => 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$backup_id = (int)$defConfig['backup_id'];
|
||||||
|
$part_id = (int)$defConfig['part_id'];
|
||||||
|
|
||||||
|
$backup_stats = Platform::getInstance()->get_statistics($backup_id);
|
||||||
|
|
||||||
|
if (empty($backup_stats))
|
||||||
|
{
|
||||||
|
// Backup record doesn't exist
|
||||||
|
@ob_end_clean();
|
||||||
|
header('HTTP/1.1 500 Invalid backup record identifier');
|
||||||
|
flush();
|
||||||
|
|
||||||
|
$this->container->platform->closeApplication();
|
||||||
|
}
|
||||||
|
|
||||||
|
$files = Factory::getStatistics()->get_all_filenames($backup_stats);
|
||||||
|
|
||||||
|
if ((count($files) < $part_id) || ($part_id <= 0))
|
||||||
|
{
|
||||||
|
// Invalid part
|
||||||
|
@ob_end_clean();
|
||||||
|
header('HTTP/1.1 500 Invalid backup part');
|
||||||
|
flush();
|
||||||
|
|
||||||
|
$this->container->platform->closeApplication();
|
||||||
|
}
|
||||||
|
|
||||||
|
$filename = $files[ $part_id - 1 ];
|
||||||
|
@clearstatcache();
|
||||||
|
|
||||||
|
// For a certain unmentionable browser
|
||||||
|
if (function_exists('ini_get') && function_exists('ini_set'))
|
||||||
|
{
|
||||||
|
if (ini_get('zlib.output_compression'))
|
||||||
|
{
|
||||||
|
ini_set('zlib.output_compression', 'Off');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove php's time limit
|
||||||
|
if (function_exists('ini_get') && function_exists('set_time_limit'))
|
||||||
|
{
|
||||||
|
if (!ini_get('safe_mode'))
|
||||||
|
{
|
||||||
|
@set_time_limit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$basename = @basename($filename);
|
||||||
|
$fileSize = @filesize($filename);
|
||||||
|
$extension = strtolower(str_replace(".", "", strrchr($filename, ".")));
|
||||||
|
|
||||||
|
while (@ob_end_clean())
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
@clearstatcache();
|
||||||
|
// Send MIME headers
|
||||||
|
header('MIME-Version: 1.0');
|
||||||
|
header('Content-Disposition: attachment; filename="' . $basename . '"');
|
||||||
|
header('Content-Transfer-Encoding: binary');
|
||||||
|
header('Accept-Ranges: bytes');
|
||||||
|
|
||||||
|
switch ($extension)
|
||||||
|
{
|
||||||
|
case 'zip':
|
||||||
|
// ZIP MIME type
|
||||||
|
header('Content-Type: application/zip');
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Generic binary data MIME type
|
||||||
|
header('Content-Type: application/octet-stream');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify of file size, if this info is available
|
||||||
|
if ($fileSize > 0)
|
||||||
|
{
|
||||||
|
header('Content-Length: ' . @filesize($filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable caching
|
||||||
|
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
|
||||||
|
header("Expires: 0");
|
||||||
|
header('Pragma: no-cache');
|
||||||
|
flush();
|
||||||
|
|
||||||
|
if ($fileSize > 0)
|
||||||
|
{
|
||||||
|
// If the filesize is reported, use 1M chunks for echoing the data to the browser
|
||||||
|
$blockSize = 1048576; //1M chunks
|
||||||
|
$handle = @fopen($filename, "r");
|
||||||
|
|
||||||
|
// Now we need to loop through the file and echo out chunks of file data
|
||||||
|
if ($handle !== false)
|
||||||
|
{
|
||||||
|
while (!@feof($handle))
|
||||||
|
{
|
||||||
|
echo @fread($handle, $blockSize);
|
||||||
|
@ob_flush();
|
||||||
|
flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($handle !== false)
|
||||||
|
{
|
||||||
|
@fclose($handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If the filesize is not reported, hope that readfile works
|
||||||
|
@readfile($filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
flush();
|
||||||
|
|
||||||
|
$this->container->platform->closeApplication();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\Profiles;
|
||||||
|
use Akeeba\Engine\Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export the profile's configuration
|
||||||
|
*/
|
||||||
|
class ExportConfiguration extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile_id = (int)$defConfig['profile'];
|
||||||
|
|
||||||
|
if ($profile_id <= 0)
|
||||||
|
{
|
||||||
|
$profile_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var Profiles $profile */
|
||||||
|
$profile = $this->container->factory->model('Profiles')->tmpInstance();
|
||||||
|
|
||||||
|
$data = $profile->findOrFail($profile_id)->getData();
|
||||||
|
|
||||||
|
if (substr($data['configuration'], 0, 12) == '###AES128###')
|
||||||
|
{
|
||||||
|
// Load the server key file if necessary
|
||||||
|
if (!defined('AKEEBA_SERVERKEY'))
|
||||||
|
{
|
||||||
|
$filename = JPATH_COMPONENT_ADMINISTRATOR . '/BackupEngine/serverkey.php';
|
||||||
|
|
||||||
|
include_once $filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
$key = Factory::getSecureSettings()->getKey();
|
||||||
|
|
||||||
|
$data['configuration'] = Factory::getSecureSettings()->decryptSettings($data['configuration'], $key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'description' => $data['description'],
|
||||||
|
'configuration' => $data['configuration'],
|
||||||
|
'filters' => $data['filters'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Engine\Factory;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get information for a given backup record
|
||||||
|
*/
|
||||||
|
class GetBackupInfo extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'backup_id' => 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$backup_id = (int)$defConfig['backup_id'];
|
||||||
|
|
||||||
|
// Get the basic statistics
|
||||||
|
$record = Platform::getInstance()->get_statistics($backup_id);
|
||||||
|
|
||||||
|
// Get a list of filenames
|
||||||
|
$backup_stats = Platform::getInstance()->get_statistics($backup_id);
|
||||||
|
|
||||||
|
// Backup record doesn't exist
|
||||||
|
if (empty($backup_stats))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Invalid backup record identifier', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
$filenames = Factory::getStatistics()->get_all_filenames($record);
|
||||||
|
|
||||||
|
if (empty($filenames))
|
||||||
|
{
|
||||||
|
// Archives are not stored on the server or no files produced
|
||||||
|
$record['filenames'] = array();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$filedata = array();
|
||||||
|
$i = 0;
|
||||||
|
|
||||||
|
// Get file sizes per part
|
||||||
|
foreach ($filenames as $file)
|
||||||
|
{
|
||||||
|
$i++;
|
||||||
|
$size = @filesize($file);
|
||||||
|
$size = is_numeric($size) ? $size : 0;
|
||||||
|
$filedata[] = array(
|
||||||
|
'part' => $i,
|
||||||
|
'name' => basename($file),
|
||||||
|
'size' => $size
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the file info to $record['filenames']
|
||||||
|
$record['filenames'] = $filedata;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $record;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\DatabaseFilters;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the database entities along with their filtering status (typically for rendering a GUI)
|
||||||
|
*/
|
||||||
|
class GetDBEntities extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
'root' => '[SITEDB]',
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = $filter->clean($defConfig['profile'], 'int');
|
||||||
|
$root = $filter->clean($defConfig['root'], 'string');
|
||||||
|
|
||||||
|
// We need a valid profile ID
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a root
|
||||||
|
if (empty($root))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Unknown database root', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var DatabaseFilters $model */
|
||||||
|
$model = $this->container->factory->model('DatabaseFilters')->tmpInstance();
|
||||||
|
|
||||||
|
return $model->make_listing($root);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\DatabaseFilters;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the database filters
|
||||||
|
*/
|
||||||
|
class GetDBFilters extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
'root' => '[SITEDB]',
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = $filter->clean($defConfig['profile'], 'int');
|
||||||
|
$root = $filter->clean($defConfig['root'], 'string');
|
||||||
|
|
||||||
|
// We need a valid profile ID
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a root
|
||||||
|
if (empty($root))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Unknown database root', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var DatabaseFilters $model */
|
||||||
|
$model = $this->container->factory->model('DatabaseFilters')->tmpInstance();
|
||||||
|
|
||||||
|
return $model->get_filters($root);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\DatabaseFilters;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the database roots (database definitions)
|
||||||
|
*/
|
||||||
|
class GetDBRoots extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = (int)$defConfig['profile'];
|
||||||
|
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var DatabaseFilters $model */
|
||||||
|
$model = $this->container->factory->model('DatabaseFilters')->tmpInstance();
|
||||||
|
|
||||||
|
return $model->get_roots();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,82 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\FileFilters;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the filesystem entities along with their filtering status (typically for rendering a GUI)
|
||||||
|
*/
|
||||||
|
class GetFSEntities extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
'root' => '[SITEROOT]',
|
||||||
|
'subdirectory' => '',
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = $filter->clean($defConfig['profile'], 'int');
|
||||||
|
$root = $filter->clean($defConfig['root'], 'string');
|
||||||
|
$subdirectory = $filter->clean($defConfig['subdirectory'], 'path');
|
||||||
|
$crumbs = array();
|
||||||
|
|
||||||
|
// We need a valid profile ID
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a root
|
||||||
|
if (empty($root))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Unknown filesystem root', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the subdirectory and explode it to its parts
|
||||||
|
if (!empty($subdirectory))
|
||||||
|
{
|
||||||
|
$subdirectory = trim($subdirectory, '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($subdirectory))
|
||||||
|
{
|
||||||
|
$crumbs = explode('/', $subdirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the active profile
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var FileFilters $model */
|
||||||
|
$model = $this->container->factory->model('FileFilters')->tmpInstance();
|
||||||
|
|
||||||
|
return $model->make_listing($root, $crumbs);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\FileFilters;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the filesystem filters
|
||||||
|
*/
|
||||||
|
class GetFSFilters extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
'root' => '[SITEROOT]',
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = $filter->clean($defConfig['profile'], 'int');
|
||||||
|
$root = $filter->clean($defConfig['root'], 'string');
|
||||||
|
|
||||||
|
// We need a valid profile ID
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a root
|
||||||
|
if (empty($root))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Unknown filesystem root', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the active profile
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var FileFilters $model */
|
||||||
|
$model = $this->container->factory->model('FileFilters')->tmpInstance();
|
||||||
|
|
||||||
|
return $model->get_filters($root);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\FileFilters;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the filesystem roots (site root and extra included directories)
|
||||||
|
*/
|
||||||
|
class GetFSRoots extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = (int)$defConfig['profile'];
|
||||||
|
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the active profile
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var FileFilters $model */
|
||||||
|
$model = $this->container->factory->model('FileFilters')->tmpInstance();
|
||||||
|
|
||||||
|
return $model->get_roots();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Engine\Factory;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the GUI definitions for the configuration page
|
||||||
|
*/
|
||||||
|
class GetGUIConfiguration extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = (int)$defConfig['profile'];
|
||||||
|
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the active profile
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
return Factory::getEngineParamsProvider()->getJsonGuiDefinition();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\MultipleDatabases;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the extra included databases
|
||||||
|
*/
|
||||||
|
class GetIncludedDBs extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = (int)$defConfig['profile'];
|
||||||
|
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the active profile
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var MultipleDatabases $model */
|
||||||
|
$model = $this->container->factory->model('MultipleDatabases')->tmpInstance();
|
||||||
|
|
||||||
|
return $model->get_databases();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\IncludeFolders;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the extra included directories
|
||||||
|
*/
|
||||||
|
class GetIncludedDirectories extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = (int)$defConfig['profile'];
|
||||||
|
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the active profile
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var IncludeFolders $model */
|
||||||
|
$model = $this->container->factory->model('IncludeFolders')->tmpInstance();
|
||||||
|
|
||||||
|
return $model->get_directories();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\Profiles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of known backup profiles
|
||||||
|
*/
|
||||||
|
class GetProfiles extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
/** @var Profiles $model */
|
||||||
|
$model = $this->container->factory->model('Profiles')->tmpInstance();
|
||||||
|
|
||||||
|
$profiles = $model->get(true);
|
||||||
|
$ret = array();
|
||||||
|
|
||||||
|
if (count($profiles))
|
||||||
|
{
|
||||||
|
foreach ($profiles as $profile)
|
||||||
|
{
|
||||||
|
$temp = new \stdClass();
|
||||||
|
$temp->id = $profile->id;
|
||||||
|
$temp->name = $profile->description;
|
||||||
|
$ret[] = $temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\RegExDatabaseFilters;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the regex database filters
|
||||||
|
*/
|
||||||
|
class GetRegexDBFilters extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
'root' => '[SITEDB]',
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = $filter->clean($defConfig['profile'], 'int');
|
||||||
|
$root = $filter->clean($defConfig['root'], 'string');
|
||||||
|
|
||||||
|
// We need a valid profile ID
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a root
|
||||||
|
if (empty($root))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Unknown database root', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the active profile
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var RegExDatabaseFilters $model */
|
||||||
|
$model = $this->container->factory->model('RegExDatabaseFilters')->tmpInstance();
|
||||||
|
|
||||||
|
return $model->get_regex_filters($root);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\RegExFileFilters;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the regex filesystem filters
|
||||||
|
*/
|
||||||
|
class GetRegexFSFilters extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
'root' => '[SITEROOT]',
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = $filter->clean($defConfig['profile'], 'int');
|
||||||
|
$root = $filter->clean($defConfig['root'], 'string');
|
||||||
|
|
||||||
|
// We need a valid profile ID
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a root
|
||||||
|
if (empty($root))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Unknown database root', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the active profile
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var RegExFileFilters $model */
|
||||||
|
$model = $this->container->factory->model('RegExFileFilters')->tmpInstance();
|
||||||
|
|
||||||
|
return $model->get_regex_filters($root);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\Updates;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the version information of Akeeba Backup
|
||||||
|
*/
|
||||||
|
class GetVersion extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
/** @var Updates $model */
|
||||||
|
$model = $this->container->factory->model('Updates')->tmpInstance();
|
||||||
|
|
||||||
|
$updateInformation = $model->getUpdates();
|
||||||
|
|
||||||
|
$edition = AKEEBA_PRO ? 'pro' : 'core';
|
||||||
|
|
||||||
|
return (object)array(
|
||||||
|
'api' => AKEEBA_JSON_API_VERSION,
|
||||||
|
'component' => AKEEBA_VERSION,
|
||||||
|
'date' => AKEEBA_DATE,
|
||||||
|
'edition' => $edition,
|
||||||
|
'updateinfo' => $updateInformation,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\Profiles;
|
||||||
|
use Akeeba\Engine\Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import the profile's configuration
|
||||||
|
*/
|
||||||
|
class ImportConfiguration extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
'data' => null,
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile_id = (int)$defConfig['profile'];
|
||||||
|
$data = $defConfig['data'];
|
||||||
|
|
||||||
|
if ($profile_id <= 0)
|
||||||
|
{
|
||||||
|
$profile_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var Profiles $profile */
|
||||||
|
$profile = $this->container->factory->model('Profiles')->tmpInstance();
|
||||||
|
|
||||||
|
if ($profile_id)
|
||||||
|
{
|
||||||
|
$profile->find($profile_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
$profile->import($data);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\Statistics;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List the backup records
|
||||||
|
*/
|
||||||
|
class ListBackups extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'from' => 0,
|
||||||
|
'limit' => 50
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$from = (int)$defConfig['from'];
|
||||||
|
$limit = (int)$defConfig['limit'];
|
||||||
|
|
||||||
|
/** @var Statistics $model */
|
||||||
|
$model = $this->container->factory->model('Statistics')->tmpInstance();
|
||||||
|
$model->setState('limitstart', $from);
|
||||||
|
$model->setState('limit', $limit);
|
||||||
|
|
||||||
|
return $model->getStatisticsListWithMeta(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Engine\Factory;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the log contents
|
||||||
|
*/
|
||||||
|
class Log extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'tag' => 'remote'
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$tag = (int)$defConfig['tag'];
|
||||||
|
|
||||||
|
$filename = Factory::getLog()->getLogFilename($tag);
|
||||||
|
|
||||||
|
return file_get_contents($filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\MultipleDatabases;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an extra database definition
|
||||||
|
*/
|
||||||
|
class RemoveIncludedDB extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
'name' => '',
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = $filter->clean($defConfig['profile'], 'int');
|
||||||
|
$name = $filter->clean($defConfig['name'], 'string');
|
||||||
|
|
||||||
|
// We need a valid profile ID
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a uuid
|
||||||
|
if (empty($name))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('The database name is required', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the active profile
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var MultipleDatabases $model */
|
||||||
|
$model = $this->container->factory->model('MultipleDatabases')->tmpInstance();
|
||||||
|
|
||||||
|
return $model->remove($name);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\IncludeFolders;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an extra directory definition
|
||||||
|
*/
|
||||||
|
class RemoveIncludedDirectory extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
'uuid' => '',
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = $filter->clean($defConfig['profile'], 'int');
|
||||||
|
$uuid = $filter->clean($defConfig['uuid'], 'string');
|
||||||
|
|
||||||
|
// We need a valid profile ID
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a uuid
|
||||||
|
if (empty($uuid))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('UUID is required', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the active profile
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var IncludeFolders $model */
|
||||||
|
$model = $this->container->factory->model('IncludeFolders')->tmpInstance();
|
||||||
|
|
||||||
|
return $model->remove($uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Engine\Factory;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the configuration for a given profile
|
||||||
|
*/
|
||||||
|
class SaveConfiguration extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => -1,
|
||||||
|
'engineconfig' => array()
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = (int)$defConfig['profile'];
|
||||||
|
$data = $defConfig['engineconfig'];
|
||||||
|
|
||||||
|
if (empty($profile))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Invalid profile ID', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forbid stupidly selecting the site's root as the output or temporary directory
|
||||||
|
if (array_key_exists('akeeba.basic.output_directory', $data))
|
||||||
|
{
|
||||||
|
$folder = $data['akeeba.basic.output_directory'];
|
||||||
|
$folder = Factory::getFilesystemTools()->translateStockDirs($folder, true, true);
|
||||||
|
|
||||||
|
$check = Factory::getFilesystemTools()->translateStockDirs('[SITEROOT]', true, true);
|
||||||
|
|
||||||
|
if ($check == $folder)
|
||||||
|
{
|
||||||
|
$data['akeeba.basic.output_directory'] = '[DEFAULT_OUTPUT]';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge it
|
||||||
|
$config = Factory::getConfiguration();
|
||||||
|
$protectedKeys = $config->getProtectedKeys();
|
||||||
|
$config->resetProtectedKeys();
|
||||||
|
$config->mergeArray($data, false, false);
|
||||||
|
$config->setProtectedKeys($protectedKeys);
|
||||||
|
|
||||||
|
// Save configuration
|
||||||
|
return Platform::getInstance()->save_configuration($profile);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\Profiles;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a backup profile
|
||||||
|
*/
|
||||||
|
class SaveProfile extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
'description' => null,
|
||||||
|
'quickicon' => null,
|
||||||
|
'source' => 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = (int)$defConfig['profile'];
|
||||||
|
$description = $defConfig['description'];
|
||||||
|
$quickicon = $defConfig['quickicon'];
|
||||||
|
$source = (int)$defConfig['source'];
|
||||||
|
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// At least one of these parameters is required
|
||||||
|
if (empty($profile) && empty($source) && empty($description))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Invalid profile ID', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a profile model
|
||||||
|
/** @var Profiles $profileModel */
|
||||||
|
$profileModel = $this->container->factory->model('Profiles')->tmpInstance();
|
||||||
|
|
||||||
|
// Load the profile
|
||||||
|
$sourceId = empty($profile) ? $source : $profile;
|
||||||
|
|
||||||
|
if (!empty($sourceId))
|
||||||
|
{
|
||||||
|
$profileModel->findOrFail($sourceId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$profileModel->reset(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$profileModel->setFieldValue('id', $profile);
|
||||||
|
|
||||||
|
if ($description)
|
||||||
|
{
|
||||||
|
$profileModel->setFieldValue('description', $description);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_null($quickicon))
|
||||||
|
{
|
||||||
|
$profileModel->setFieldValue('quickicon', (int)$quickicon);
|
||||||
|
}
|
||||||
|
|
||||||
|
$profileModel->save();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,95 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\DatabaseFilters;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set or unset a database filter
|
||||||
|
*/
|
||||||
|
class SetDBFilter extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
'root' => '[SITEDB]',
|
||||||
|
'table' => '',
|
||||||
|
'type' => 'tables',
|
||||||
|
'status' => 1
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = $filter->clean($defConfig['profile'], 'int');
|
||||||
|
$root = $filter->clean($defConfig['root'], 'string');
|
||||||
|
$table = $filter->clean($defConfig['table'], 'string');
|
||||||
|
$type = $filter->clean($defConfig['type'], 'cmd');
|
||||||
|
$status = $filter->clean($defConfig['status'], 'bool');
|
||||||
|
|
||||||
|
// We need a valid profile ID
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a root
|
||||||
|
if (empty($root))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Unknown database root', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a table name
|
||||||
|
if (empty($table))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Table name is mandatory', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a table name
|
||||||
|
if (empty($type))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Filter type is mandatory', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the active profile
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var DatabaseFilters $model */
|
||||||
|
$model = $this->container->factory->model('DatabaseFilters')->tmpInstance();
|
||||||
|
|
||||||
|
if ($status)
|
||||||
|
{
|
||||||
|
$ret = $model->setFilter($root, $table, $type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$ret = $model->remove($root, $table, $type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,112 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\FileFilters;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set or unset a filesystem filter
|
||||||
|
*/
|
||||||
|
class SetFSFilter extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
'root' => '[SITEROOT]',
|
||||||
|
'path' => '',
|
||||||
|
'type' => '',
|
||||||
|
'status' => 1
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = $filter->clean($defConfig['profile'], 'int');
|
||||||
|
$root = $filter->clean($defConfig['root'], 'string');
|
||||||
|
$path = $filter->clean($defConfig['path'], 'path');
|
||||||
|
$type = $filter->clean($defConfig['type'], 'cmd');
|
||||||
|
$status = $filter->clean($defConfig['status'], 'bool');
|
||||||
|
|
||||||
|
$crumbs = array();
|
||||||
|
$node = '';
|
||||||
|
|
||||||
|
// We need a valid profile ID
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a root
|
||||||
|
if (empty($root))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Unknown filesystem root', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a path
|
||||||
|
if (empty($path))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Unknown path', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the subdirectory and explode it to its parts
|
||||||
|
$path = trim($path, '/');
|
||||||
|
|
||||||
|
if (!empty($path))
|
||||||
|
{
|
||||||
|
$crumbs = explode('/', $root);
|
||||||
|
$node = array_pop($crumbs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($node))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Unknown path', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a table name
|
||||||
|
if (empty($type))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Filter type is mandatory', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the active profile
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var FileFilters $model */
|
||||||
|
$model = $this->container->factory->model('FileFilters')->tmpInstance();
|
||||||
|
|
||||||
|
if ($status)
|
||||||
|
{
|
||||||
|
$ret = $model->setFilter($root, $crumbs, $node, $type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$ret = $model->remove($root, $crumbs, $node, $type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\MultipleDatabases;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up or edit an extra database definition
|
||||||
|
*/
|
||||||
|
class SetIncludedDB extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
'name' => '',
|
||||||
|
'connection' => array(),
|
||||||
|
'test' => true,
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = $filter->clean($defConfig['profile'], 'int');
|
||||||
|
$name = $filter->clean($defConfig['name'], 'string');
|
||||||
|
$connection = $filter->clean($defConfig['connection'], 'array');
|
||||||
|
$test = $filter->clean($defConfig['test'], 'bool');
|
||||||
|
|
||||||
|
// We need a valid profile ID
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
empty($connection) || !isset($connection['host']) || !isset($connection['driver'])
|
||||||
|
|| !isset($connection['database']) || !isset($connection['user'])
|
||||||
|
|| !isset($connection['password'])
|
||||||
|
)
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Connection information missing or incomplete', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the active profile
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var MultipleDatabases $model */
|
||||||
|
$model = $this->container->factory->model('MultipleDatabases')->tmpInstance();
|
||||||
|
|
||||||
|
if ($test)
|
||||||
|
{
|
||||||
|
$result = $model->test($connection);
|
||||||
|
|
||||||
|
if (!$result['status'])
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Connection test failed: ' . $result['message'], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $model->setFilter($name, $connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\IncludeFolders;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
use Akeeba\Engine\Util\RandomValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up or edit an extra directory definition
|
||||||
|
*/
|
||||||
|
class SetIncludedDirectory extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
'uuid' => '',
|
||||||
|
'path' => '',
|
||||||
|
'virtualFolder' => '',
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = $filter->clean($defConfig['profile'], 'int');
|
||||||
|
$path = $filter->clean($defConfig['path'], 'path');
|
||||||
|
$uuid = $filter->clean($defConfig['uuid'], 'string');
|
||||||
|
$virtualFolder = $filter->clean($defConfig['virtualFolder'], 'string');
|
||||||
|
|
||||||
|
// We need a valid profile ID
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a path
|
||||||
|
if (empty($path))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Path is required', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a uuid
|
||||||
|
if (empty($uuid))
|
||||||
|
{
|
||||||
|
$uuid = $this->uuid_v4();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a vf
|
||||||
|
if (empty($virtualFolder))
|
||||||
|
{
|
||||||
|
$virtualFolder = basename($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the active profile
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var IncludeFolders $model */
|
||||||
|
$model = $this->container->factory->model('IncludeFolders')->tmpInstance();
|
||||||
|
|
||||||
|
$data = array($path, $virtualFolder);
|
||||||
|
|
||||||
|
return $model->setFilter($uuid, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a UUID v4
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function uuid_v4()
|
||||||
|
{
|
||||||
|
$randval = new RandomValue();
|
||||||
|
$data = $randval->generate(16);
|
||||||
|
|
||||||
|
$data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100
|
||||||
|
$data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10
|
||||||
|
|
||||||
|
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,95 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\RegExDatabaseFilters;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set or unset a Regex database filter
|
||||||
|
*/
|
||||||
|
class SetRegexDBFilter extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
'root' => '[SITEDB]',
|
||||||
|
'regex' => '',
|
||||||
|
'type' => 'tables',
|
||||||
|
'status' => 1
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = $filter->clean($defConfig['profile'], 'int');
|
||||||
|
$root = $filter->clean($defConfig['root'], 'string');
|
||||||
|
$regex = $filter->clean($defConfig['regex'], 'string');
|
||||||
|
$type = $filter->clean($defConfig['type'], 'cmd');
|
||||||
|
$status = $filter->clean($defConfig['status'], 'bool');
|
||||||
|
|
||||||
|
// We need a valid profile ID
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a root
|
||||||
|
if (empty($root))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Unknown database root', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a regex name
|
||||||
|
if (empty($regex))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Regex is mandatory', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a regex name
|
||||||
|
if (empty($type))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Filter type is mandatory', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the active profile
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var RegExDatabaseFilters $model */
|
||||||
|
$model = $this->container->factory->model('RegExDatabaseFilters')->tmpInstance();
|
||||||
|
|
||||||
|
if ($status)
|
||||||
|
{
|
||||||
|
$ret = $model->setFilter($type, $root, $regex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$ret = $model->remove($type, $root, $regex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,95 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\RegExFileFilters;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set or unset a Regex filesystem filter
|
||||||
|
*/
|
||||||
|
class SetRegexFSFilter extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 0,
|
||||||
|
'root' => '[SITEDB]',
|
||||||
|
'regex' => '',
|
||||||
|
'type' => 'directories',
|
||||||
|
'status' => 1
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = $filter->clean($defConfig['profile'], 'int');
|
||||||
|
$root = $filter->clean($defConfig['root'], 'string');
|
||||||
|
$regex = $filter->clean($defConfig['regex'], 'string');
|
||||||
|
$type = $filter->clean($defConfig['type'], 'cmd');
|
||||||
|
$status = $filter->clean($defConfig['status'], 'bool');
|
||||||
|
|
||||||
|
// We need a valid profile ID
|
||||||
|
if ($profile <= 0)
|
||||||
|
{
|
||||||
|
$profile = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a root
|
||||||
|
if (empty($root))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Unknown database root', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a regex name
|
||||||
|
if (empty($regex))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Regex is mandatory', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need a regex name
|
||||||
|
if (empty($type))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Filter type is mandatory', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the active profile
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
|
||||||
|
// Load the configuration
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var RegExFileFilters $model */
|
||||||
|
$model = $this->container->factory->model('RegExFileFilters')->tmpInstance();
|
||||||
|
|
||||||
|
if ($status)
|
||||||
|
{
|
||||||
|
$ret = $model->setFilter($type, $root, $regex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$ret = $model->remove($type, $root, $regex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,89 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Engine\Factory;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a backup job
|
||||||
|
*/
|
||||||
|
class StartBackup extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => 1,
|
||||||
|
'description' => '',
|
||||||
|
'comment' => '',
|
||||||
|
'backupid' => null,
|
||||||
|
'overrides' => array(),
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = (int) $defConfig['profile'];
|
||||||
|
$profile = max(1, $profile); // Make sure $profile is a positive integer >= 1
|
||||||
|
$description = $filter->clean($defConfig['description'], 'string');
|
||||||
|
$comment = $filter->clean($defConfig['comment'], 'string');
|
||||||
|
$backupid = $filter->clean($defConfig['backupid'], 'cmd');
|
||||||
|
$backupid = empty($backupid) ? null : $backupid; // Otherwise the Engine doesn't set a backup ID
|
||||||
|
$overrides = $filter->clean($defConfig['overrides'], 'array');
|
||||||
|
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
define('AKEEBA_PROFILE', $profile);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DO NOT REMOVE!
|
||||||
|
*
|
||||||
|
* The Model will only try to load the configuration after nuking the factory. This causes Profile 1 to be
|
||||||
|
* loaded first. Then it figures out it needs to load a different profile and it does – but the protected keys
|
||||||
|
* are NOT replaced, meaning that certain configuration parameters are not replaced. Most notably, the chain.
|
||||||
|
* This causes backups to behave weirdly. So, DON'T REMOVE THIS UNLESS WE REFACTOR THE MODEL.
|
||||||
|
*/
|
||||||
|
Platform::getInstance()->load_configuration($profile);
|
||||||
|
|
||||||
|
/** @var \Akeeba\Backup\Site\Model\Backup $model */
|
||||||
|
$model = $this->container->factory->model('Backup')->tmpInstance();
|
||||||
|
$model->setState('tag', AKEEBA_BACKUP_ORIGIN);
|
||||||
|
$model->setState('backupid', $backupid);
|
||||||
|
$model->setState('description', $description);
|
||||||
|
$model->setState('comment', $comment);
|
||||||
|
|
||||||
|
$array = $model->startBackup($overrides);
|
||||||
|
|
||||||
|
if ($array['Error'] != '')
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('A backup error has occurred: ' . $array['Error'], 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BackupID contains the numeric backup record ID. backupid contains the backup id (usually in the form id123)
|
||||||
|
$statistics = Factory::getStatistics();
|
||||||
|
$array['BackupID'] = $statistics->getId();
|
||||||
|
|
||||||
|
// Remote clients expect a boolean, not an integer.
|
||||||
|
$array['HasRun'] = ($array['HasRun'] === 0);
|
||||||
|
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Engine\Factory;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Step through a backup job
|
||||||
|
*/
|
||||||
|
class StepBackup extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'profile' => null,
|
||||||
|
'tag' => AKEEBA_BACKUP_ORIGIN,
|
||||||
|
'backupid' => null,
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$profile = $filter->clean($defConfig['profile'], 'int');
|
||||||
|
$tag = $filter->clean($defConfig['tag'], 'cmd');
|
||||||
|
$backupid = $filter->clean($defConfig['backupid'], 'cmd');
|
||||||
|
|
||||||
|
if (is_null($backupid) && defined('AKEEBA_BACKUP_ID'))
|
||||||
|
{
|
||||||
|
$tag = AKEEBA_BACKUP_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($backupid))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException("JSON API :: stepBackup -- You have not provided the required backupid parameter. This parameter is MANDATORY since May 2016. Please update your client software to include this parameter.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to set the profile from the setup parameters
|
||||||
|
if (!empty($profile))
|
||||||
|
{
|
||||||
|
$profile = max(1, $profile); // Make sure $profile is a positive integer >= 1
|
||||||
|
$this->container->platform->setSessionVar('profile', $profile);
|
||||||
|
define('AKEEBA_PROFILE', $profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var \Akeeba\Backup\Site\Model\Backup $model */
|
||||||
|
$model = $this->container->factory->model('Backup')->tmpInstance();
|
||||||
|
$model->setState('tag', $tag);
|
||||||
|
$model->setState('backupid', $backupid);
|
||||||
|
$array = $model->stepBackup(false);
|
||||||
|
|
||||||
|
if ($array['Error'] != '')
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('A backup error has occurred: ' . $array['Error'], 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BackupID contains the numeric backup record ID. backupid contains the backup id (usually in the form id123)
|
||||||
|
$statistics = Factory::getStatistics();
|
||||||
|
$array['BackupID'] = $statistics->getId();
|
||||||
|
|
||||||
|
// Remote clients expect a boolean, not an integer.
|
||||||
|
$array['HasRun'] = ($array['HasRun'] === 0);
|
||||||
|
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\MultipleDatabases;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test an extra database definition
|
||||||
|
*/
|
||||||
|
class TestDBConnection extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'connection' => array(),
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$connection = $filter->clean($defConfig['connection'], 'array');
|
||||||
|
|
||||||
|
if (
|
||||||
|
empty($connection) || !isset($connection['host']) || !isset($connection['driver'])
|
||||||
|
|| !isset($connection['database']) || !isset($connection['user'])
|
||||||
|
|| !isset($connection['password'])
|
||||||
|
)
|
||||||
|
{
|
||||||
|
throw new \RuntimeException('Connection information missing or incomplete', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var MultipleDatabases $model */
|
||||||
|
$model = $this->container->factory->model('MultipleDatabases')->tmpInstance();
|
||||||
|
|
||||||
|
return $model->test($connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json\Task;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use Akeeba\Backup\Site\Model\Updates;
|
||||||
|
use Akeeba\Engine\Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the update information
|
||||||
|
*/
|
||||||
|
class UpdateGetInformation extends AbstractTask
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array())
|
||||||
|
{
|
||||||
|
$filter = \JFilterInput::getInstance();
|
||||||
|
|
||||||
|
// Get the passed configuration values
|
||||||
|
$defConfig = array(
|
||||||
|
'force' => 0
|
||||||
|
);
|
||||||
|
|
||||||
|
$defConfig = array_merge($defConfig, $parameters);
|
||||||
|
|
||||||
|
$force = $filter->clean($defConfig['force'], 'bool');
|
||||||
|
|
||||||
|
/** @var Updates $model */
|
||||||
|
$model = $this->container->factory->model('Updates')->tmpInstance();
|
||||||
|
|
||||||
|
$updateInformation = $model->getUpdates($force);
|
||||||
|
|
||||||
|
return (object)$updateInformation;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Akeeba\Backup\Site\Model\Json;
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
use FOF30\Container\Container;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for JSON API tasks
|
||||||
|
*/
|
||||||
|
interface TaskInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Public constructor
|
||||||
|
*
|
||||||
|
* @param Container $container The container of the component we belong to
|
||||||
|
*/
|
||||||
|
public function __construct(Container $container);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the JSON API task's name ("method" name). Remote clients will use it to call us.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getMethodName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the JSON API task
|
||||||
|
*
|
||||||
|
* @param array $parameters The parameters to this task
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException In case of an error
|
||||||
|
*/
|
||||||
|
public function execute(array $parameters = array());
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 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\Admin\Model\MultipleDatabases as AdminModel;
|
||||||
|
|
||||||
|
class MultipleDatabases extends AdminModel
|
||||||
|
{
|
||||||
|
}
|
||||||
17
deployed/akeeba/components/com_akeeba/Model/Profiles.php
Normal file
17
deployed/akeeba/components/com_akeeba/Model/Profiles.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 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\Admin\Model\Profiles as AdminModel;
|
||||||
|
|
||||||
|
class Profiles extends AdminModel
|
||||||
|
{
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 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\Admin\Model\RegExDatabaseFilters as AdminModel;
|
||||||
|
|
||||||
|
class RegExDatabaseFilters extends AdminModel
|
||||||
|
{
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 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\Admin\Model\RegExFileFilters as AdminModel;
|
||||||
|
|
||||||
|
class RegExFileFilters extends AdminModel
|
||||||
|
{
|
||||||
|
}
|
||||||
17
deployed/akeeba/components/com_akeeba/Model/Statistics.php
Normal file
17
deployed/akeeba/components/com_akeeba/Model/Statistics.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 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\Admin\Model\Statistics as AdminModel;
|
||||||
|
|
||||||
|
class Statistics extends AdminModel
|
||||||
|
{
|
||||||
|
}
|
||||||
17
deployed/akeeba/components/com_akeeba/Model/Updates.php
Normal file
17
deployed/akeeba/components/com_akeeba/Model/Updates.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 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\Admin\Model\Updates as AdminModel;
|
||||||
|
|
||||||
|
class Updates extends AdminModel
|
||||||
|
{
|
||||||
|
}
|
||||||
18
deployed/akeeba/components/com_akeeba/akeeba.php
Normal file
18
deployed/akeeba/components/com_akeeba/akeeba.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package AkeebaBackup
|
||||||
|
* @copyright Copyright (c)2006-2018 Nicholas K. Dionysopoulos / Akeeba Ltd
|
||||||
|
* @license GNU General Public License version 3, or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Protect from unauthorized access
|
||||||
|
defined('_JEXEC') or die();
|
||||||
|
|
||||||
|
JDEBUG ? define('AKEEBADEBUG', 1) : null;
|
||||||
|
|
||||||
|
if (!defined('FOF30_INCLUDED') && !@include_once(JPATH_LIBRARIES . '/fof30/include.php'))
|
||||||
|
{
|
||||||
|
throw new RuntimeException('FOF 3.0 is not installed', 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
FOF30\Container\Container::getInstance('com_akeeba')->dispatcher->dispatch();
|
||||||
1
deployed/akeeba/components/com_akeeba/index.html
Normal file
1
deployed/akeeba/components/com_akeeba/index.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<html><head><title></title></head><body></body></html>
|
||||||
Loading…
Reference in New Issue
Block a user