%PDF- %PDF-
Direktori : /www/varak.net/nextcloud.varak.net/apps_old/apps/passwords/lib/Services/ |
Current File : //www/varak.net/nextcloud.varak.net/apps_old/apps/passwords/lib/Services/BackupService.php |
<?php namespace OCA\Passwords\Services; use Exception; use OCA\Passwords\Helper\Backup\CreateBackupHelper; use OCA\Passwords\Helper\Backup\RestoreBackupHelper; use OCP\Files\IAppData; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; use OCP\Files\SimpleFS\ISimpleFile; use OCP\Files\SimpleFS\ISimpleFolder; use OCP\Util; /** * Class BackupService * * @package OCA\Passwords\Services */ class BackupService { const AUTO_BACKUPS = 'autoBackups'; const BACKUPS = 'backups'; /** * @var ConfigurationService */ protected ConfigurationService $config; /** * @var IAppData */ protected IAppData $appData; /** * @var CreateBackupHelper */ protected CreateBackupHelper $createBackupHelper; /** * @var RestoreBackupHelper */ protected RestoreBackupHelper $restoreBackupHelper; /** * BackupService constructor. * * @param IAppData $appData * @param CreateBackupHelper $createBackupHelper * @param RestoreBackupHelper $restoreBackupHelper * @param ConfigurationService $config */ public function __construct(IAppData $appData, CreateBackupHelper $createBackupHelper, RestoreBackupHelper $restoreBackupHelper, ConfigurationService $config) { $this->appData = $appData; $this->createBackupHelper = $createBackupHelper; $this->restoreBackupHelper = $restoreBackupHelper; $this->config = $config; } /** * @param string|null $name * * @param string|null $folder * * @return ISimpleFile * @throws NotFoundException * @throws NotPermittedException * @throws Exception */ public function createBackup(?string $name = null, string $folder = self::BACKUPS): ISimpleFile { if(empty($name)) { $name = date('Y-m-d_H-i-s'); } else if(strlen($name) > 20) { $name = substr($name, 0, 20); } $backups = $this->getBackups(); if(isset($backups[ $name ])) $backups[ $name ]->delete(); $name .= '.json'; $data = json_encode($this->createBackupHelper->getData()); if(extension_loaded('zlib')) { $name .= '.gz'; $data = gzencode($data); } $folder = $this->getBackupFolder($folder); $file = $folder->newFile($name); $file->putContent($data); return $file; } /** * @param string|null $location * * @return ISimpleFile[] * @throws NotPermittedException */ public function getBackups(?string $location = null): array { $folders = [self::BACKUPS, self::AUTO_BACKUPS]; if(in_array($location, $folders)) $folders = [$location]; $backups = []; foreach($folders as $folder) { $files = $this->getBackupFolder($folder)->getDirectoryListing(); foreach($files as $file) { $name = $file->getName(); $name = substr($name, 0, strrpos($name, '.json')); $backups[ $name ] = $file; } } ksort($backups); return $backups; } /** * @param ISimpleFile $backup * @param bool $details * * @return array */ public function getBackupInfo(ISimpleFile $backup, bool $details = false): array { $name = $backup->getName(); preg_match('/^([\w\-.]+)(\.json(\.gz)?)$/', $name, $matches); $info = [ 'label' => $matches[1], 'name' => $name, 'size' => Util::humanFileSize($backup->getSize()), 'format' => isset($matches[3]) ? 'compressed':'json' ]; if($details) { try { $data = $this->unpackBackupFile($backup); $info['version'] = $data['version'] ?? 0; $info['users'] = isset($data['settings']['users']) ? count($data['settings']['users']):0; $info['entities'] = [ 'passwords' => isset($data['passwords']) ? count($data['passwords']):0, 'folders' => isset($data['folders']) ? count($data['folders']):0, 'tags' => isset($data['tags']) ? count($data['tags']):0, 'shares' => isset($data['shares']) ? count($data['shares']):0, 'keychains' => isset($data['keychains']) ? count($data['keychains']):0, 'challenges' => isset($data['challenges']) ? count($data['challenges']):0 ]; } catch(\Throwable $e) { $info['error'] = $e->getMessage(); } } return $info; } /** * @param string $name * @param array $options * * @return bool * @throws NotFoundException * @throws NotPermittedException * @throws Exception */ public function restoreBackup(string $name, array $options = []): bool { $backups = $this->getBackups(); if(!isset($backups[ $name ])) return false; $file = $backups[ $name ]; $backup = $this->unpackBackupFile($file); return $this->restoreBackupHelper->restore($backup, $options); } /** * @throws NotPermittedException */ public function removeOldBackups(): void { $maxBackups = intval($this->config->getAppValue('backup/files/maximum', 28)); if($maxBackups === 0) return; $backups = array_values($this->getBackups(self::AUTO_BACKUPS)); if(count($backups) <= $maxBackups) return; $delete = count($backups) - $maxBackups; for($i = 0; $i < $delete; $i++) { $backups[ $i ]->delete(); } } /** * @param string $name * * @return ISimpleFolder * @throws NotPermittedException */ public function getBackupFolder(string $name = self::BACKUPS): ISimpleFolder { try { return $this->appData->getFolder($name); } catch(NotFoundException $e) { return $this->appData->newFolder($name); } } /** * @param ISimpleFile $file * * @return mixed * @throws NotFoundException * @throws NotPermittedException */ protected function unpackBackupFile(ISimpleFile $file) { $data = $file->getContent(); if(substr($file->getName(), -2) === 'gz') { if(!extension_loaded('zlib')) throw new Exception('PHP extension zlib is required to read compressed backups.'); $data = gzdecode($data); } return json_decode($data, true); } }