signing metadata to ensure integrity on remote instances
This commit is contained in:
Родитель
9d8d323f3d
Коммит
8b8aa24f32
|
@ -8,16 +8,16 @@
|
|||
"packages": [
|
||||
{
|
||||
"name": "artificial-owl/my-small-php-tools",
|
||||
"version": "v23.0.6",
|
||||
"version": "v23.0.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ArtificialOwl/my-small-php-tools.git",
|
||||
"reference": "f3ee2fab1ce33a1edc0993b42c7008196d75015d"
|
||||
"reference": "0d9011b41954f072ba5ff721aee6b83b583a4da2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ArtificialOwl/my-small-php-tools/zipball/f3ee2fab1ce33a1edc0993b42c7008196d75015d",
|
||||
"reference": "f3ee2fab1ce33a1edc0993b42c7008196d75015d",
|
||||
"url": "https://api.github.com/repos/ArtificialOwl/my-small-php-tools/zipball/0d9011b41954f072ba5ff721aee6b83b583a4da2",
|
||||
"reference": "0d9011b41954f072ba5ff721aee6b83b583a4da2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -42,9 +42,9 @@
|
|||
"description": "My small PHP Tools",
|
||||
"support": {
|
||||
"issues": "https://github.com/ArtificialOwl/my-small-php-tools/issues",
|
||||
"source": "https://github.com/ArtificialOwl/my-small-php-tools/tree/v23.0.6"
|
||||
"source": "https://github.com/ArtificialOwl/my-small-php-tools/tree/v23.0.7"
|
||||
},
|
||||
"time": "2021-09-14T13:08:06+00:00"
|
||||
"time": "2021-09-17T09:48:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ifsnop/mysqldump-php",
|
||||
|
|
|
@ -98,7 +98,7 @@ class PointUpload extends Base {
|
|||
* @throws RestoringPointNotFoundException
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output) {
|
||||
$point = $this->pointService->getPoint($input->getArgument('point'));
|
||||
$point = $this->pointService->getRestoringPoint($input->getArgument('point'));
|
||||
|
||||
$checks = $this->remoteService->verifyPoint($point);
|
||||
|
||||
|
@ -124,7 +124,7 @@ class PointUpload extends Base {
|
|||
}
|
||||
|
||||
$health = $item->getHealth();
|
||||
$this->uploadMissingFiles($instance, $point, $item->getHealth(), $output);
|
||||
$this->uploadMissingFiles($instance, $point, $health, $output);
|
||||
if ($health->getStatus() === RestoringHealth::STATUS_OK) {
|
||||
$output->writeln(' > RestoringPoint is fully uploaded to ' . $instance);
|
||||
}
|
||||
|
@ -260,7 +260,8 @@ class PointUpload extends Base {
|
|||
}
|
||||
|
||||
$output->write(' * Uploading ' . $chunk->getDataName() . '/' . $chunk->getChunkName() . ': ');
|
||||
$restoringChunk = $this->pointService->getChunkContent($point, $chunk->getDataName(), $chunk->getChunkName());
|
||||
$restoringChunk =
|
||||
$this->pointService->getChunkContent($point, $chunk->getDataName(), $chunk->getChunkName());
|
||||
$this->remoteService->uploadChunk($instance, $point, $restoringChunk);
|
||||
$output->writeln('<info>ok</info>');
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ class ArchiveFile implements JsonSerializable {
|
|||
*
|
||||
* @return ArchiveFile
|
||||
*/
|
||||
public function setName(string $name): ArchiveFile {
|
||||
public function setName(string $name): self {
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
|
@ -94,13 +94,12 @@ class ArchiveFile implements JsonSerializable {
|
|||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function jsonSerialize() {
|
||||
public function jsonSerialize(): array {
|
||||
return
|
||||
[
|
||||
'name' => $this->getName()
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,9 @@ class RestoringChunk implements JsonSerializable, IDeserializable {
|
|||
/** @var string */
|
||||
private $checksum = '';
|
||||
|
||||
/** @var bool */
|
||||
private $encrypted = false;
|
||||
|
||||
/** @var string */
|
||||
private $encryptedChecksum = '';
|
||||
|
||||
|
@ -104,6 +107,17 @@ class RestoringChunk implements JsonSerializable, IDeserializable {
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFilename(): string {
|
||||
if ($this->isEncrypted()) {
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
return $this->getName() . '.zip';
|
||||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * @return int
|
||||
|
@ -184,6 +198,25 @@ class RestoringChunk implements JsonSerializable, IDeserializable {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param bool $encrypted
|
||||
*
|
||||
* @return RestoringChunk
|
||||
*/
|
||||
public function setEncrypted(bool $encrypted): self {
|
||||
$this->encrypted = $encrypted;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isEncrypted(): bool {
|
||||
return $this->encrypted;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
@ -246,13 +279,14 @@ class RestoringChunk implements JsonSerializable, IDeserializable {
|
|||
* @return RestoringChunk
|
||||
*/
|
||||
public function import(array $data): IDeserializable {
|
||||
$this->setName($this->get('name', $data, ''))
|
||||
$this->setName($this->get('name', $data))
|
||||
// ->setFiles($this->getArray('files', $data, []))
|
||||
->setCount($this->getInt('count', $data, 0))
|
||||
->setSize($this->getInt('size', $data, 0))
|
||||
->setChecksum($this->get('checksum', $data, ''))
|
||||
->setCount($this->getInt('count', $data))
|
||||
->setSize($this->getInt('size', $data))
|
||||
->setContent($this->get('content', $data))
|
||||
->setEncryptedChecksum($this->get('encrypted', $data, ''));
|
||||
->setEncrypted($this->getBool('encrypted', $data))
|
||||
->setChecksum($this->get('checksum', $data))
|
||||
->setEncryptedChecksum($this->get('encryptedChecksum', $data));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -276,8 +310,9 @@ class RestoringChunk implements JsonSerializable, IDeserializable {
|
|||
'name' => $this->getName(),
|
||||
'count' => $this->getCount(),
|
||||
'size' => $this->getSize(),
|
||||
'encrypted' => $this->isEncrypted(),
|
||||
'checksum' => $this->getChecksum(),
|
||||
'encrypted' => $this->getEncryptedChecksum()
|
||||
'encryptedChecksum' => $this->getEncryptedChecksum()
|
||||
];
|
||||
|
||||
if ($this->getContent() !== '') {
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace OCA\Backup\Model;
|
|||
use ArtificialOwl\MySmallPhpTools\Db\Nextcloud\nc23\INC23QueryRow;
|
||||
use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException;
|
||||
use ArtificialOwl\MySmallPhpTools\IDeserializable;
|
||||
use ArtificialOwl\MySmallPhpTools\ISignedModel;
|
||||
use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore;
|
||||
use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize;
|
||||
use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger;
|
||||
|
@ -48,7 +49,7 @@ use OCP\Files\SimpleFS\ISimpleFolder;
|
|||
*
|
||||
* @package OCA\Backup\Model
|
||||
*/
|
||||
class RestoringPoint implements IDeserializable, INC23QueryRow, JsonSerializable {
|
||||
class RestoringPoint implements IDeserializable, INC23QueryRow, ISignedModel, JsonSerializable {
|
||||
|
||||
|
||||
use TArrayTools;
|
||||
|
@ -83,6 +84,9 @@ class RestoringPoint implements IDeserializable, INC23QueryRow, JsonSerializable
|
|||
/** @var RestoringHealth */
|
||||
private $health;
|
||||
|
||||
/** @var string */
|
||||
private $signature = '';
|
||||
|
||||
/** @var bool */
|
||||
private $package = false;
|
||||
|
||||
|
@ -304,6 +308,25 @@ class RestoringPoint implements IDeserializable, INC23QueryRow, JsonSerializable
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $signature
|
||||
*
|
||||
* @return RestoringPoint
|
||||
*/
|
||||
public function setSignature(string $signature): self {
|
||||
$this->signature = $signature;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSignature(): string {
|
||||
return $this->signature;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param bool $package
|
||||
*
|
||||
|
@ -347,6 +370,7 @@ class RestoringPoint implements IDeserializable, INC23QueryRow, JsonSerializable
|
|||
|
||||
$metadata = new SimpleDataStore($this->getArray('metadata', $data));
|
||||
$this->setNc($metadata->gArray('nc'));
|
||||
$this->setSignature($metadata->g('signature'));
|
||||
|
||||
try {
|
||||
/** @var RestoringHealth $health */
|
||||
|
@ -377,7 +401,8 @@ class RestoringPoint implements IDeserializable, INC23QueryRow, JsonSerializable
|
|||
->setInstance($this->get('instance', $data))
|
||||
->setRoot($this->get('root', $data))
|
||||
->setStatus($this->getInt('status', $data))
|
||||
->setDate($this->getInt('date', $data));
|
||||
->setDate($this->getInt('date', $data))
|
||||
->setSignature($this->get('signature', $data));
|
||||
$this->setNc($this->getArray('nc', $data));
|
||||
|
||||
if ($this->getId() === '' || $this->getStatus() === -1) {
|
||||
|
@ -402,6 +427,20 @@ class RestoringPoint implements IDeserializable, INC23QueryRow, JsonSerializable
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function signedData(): array {
|
||||
return [
|
||||
'id' => $this->getId(),
|
||||
'nc' => $this->getNC(),
|
||||
'root' => $this->getRoot(),
|
||||
'data' => $this->getRestoringData(),
|
||||
'date' => $this->getDate()
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
|
@ -413,6 +452,7 @@ class RestoringPoint implements IDeserializable, INC23QueryRow, JsonSerializable
|
|||
'root' => $this->getRoot(),
|
||||
'status' => $this->getStatus(),
|
||||
'data' => $this->getRestoringData(),
|
||||
'signature' => $this->getSignature(),
|
||||
'date' => $this->getDate()
|
||||
];
|
||||
|
||||
|
@ -424,4 +464,3 @@ class RestoringPoint implements IDeserializable, INC23QueryRow, JsonSerializable
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -110,6 +110,8 @@ class CreateRestoringPoint extends CoreRequest implements IRemoteRequest {
|
|||
|
||||
try {
|
||||
$this->pointRequest->save($point);
|
||||
$this->pointService->saveMetadata($point);
|
||||
|
||||
$stored = $this->pointRequest->getById($point->getId(), $signatory->getInstance());
|
||||
|
||||
$this->setOutcome(new SimpleDataStore([$point->getId() => $stored]));
|
||||
|
|
|
@ -32,14 +32,18 @@ declare(strict_types=1);
|
|||
namespace OCA\Backup\RemoteRequest;
|
||||
|
||||
|
||||
use ArtificialOwl\MySmallPhpTools\Exceptions\InvalidItemException;
|
||||
use ArtificialOwl\MySmallPhpTools\IDeserializable;
|
||||
use ArtificialOwl\MySmallPhpTools\Model\SimpleDataStore;
|
||||
use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Deserialize;
|
||||
use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger;
|
||||
use OCA\Backup\AppInfo\Application;
|
||||
use OCA\Backup\Db\PointRequest;
|
||||
use OCA\Backup\Exceptions\RestoringPointNotFoundException;
|
||||
use OCA\Backup\IRemoteRequest;
|
||||
use OCA\Backup\Model\RestoringChunk;
|
||||
use OCA\Backup\Service\ArchiveService;
|
||||
use OCA\Backup\Service\PointService;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\Files\NotPermittedException;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -54,37 +58,66 @@ class UploadRestoringPoint extends CoreRequest implements IRemoteRequest {
|
|||
use TNC23Logger;
|
||||
|
||||
|
||||
/** @var PointRequest */
|
||||
private $pointRequest;
|
||||
/** @var PointService */
|
||||
private $pointService;
|
||||
|
||||
/** @var ArchiveService */
|
||||
private $chunkService;
|
||||
|
||||
|
||||
/**
|
||||
* UploadRestoringPoint constructor.
|
||||
*
|
||||
* @param PointRequest $pointRequest
|
||||
* @param PointService $pointService
|
||||
* @param ArchiveService $chunkService
|
||||
*/
|
||||
public function __construct(PointRequest $pointRequest) {
|
||||
public function __construct(
|
||||
PointService $pointService,
|
||||
ArchiveService $chunkService
|
||||
) {
|
||||
parent::__construct();
|
||||
$this->pointRequest = $pointRequest;
|
||||
|
||||
$this->pointService = $pointService;
|
||||
$this->chunkService = $chunkService;
|
||||
|
||||
$this->setup('app', Application::APP_ID);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function execute(): void {
|
||||
$chunk = $this->deserializeJson($this->getSignedRequest()->getBody(), RestoringChunk::class);
|
||||
try {
|
||||
$signedRequest = $this->getSignedRequest();
|
||||
$signatory = $signedRequest->getSignatory();
|
||||
$pointId = $signedRequest->getIncomingRequest()->getParam('pointId');
|
||||
|
||||
$point = $this->pointService->getRestoringPoint($pointId, $signatory->getInstance());
|
||||
/** @var RestoringChunk $chunk */
|
||||
$chunk = $this->deserializeJson($signedRequest->getBody(), RestoringChunk::class);
|
||||
|
||||
$this->pointService->initBaseFolder($point);
|
||||
$this->chunkService->saveChunkContent($point, $chunk);
|
||||
|
||||
$this->pointService->generateHealth($point, true);
|
||||
|
||||
// $this->setOutcome(new SimpleDataStore(['dssd']));
|
||||
} catch (RestoringPointNotFoundException
|
||||
| InvalidItemException
|
||||
| NotFoundException
|
||||
| NotPermittedException $e) {
|
||||
}
|
||||
|
||||
$this->log(3, '### ' . strlen($chunk->getContent()));
|
||||
$this->setOutcome(new SimpleDataStore(['dssd']));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return IDeserializable
|
||||
*/
|
||||
public function import(array $data): IDeserializable {
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -39,8 +39,8 @@ use OCA\Backup\Exceptions\ArchiveCreateException;
|
|||
use OCA\Backup\Exceptions\ArchiveDeleteException;
|
||||
use OCA\Backup\Exceptions\ArchiveNotFoundException;
|
||||
use OCA\Backup\Exceptions\BackupAppCopyException;
|
||||
use OCA\Backup\Exceptions\BackupFolderException;
|
||||
use OCA\Backup\Exceptions\BackupScriptNotFoundException;
|
||||
use OCA\Backup\Exceptions\ChunkNotFoundException;
|
||||
use OCA\Backup\Exceptions\EncryptionKeyException;
|
||||
use OCA\Backup\Model\ArchiveFile;
|
||||
use OCA\Backup\Model\Backup;
|
||||
|
@ -113,44 +113,44 @@ class ArchiveService {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Backup $backup
|
||||
* @param RestoringChunk $archive
|
||||
* @param string $root
|
||||
*
|
||||
* @throws ArchiveDeleteException
|
||||
* @throws ArchiveNotFoundException
|
||||
* @throws EncryptionKeyException
|
||||
* @throws BackupFolderException
|
||||
*/
|
||||
public function extractAll(Backup $backup, RestoringChunk $archive, string $root): void {
|
||||
if (!is_dir($root)) {
|
||||
if (!@mkdir($root, 0755, true)) {
|
||||
throw new BackupFolderException('could not create ' . $root);
|
||||
}
|
||||
}
|
||||
|
||||
$this->decryptArchive($backup, $archive);
|
||||
$this->extractAllFromArchive($archive, $root);
|
||||
$this->deleteArchive($backup, $archive, 'zip');
|
||||
}
|
||||
//
|
||||
// /**
|
||||
// * @param Backup $backup
|
||||
// * @param RestoringChunk $archive
|
||||
// * @param string $root
|
||||
// *
|
||||
// * @throws ArchiveDeleteException
|
||||
// * @throws ArchiveNotFoundException
|
||||
// * @throws EncryptionKeyException
|
||||
// * @throws BackupFolderException
|
||||
// */
|
||||
// public function extractAll(Backup $backup, RestoringChunk $archive, string $root): void {
|
||||
// if (!is_dir($root)) {
|
||||
// if (!@mkdir($root, 0755, true)) {
|
||||
// throw new BackupFolderException('could not create ' . $root);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// $this->decryptArchive($backup, $archive);
|
||||
// $this->extractAllFromArchive($archive, $root);
|
||||
// $this->deleteArchive($backup, $archive, 'zip');
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* @param RestoringChunk $archive
|
||||
* @param string $root
|
||||
*
|
||||
* @throws ArchiveNotFoundException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function extractAllFromArchive(RestoringChunk $archive, string $root): void {
|
||||
$zip = $this->openZipArchive($archive);
|
||||
$zip->extractTo($root);
|
||||
$this->closeZipArchive($zip);
|
||||
|
||||
unlink($root . '.backup.' . $archive->getName() . '.json');
|
||||
}
|
||||
// /**
|
||||
// * @param RestoringChunk $archive
|
||||
// * @param string $root
|
||||
// *
|
||||
// * @throws ArchiveNotFoundException
|
||||
// * @throws Exception
|
||||
// */
|
||||
// public function extractAllFromArchive(RestoringChunk $archive, string $root): void {
|
||||
// $zip = $this->openZipArchive($archive);
|
||||
// $zip->extractTo($root);
|
||||
// $this->closeZipArchive($zip);
|
||||
//
|
||||
// unlink($root . '.backup.' . $archive->getName() . '.json');
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
|
@ -614,4 +614,61 @@ class ArchiveService {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param RestoringPoint $point
|
||||
* @param string $data
|
||||
* @param string $chunk
|
||||
*
|
||||
* @return RestoringChunk
|
||||
* @throws ChunkNotFoundException
|
||||
*/
|
||||
public function extractChunkFromRP(RestoringPoint $point, string $data, string $chunk): RestoringChunk {
|
||||
foreach ($point->getRestoringData() as $restoringData) {
|
||||
if ($restoringData->getName() !== $data) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($restoringData->getChunks() as $restoringChunk) {
|
||||
if ($restoringChunk->getName() === $chunk) {
|
||||
return $restoringChunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new ChunkNotFoundException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param RestoringPoint $point
|
||||
* @param RestoringChunk $restoringChunk
|
||||
*/
|
||||
public function getChunkContent(RestoringPoint $point, RestoringChunk $restoringChunk): void {
|
||||
$folder = $point->getBaseFolder();
|
||||
try {
|
||||
$file = $folder->getFile($restoringChunk->getFilename());
|
||||
$restoringChunk->setContent(base64_encode($file->getContent()));
|
||||
} catch (NotFoundException | NotPermittedException $e) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param RestoringPoint $point
|
||||
* @param RestoringChunk $chunk
|
||||
*/
|
||||
public function saveChunkContent(RestoringPoint $point, RestoringChunk $chunk) {
|
||||
$folder = $point->getBaseFolder();
|
||||
try {
|
||||
try {
|
||||
$file = $folder->getFile($chunk->getFilename());
|
||||
} catch (NotFoundException $e) {
|
||||
$file = $folder->newFile($chunk->getFilename());
|
||||
}
|
||||
|
||||
$file->putContent(base64_decode($chunk->getContent()));
|
||||
} catch (NotPermittedException | NotFoundException $e) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,7 +32,8 @@ declare(strict_types=1);
|
|||
namespace OCA\Backup\Service;
|
||||
|
||||
|
||||
use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc22\TNC22Logger;
|
||||
use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Logger;
|
||||
use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc23\TNC23Signatory;
|
||||
use ArtificialOwl\MySmallPhpTools\Traits\TStringTools;
|
||||
use OC;
|
||||
use OC\Files\AppData\Factory;
|
||||
|
@ -42,6 +43,8 @@ use OCA\Backup\Exceptions\ArchiveCreateException;
|
|||
use OCA\Backup\Exceptions\ArchiveNotFoundException;
|
||||
use OCA\Backup\Exceptions\BackupAppCopyException;
|
||||
use OCA\Backup\Exceptions\BackupScriptNotFoundException;
|
||||
use OCA\Backup\Exceptions\ChunkNotFoundException;
|
||||
use OCA\Backup\Exceptions\RestoringPointException;
|
||||
use OCA\Backup\Exceptions\RestoringPointNotFoundException;
|
||||
use OCA\Backup\Exceptions\SqlDumpException;
|
||||
use OCA\Backup\Model\RestoringChunk;
|
||||
|
@ -64,7 +67,8 @@ use OCP\Util;
|
|||
class PointService {
|
||||
|
||||
|
||||
use TNC22Logger;
|
||||
use TNC23Signatory;
|
||||
use TNC23Logger;
|
||||
use TStringTools;
|
||||
|
||||
|
||||
|
@ -76,11 +80,14 @@ class PointService {
|
|||
/** @var PointRequest */
|
||||
private $pointRequest;
|
||||
|
||||
/** @var ConfigService */
|
||||
private $configService;
|
||||
/** @var RemoteStreamService */
|
||||
private $remoteStreamService;
|
||||
|
||||
/** @var ArchiveService */
|
||||
private $archiveService;
|
||||
private $chunkService;
|
||||
|
||||
/** @var ConfigService */
|
||||
private $configService;
|
||||
|
||||
/** @var IAppData */
|
||||
private $appData;
|
||||
|
@ -93,16 +100,19 @@ class PointService {
|
|||
* PointService constructor.
|
||||
*
|
||||
* @param PointRequest $pointRequest
|
||||
* @param ArchiveService $archiveService
|
||||
* @param RemoteStreamService $remoteStreamService
|
||||
* @param ArchiveService $chunkService
|
||||
* @param ConfigService $configService
|
||||
*/
|
||||
public function __construct(
|
||||
PointRequest $pointRequest,
|
||||
ArchiveService $archiveService,
|
||||
RemoteStreamService $remoteStreamService,
|
||||
ArchiveService $chunkService,
|
||||
ConfigService $configService
|
||||
) {
|
||||
$this->pointRequest = $pointRequest;
|
||||
$this->archiveService = $archiveService;
|
||||
$this->chunkService = $chunkService;
|
||||
$this->remoteStreamService = $remoteStreamService;
|
||||
$this->configService = $configService;
|
||||
|
||||
$this->setup('app', 'backup');
|
||||
|
@ -111,11 +121,22 @@ class PointService {
|
|||
|
||||
/**
|
||||
* @param string $pointId
|
||||
* @param string $instance
|
||||
*
|
||||
* @return RestoringPoint
|
||||
* @throws RestoringPointNotFoundException
|
||||
*/
|
||||
public function getPoint(string $pointId): RestoringPoint {
|
||||
return $this->pointRequest->getById($pointId);
|
||||
public function getRestoringPoint(string $pointId, string $instance = ''): RestoringPoint {
|
||||
return $this->pointRequest->getById($pointId, $instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $instance
|
||||
*
|
||||
* @return RestoringPoint[]
|
||||
*/
|
||||
public function getRPByInstance(string $instance): array {
|
||||
return $this->pointRequest->getByInstance($instance);
|
||||
}
|
||||
|
||||
|
||||
|
@ -130,15 +151,16 @@ class PointService {
|
|||
* @throws BackupAppCopyException
|
||||
* @throws BackupScriptNotFoundException
|
||||
* @throws SqlDumpException
|
||||
* @throws RestoringPointException
|
||||
*/
|
||||
public function create(bool $complete): RestoringPoint {
|
||||
$point = $this->initRestoringPoint($complete);
|
||||
$this->archiveService->copyApp($point);
|
||||
$this->chunkService->copyApp($point);
|
||||
|
||||
// $backup->setEncryptionKey('12345');
|
||||
$this->archiveService->createChunks($point);
|
||||
$this->chunkService->createChunks($point);
|
||||
$this->backupSql($point);
|
||||
$this->generateMetadata($point);
|
||||
$this->saveMetadata($point);
|
||||
|
||||
$this->pointRequest->save($point);
|
||||
|
||||
|
@ -163,9 +185,6 @@ class PointService {
|
|||
$point->setNC(Util::getVersion());
|
||||
|
||||
$this->initBaseFolder($point);
|
||||
$temp = $point->getBaseFolder()->newFile(self::METADATA_FILE);
|
||||
$temp->putContent('');
|
||||
|
||||
$this->addingRestoringData($point, $complete);
|
||||
|
||||
return $point;
|
||||
|
@ -240,7 +259,7 @@ class PointService {
|
|||
$content = $this->generateSqlDump();
|
||||
|
||||
$data = new RestoringData(RestoringData::SQL_DUMP, '', 'sqldump');
|
||||
$this->archiveService->createContentChunk(
|
||||
$this->chunkService->createContentChunk(
|
||||
$point,
|
||||
$data,
|
||||
self::SQL_DUMP_FILE,
|
||||
|
@ -273,18 +292,21 @@ class PointService {
|
|||
/**
|
||||
* @param RestoringPoint $point
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @throws NotPermittedException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
private function generateMetadata(RestoringPoint $point) {
|
||||
if (!$point->hasBaseFolder()) {
|
||||
return;
|
||||
}
|
||||
public function saveMetadata(RestoringPoint $point) {
|
||||
$this->initBaseFolder($point);
|
||||
|
||||
$folder = $point->getBaseFolder();
|
||||
|
||||
$json = $folder->getFile(self::METADATA_FILE);
|
||||
$json->putContent(json_encode($point, JSON_PRETTY_PRINT));
|
||||
try {
|
||||
$file = $folder->getFile(self::METADATA_FILE);
|
||||
} catch (NotFoundException $e) {
|
||||
$file = $folder->newFile(self::METADATA_FILE);
|
||||
}
|
||||
|
||||
$file->putContent(json_encode($point, JSON_PRETTY_PRINT));
|
||||
}
|
||||
|
||||
|
||||
|
@ -325,6 +347,11 @@ class PointService {
|
|||
|
||||
|
||||
/**
|
||||
* This will destroy all backup stored locally
|
||||
* (from this instance and from remote instance using this instance as storage)
|
||||
*
|
||||
* This method is only called when the app is reset/uninstall using ./occ backup:reset
|
||||
*
|
||||
* @throws NotPermittedException
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
|
@ -344,7 +371,11 @@ class PointService {
|
|||
* @throws NotFoundException
|
||||
* @throws NotPermittedException
|
||||
*/
|
||||
private function initBaseFolder(RestoringPoint $point): void {
|
||||
public function initBaseFolder(RestoringPoint $point): void {
|
||||
if ($point->hasBaseFolder()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->initBackupFS();
|
||||
|
||||
try {
|
||||
|
@ -359,6 +390,7 @@ class PointService {
|
|||
|
||||
/**
|
||||
* @param RestoringPoint $point
|
||||
* @param bool $updateDb
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @throws NotPermittedException
|
||||
|
@ -402,7 +434,7 @@ class PointService {
|
|||
*/
|
||||
private function generateChunkHealthStatus(RestoringPoint $point, RestoringChunk $chunk): int {
|
||||
try {
|
||||
$checksum = $this->archiveService->getChecksum($point, $chunk, false);
|
||||
$checksum = $this->chunkService->getChecksum($point, $chunk, false);
|
||||
if ($checksum !== $chunk->getChecksum()) {
|
||||
return RestoringChunkHealth::STATUS_CHECKSUM;
|
||||
}
|
||||
|
@ -422,44 +454,15 @@ class PointService {
|
|||
* @return RestoringChunk
|
||||
* @throws NotFoundException
|
||||
* @throws NotPermittedException
|
||||
* @throws ChunkNotFoundException
|
||||
*/
|
||||
public function getChunkContent(RestoringPoint $point, string $data, string $chunk): RestoringChunk {
|
||||
$restoringChunk = $this->getChunk($point, $data, $chunk);
|
||||
|
||||
$this->initBaseFolder($point);
|
||||
$folder = $point->getBaseFolder();
|
||||
$file = $folder->getFile($chunk . '.zip');
|
||||
|
||||
$restoringChunk->setContent(base64_encode($file->getContent()));
|
||||
$restoringChunk = $this->chunkService->extractChunkFromRP($point, $data, $chunk);
|
||||
$this->chunkService->getChunkContent($point, $restoringChunk);
|
||||
|
||||
return $restoringChunk;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param RestoringPoint $point
|
||||
* @param string $data
|
||||
* @param string $chunk
|
||||
*
|
||||
* @return RestoringChunk
|
||||
* @throws ChunkNotFoundException
|
||||
*/
|
||||
private function getChunk(RestoringPoint $point, string $data, string $chunk): RestoringChunk {
|
||||
foreach ($point->getRestoringData() as $restoringData) {
|
||||
if ($restoringData->getName() !== $data) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($restoringData->getChunks() as $restoringChunk) {
|
||||
if ($restoringChunk->getName() === $chunk) {
|
||||
return $restoringChunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new ChunkNotFoundException();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -170,6 +170,8 @@ class RemoteService {
|
|||
throw new RemoteInstanceException('instance not configured as outgoing');
|
||||
}
|
||||
|
||||
$this->remoteStreamService->signPoint($point);
|
||||
|
||||
$result = $this->remoteStreamService->resultRequestRemoteInstance(
|
||||
$remoteInstance->getInstance(),
|
||||
RemoteInstance::RP_CREATE,
|
||||
|
|
|
@ -53,6 +53,7 @@ use OCA\Backup\Exceptions\RemoteInstanceException;
|
|||
use OCA\Backup\Exceptions\RemoteInstanceNotFoundException;
|
||||
use OCA\Backup\Exceptions\RemoteResourceNotFoundException;
|
||||
use OCA\Backup\Model\RemoteInstance;
|
||||
use OCA\Backup\Model\RestoringPoint;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\IURLGenerator;
|
||||
|
||||
|
@ -369,5 +370,12 @@ class RemoteStreamService extends NC23Signature {
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SignatoryException
|
||||
*/
|
||||
public function signPoint(RestoringPoint $point) {
|
||||
$this->signModel($point, $this->getAppSignatory(false));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче