Some draft code for #318

This commit is contained in:
the-djmaze 2022-04-06 11:24:37 +02:00
parent dcbafb70eb
commit 95b7dee402
4 changed files with 115 additions and 24 deletions

View file

@ -448,6 +448,33 @@ class ActionsAdmin extends Actions
('plugin' !== $sType ? array('Reload' => true) : true) : false);
}
// /?admin/Backup
public function DoAdminBackup() : void
{
try {
$this->IsAdminLoggined();
$file = \SnappyMail\Upgrade::backup();
\header('Content-Type: application/gzip');
\header('Content-Disposition: attachment; filename="' . \basename($file) . '"');
\header('Content-Transfer-Encoding: binary');
\header('Content-Length: ' . \filesize($file));
$fp = \fopen($file, 'rb');
\fpassthru($fp);
\unlink($file);
} catch (\Throwable $e) {
if (102 == $e->getCode()) {
\MailSo\Base\Http::StatusHeader(403);
}
echo $e->getMessage();
}
exit;
}
public function DoAdminUpgradeCore() : array
{
return $this->DefaultResponse(__FUNCTION__, \SnappyMail\Upgrade::core());
}
public function DoAdminPluginDisable() : array
{
$this->IsAdminLoggined();

View file

@ -74,6 +74,16 @@ class ServiceActions
return $this;
}
/*
public function ServiceBackup() : void
{
if (\method_exists($this->oActions, 'DoAdminBackup')) {
$this->oActions->DoAdminBackup();
}
exit;
}
*/
public function ServiceJson() : string
{
\ob_start();

View file

@ -7,11 +7,11 @@ abstract class Repository
// snappyMailRepo
const BASE_URL = 'https://snappymail.eu/repository/v2/';
private static function get(string $path, string $proxy, string $proxy_auth) : string
private static function get(string $path) : string
{
$oHTTP = HTTP\Request::factory(/*'socket' or 'curl'*/);
$oHTTP->proxy = $proxy;
$oHTTP->proxy_auth = $proxy_auth;
$oHTTP->proxy = \RainLoop\Api::Config()->Get('labs', 'curl_proxy', '');
$oHTTP->proxy_auth = \RainLoop\Api::Config()->Get('labs', 'curl_proxy_auth', '');
$oHTTP->max_response_kb = 0;
$oHTTP->timeout = 15; // timeout in seconds.
$oResponse = $oHTTP->doRequest('GET', static::BASE_URL . $path);
@ -26,16 +26,17 @@ abstract class Repository
// $aRep = \json_decode($sRep);
private static function download(string $path, string $proxy, string $proxy_auth) : string
private static function download(string $path) : string
{
$sTmp = APP_PRIVATE_DATA . \md5(\microtime(true).$path) . \preg_replace('/^.*?(\\.[a-z\\.]+)$/Di', '$1', $path);
$pDest = \fopen($sTmp, 'w+b');
if (!$pDest) {
throw new \Exception('Cannot create temp file: '.$sTmp);
}
$oHTTP = HTTP\Request::factory(/*'socket' or 'curl'*/);
$oHTTP->proxy = $proxy;
$oHTTP->proxy_auth = $proxy_auth;
$oHTTP->proxy = \RainLoop\Api::Config()->Get('labs', 'curl_proxy', '');
$oHTTP->proxy_auth = \RainLoop\Api::Config()->Get('labs', 'curl_proxy_auth', '');
$oHTTP->max_response_kb = 0;
$oHTTP->timeout = 15; // timeout in seconds.
$oHTTP->streamBodyTo($pDest);
@ -81,10 +82,7 @@ abstract class Repository
if ('' === $sRep || 0 === $iRepTime || \time() - 3600 > $iRepTime)
{
$sRep = static::get($sRepoFile,
\RainLoop\Api::Config()->Get('labs', 'curl_proxy', ''),
\RainLoop\Api::Config()->Get('labs', 'curl_proxy_auth', '')
);
$sRep = static::get($sRepoFile);
if ($sRep)
{
$aRep = \json_decode($sRep);
@ -150,6 +148,21 @@ abstract class Repository
return $aResult;
}
public static function getLatestCoreInfo()
{
\RainLoop\Api::Actions()->IsAdminLoggined();
$sRep = static::get('core.json');
return $sRep ? \json_decode($sRep) : null;
}
public static function downloadCore(string $path) : ?string
{
$info = static::getLatestCoreInfo();
return \version_compare(APP_VERSION, $info->version, '<')
? static::download($info->file) // '../latest.tar.gz'
: null;
}
public static function getPackagesList() : array
{
\RainLoop\Api::Actions()->IsAdminLoggined();
@ -230,27 +243,23 @@ abstract class Repository
}
if (isset($aList[$sId]) && $sFile === $aList[$sId]['file']) {
$sRealFile = $sFile;
$sTmp = static::download($sFile,
\RainLoop\Api::Config()->Get('labs', 'curl_proxy', ''),
\RainLoop\Api::Config()->Get('labs', 'curl_proxy_auth', '')
);
$sTmp = static::download($sFile);
}
}
if ($sTmp) {
$oArchive = new \PharData($sTmp, 0, $sRealFile);
if (static::deletePackageDir($sId)) {
if ('.phar' === \substr($sRealFile, -5)) {
$bResult = \copy($sTmp, APP_PLUGINS_PATH . \basename($sRealFile));
} else {
$bResult = $oArchive->extractTo(\rtrim(APP_PLUGINS_PATH, '\\/'));
}
if (!$bResult) {
throw new \Exception('Cannot extract package files: '.$oArchive->getStatusString());
}
} else {
if (!static::deletePackageDir($sId)) {
throw new \Exception('Cannot remove previous plugin folder: '.$sId);
}
if ('.phar' === \substr($sRealFile, -5)) {
$bResult = \copy($sTmp, APP_PLUGINS_PATH . \basename($sRealFile));
} else {
$bResult = $oArchive->extractTo(\rtrim(APP_PLUGINS_PATH, '\\/'));
}
if (!$bResult) {
throw new \Exception('Cannot extract package files: '.$oArchive->getStatusString());
}
}
} catch (\Throwable $e) {
\RainLoop\Api::Logger()->Write("Install package {$sRealFile} failed: {$e->getMessage()}", \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER');

View file

@ -162,4 +162,49 @@ abstract class Upgrade
return \unserialize($sData) ?: array();
}
}
public static function backup() : string
{
// $tar_destination = APP_DATA_FOLDER_PATH . APP_VERSION . '.tar';
$tar_destination = APP_DATA_FOLDER_PATH . 'backup-' . \date('YmdHis') . '.tar';
$tar = new \PharData($tar_destination);
$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(APP_DATA_FOLDER_PATH . '_data_'), \RecursiveIteratorIterator::SELF_FIRST);
$l = \strlen(APP_DATA_FOLDER_PATH);
foreach ($files as $file) {
$file = \str_replace('\\', '/', $file);
if (\is_file($file) && !\strpos($file, '/cache/')) {
$tar->addFile($file, \substr($file, $l));
}
}
$tar->compress(\Phar::GZ);
\unlink($tar_destination);
return $tar_destination . '.gz';
}
public static function core() : bool
{
$this->IsAdminLoggined();
$bResult = false;
if (\version_compare(APP_VERSION, '2.0', '>')
&& \is_writable(\dirname(APP_VERSION_ROOT_PATH))
&& \is_writable(APP_INDEX_ROOT_PATH . 'index.php')
) {
$sTmp = null;
try {
$sTmp = Repository::downloadCore($info->file);
if ($sTmp) {
static::backup();
$oArchive = new \PharData($sTmp, 0);
$bResult = $oArchive->extractTo(\rtrim(APP_VERSION_ROOT_PATH, '\\/'));
if (!$bResult) {
throw new \Exception('Cannot extract core files: '.$oArchive->getStatusString());
}
}
} finally {
$sTmp && \unlink($sTmp);
}
}
return $bResult;
}
}