mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-13 00:07:26 +00:00
system: remove GDrive backup from core
Still needs migration glue, but mechanics are done. PR: https://github.com/opnsense/core/issues/8343
This commit is contained in:
parent
717bf17dae
commit
d77bd0a8fb
1
Makefile
1
Makefile
@ -161,7 +161,6 @@ CORE_DEPENDS?= ca_root_nss \
|
||||
php${CORE_PHP}-dom \
|
||||
php${CORE_PHP}-filter \
|
||||
php${CORE_PHP}-gettext \
|
||||
php${CORE_PHP}-google-api-php-client \
|
||||
php${CORE_PHP}-ldap \
|
||||
php${CORE_PHP}-pcntl \
|
||||
php${CORE_PHP}-pdo \
|
||||
|
||||
2
plist
2
plist
@ -526,7 +526,6 @@
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Wireguard/forms/dialogEditWireguardClient.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Wireguard/forms/dialogEditWireguardServer.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Wireguard/forms/general.xml
|
||||
/usr/local/opnsense/mvc/app/library/Google/API/Drive.php
|
||||
/usr/local/opnsense/mvc/app/library/OPNsense/Auth/API.php
|
||||
/usr/local/opnsense/mvc/app/library/OPNsense/Auth/AuthenticationFactory.php
|
||||
/usr/local/opnsense/mvc/app/library/OPNsense/Auth/Base.php
|
||||
@ -545,7 +544,6 @@
|
||||
/usr/local/opnsense/mvc/app/library/OPNsense/Autoload/Loader.php
|
||||
/usr/local/opnsense/mvc/app/library/OPNsense/Backup/BackupFactory.php
|
||||
/usr/local/opnsense/mvc/app/library/OPNsense/Backup/Base.php
|
||||
/usr/local/opnsense/mvc/app/library/OPNsense/Backup/GDrive.php
|
||||
/usr/local/opnsense/mvc/app/library/OPNsense/Backup/IBackupProvider.php
|
||||
/usr/local/opnsense/mvc/app/library/OPNsense/Backup/Local.php
|
||||
/usr/local/opnsense/mvc/app/library/OPNsense/Base/UIModelGrid.php
|
||||
|
||||
@ -413,11 +413,6 @@ function core_xmlrpc_sync()
|
||||
'id' => 'webgui',
|
||||
'services' => ["webgui"],
|
||||
);
|
||||
$result[] = array(
|
||||
'description' => gettext('Backup - Google Drive'),
|
||||
'section' => 'system.remotebackup',
|
||||
'id' => 'remotebackup'
|
||||
);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@ -1,148 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015-2023 Deciso B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace Google\API;
|
||||
|
||||
/**
|
||||
* Class Drive wrapper around Google API for Drive support
|
||||
* @package Google\API
|
||||
*/
|
||||
class Drive
|
||||
{
|
||||
/**
|
||||
* @var null|\Google_Service_Drive service pointer
|
||||
*/
|
||||
private $service = null;
|
||||
|
||||
/**
|
||||
* @var null|\Google_Client pointer to client
|
||||
*/
|
||||
private $client = null;
|
||||
|
||||
/**
|
||||
* construct a new Drive object
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// hook in Google's autoloader
|
||||
require_once("/usr/local/share/google-api-php-client/vendor/autoload.php");
|
||||
}
|
||||
|
||||
/**
|
||||
* login to google drive
|
||||
* @param $client_id
|
||||
* @param $privateKeyB64 P12 key placed in a base64 container
|
||||
*/
|
||||
public function login($client_id, $privateKeyB64)
|
||||
{
|
||||
openssl_pkcs12_read(base64_decode($privateKeyB64), $certinfo, "notasecret");
|
||||
if (empty($certinfo)) {
|
||||
throw new \Exception("Invalid P12 key, openssl_pkcs12_read() failed");
|
||||
}
|
||||
$this->client = new \Google_Client();
|
||||
|
||||
$service_account = [
|
||||
"type" => "service_account",
|
||||
"private_key" => $certinfo['pkey'],
|
||||
"client_email" => $client_id,
|
||||
"client_id" => $client_id,
|
||||
"auth_uri" => "https://accounts.google.com/o/oauth2/auth",
|
||||
"token_uri" => "https://oauth2.googleapis.com/token",
|
||||
"auth_provider_x509_cert_url" => "https://www.googleapis.com/oauth2/v1/certs"
|
||||
];
|
||||
|
||||
$this->client->setAuthConfig($service_account);
|
||||
$this->client->addScope("https://www.googleapis.com/auth/drive");
|
||||
$this->client->setApplicationName("OPNsense");
|
||||
|
||||
$this->service = new \Google_Service_Drive($this->client);
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve directory listing
|
||||
* @param $directoryId parent directory id
|
||||
* @param $filename title/filename of object
|
||||
* @return mixed list of files
|
||||
*/
|
||||
public function listFiles($directoryId, $filename = null)
|
||||
{
|
||||
$query = "'" . $directoryId . "' in parents ";
|
||||
if ($filename != null) {
|
||||
$query .= " and title in '" . $filename . "'";
|
||||
}
|
||||
return $this->service->files->listFiles(['q' => $query, 'supportsAllDrives' => true]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* download a file by given GDrive file handle
|
||||
* @param $fileHandle (object from listFiles)
|
||||
* @return null|string
|
||||
*/
|
||||
public function download($fileHandle)
|
||||
{
|
||||
$response = $this->service->files->get($fileHandle->id, ['alt' => 'media', 'supportsAllDrives' => true]);
|
||||
return $response->getBody()->getContents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload file
|
||||
* @param string $directoryId (parent id)
|
||||
* @param string $filename
|
||||
* @param string $content
|
||||
* @param string $mimetype
|
||||
* @return \Google_Service_Drive_DriveFile handle
|
||||
*/
|
||||
public function upload($directoryId, $filename, $content, $mimetype = 'text/plain')
|
||||
{
|
||||
|
||||
$file = new \Google_Service_Drive_DriveFile();
|
||||
$file->setName($filename);
|
||||
$file->setDescription($filename);
|
||||
$file->setMimeType('text/plain');
|
||||
$file->setParents([$directoryId]);
|
||||
|
||||
$createdFile = $this->service->files->create($file, [
|
||||
'data' => $content,
|
||||
'mimeType' => $mimetype,
|
||||
'uploadType' => 'media',
|
||||
'supportsAllDrives' => true
|
||||
]);
|
||||
|
||||
return $createdFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete file
|
||||
* @param $fileHandle (object from listFiles)
|
||||
*/
|
||||
public function delete($fileHandle)
|
||||
{
|
||||
$this->service->files->delete($fileHandle['id'], ['supportsAllDrives' => true]);
|
||||
}
|
||||
}
|
||||
@ -1,306 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Deciso B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace OPNsense\Backup;
|
||||
|
||||
use OPNsense\Core\Config;
|
||||
|
||||
/**
|
||||
* Class google drive backup
|
||||
* @package OPNsense\Backup
|
||||
*/
|
||||
class Gdrive extends Base implements IBackupProvider
|
||||
{
|
||||
/**
|
||||
* get required (user interface) fields for backup connector
|
||||
* @return array configuration fields, types and description
|
||||
*/
|
||||
public function getConfigurationFields()
|
||||
{
|
||||
$fields = array();
|
||||
|
||||
$fields[] = array(
|
||||
"name" => "GDriveEnabled",
|
||||
"type" => "checkbox",
|
||||
"label" => gettext("Enable"),
|
||||
"value" => null
|
||||
);
|
||||
$fields[] = array(
|
||||
"name" => "GDriveEmail",
|
||||
"type" => "text",
|
||||
"label" => gettext("Email Address"),
|
||||
"help" => gettext("Client-ID in the Google cloud console"),
|
||||
"value" => null
|
||||
);
|
||||
$fields[] = array(
|
||||
"name" => "GDriveP12key",
|
||||
"type" => "file",
|
||||
"label" => gettext("P12 key"),
|
||||
"help" => sprintf(
|
||||
gettext('You need a private key in p12 format to use Google Drive, ' .
|
||||
'instructions on how to acquire one can be found %shere%s.'),
|
||||
'<a href="https://docs.opnsense.org/manual/how-tos/cloud_backup.html" target="_blank">',
|
||||
'</a>'
|
||||
),
|
||||
"value" => null
|
||||
);
|
||||
$fields[] = array(
|
||||
"name" => "GDriveFolderID",
|
||||
"type" => "text",
|
||||
"label" => gettext("Folder ID"),
|
||||
"value" => null
|
||||
);
|
||||
$fields[] = array(
|
||||
"name" => "GDrivePrefixHostname",
|
||||
"type" => "checkbox",
|
||||
"label" => gettext("Prefix hostname to backupfile"),
|
||||
"help" => gettext("Normally the config xml will be written as config-stamp.xml, with this option set " .
|
||||
"the filename will use the systems host and domain name."),
|
||||
"value" => null
|
||||
);
|
||||
$fields[] = array(
|
||||
"name" => "GDriveBackupCount",
|
||||
"type" => "text",
|
||||
"label" => gettext("Backup Count"),
|
||||
"value" => 60
|
||||
);
|
||||
$fields[] = array(
|
||||
"name" => "GDrivePassword",
|
||||
"type" => "password",
|
||||
"label" => gettext("Password"),
|
||||
"value" => null
|
||||
);
|
||||
$fields[] = array(
|
||||
"name" => "GDrivePasswordConfirm",
|
||||
"type" => "password",
|
||||
"label" => gettext("Confirm"),
|
||||
"value" => null
|
||||
);
|
||||
$cnf = Config::getInstance();
|
||||
if ($cnf->isValid()) {
|
||||
$config = $cnf->object();
|
||||
foreach ($fields as &$field) {
|
||||
$fieldname = $field['name'];
|
||||
if (isset($config->system->remotebackup->$fieldname)) {
|
||||
$field['value'] = (string)$config->system->remotebackup->$fieldname;
|
||||
} elseif (
|
||||
$fieldname == "GDrivePasswordConfirm" &&
|
||||
isset($config->system->remotebackup->GDrivePassword)
|
||||
) {
|
||||
$field['value'] = (string)$config->system->remotebackup->GDrivePassword;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* backup provider name
|
||||
* @return string user friendly name
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return gettext("Google Drive");
|
||||
}
|
||||
|
||||
/**
|
||||
* validate and set configuration
|
||||
* @param array $conf configuration array
|
||||
* @return array of validation errors when not saved
|
||||
*/
|
||||
public function setConfiguration($conf)
|
||||
{
|
||||
$input_errors = array();
|
||||
if ($conf['GDrivePasswordConfirm'] != $conf['GDrivePassword']) {
|
||||
$input_errors[] = gettext("The supplied 'Password' and 'Confirm' field values must match.");
|
||||
}
|
||||
if (count($input_errors) == 0) {
|
||||
$config = Config::getInstance()->object();
|
||||
if (!isset($config->system->remotebackup)) {
|
||||
$config->system->addChild('remotebackup');
|
||||
}
|
||||
foreach ($this->getConfigurationFields() as $field) {
|
||||
$fieldname = $field['name'];
|
||||
if ($field['type'] == 'file') {
|
||||
if (!empty($conf[$field['name']])) {
|
||||
$config->system->remotebackup->$fieldname = base64_encode($conf[$field['name']]);
|
||||
}
|
||||
} elseif ($field['name'] == 'GDrivePasswordConfirm') {
|
||||
/* skip password confirm field */
|
||||
} elseif (!empty($conf[$field['name']])) {
|
||||
$config->system->remotebackup->$fieldname = $conf[$field['name']];
|
||||
} else {
|
||||
unset($config->system->remotebackup->$fieldname);
|
||||
}
|
||||
}
|
||||
// remove private key when disabled
|
||||
if (
|
||||
empty($config->system->remotebackup->GDriveEnabled) &&
|
||||
isset($config->system->remotebackup->GDriveP12key)
|
||||
) {
|
||||
unset($config->system->remotebackup->GDriveP12key);
|
||||
}
|
||||
Config::getInstance()->save();
|
||||
}
|
||||
|
||||
return $input_errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array filelist
|
||||
*/
|
||||
public function backup()
|
||||
{
|
||||
$cnf = Config::getInstance();
|
||||
if ($cnf->isValid()) {
|
||||
$config = $cnf->object();
|
||||
if (
|
||||
isset($config->system->remotebackup) && isset($config->system->remotebackup->GDriveEnabled)
|
||||
&& !empty($config->system->remotebackup->GDriveEnabled)
|
||||
) {
|
||||
if (!empty($config->system->remotebackup->GDrivePrefixHostname)) {
|
||||
$fileprefix = (string)$config->system->hostname . "." . (string)$config->system->domain . "-";
|
||||
} else {
|
||||
$fileprefix = "config-";
|
||||
}
|
||||
try {
|
||||
$client = new \Google\API\Drive();
|
||||
$client->login(
|
||||
(string)$config->system->remotebackup->GDriveEmail,
|
||||
(string)$config->system->remotebackup->GDriveP12key
|
||||
);
|
||||
} catch (\Error | \Exception $e) {
|
||||
syslog(LOG_ERR, "error connecting to Google Drive");
|
||||
return array();
|
||||
}
|
||||
|
||||
// backup source data to local strings (plain/encrypted)
|
||||
$confdata = file_get_contents('/conf/config.xml');
|
||||
$confdata_enc = $this->encrypt($confdata, (string)$config->system->remotebackup->GDrivePassword);
|
||||
|
||||
// read filelist ({prefix}*.xml)
|
||||
try {
|
||||
$files = $client->listFiles((string)$config->system->remotebackup->GDriveFolderID);
|
||||
} catch (\Error | \Exception $e) {
|
||||
syslog(LOG_ERR, "error while fetching filelist from Google Drive");
|
||||
return array();
|
||||
}
|
||||
|
||||
$configfiles = array();
|
||||
foreach ($files as $file) {
|
||||
if (fnmatch("{$fileprefix}*.xml", $file['name'])) {
|
||||
$configfiles[$file['name']] = $file;
|
||||
}
|
||||
}
|
||||
krsort($configfiles);
|
||||
|
||||
|
||||
// backup new file if changed (or if first in backup)
|
||||
$target_filename = $fileprefix . time() . ".xml";
|
||||
if (count($configfiles) > 1) {
|
||||
// compare last backup with current, only save new
|
||||
try {
|
||||
$bck_data_enc = $client->download($configfiles[array_keys($configfiles)[0]]);
|
||||
if (strpos(substr($bck_data_enc, 0, 100), '---') !== false) {
|
||||
// base64 string is wrapped into tags
|
||||
$start_at = strpos($bck_data_enc, "---\n") + 4;
|
||||
$end_at = strpos($bck_data_enc, "\n---");
|
||||
$bck_data_enc = substr($bck_data_enc, $start_at, ($end_at - $start_at));
|
||||
}
|
||||
$bck_data = $this->decrypt(
|
||||
$bck_data_enc,
|
||||
(string)$config->system->remotebackup->GDrivePassword
|
||||
);
|
||||
if ($bck_data == $confdata) {
|
||||
$target_filename = null;
|
||||
}
|
||||
} catch (\Error | \Exception $e) {
|
||||
syslog(LOG_ERR, "unable to download " .
|
||||
$configfiles[array_keys($configfiles)[0]]->description . " from Google Drive (" . $e . ")");
|
||||
}
|
||||
}
|
||||
if (!is_null($target_filename)) {
|
||||
syslog(LOG_NOTICE, "backup configuration as " . $target_filename);
|
||||
try {
|
||||
$configfiles[$target_filename] = $client->upload(
|
||||
(string)$config->system->remotebackup->GDriveFolderID,
|
||||
$target_filename,
|
||||
$confdata_enc
|
||||
);
|
||||
} catch (\Error | \Exception $e) {
|
||||
syslog(LOG_ERR, "unable to upload " . $target_filename . " to Google Drive (" . $e . ")");
|
||||
return array();
|
||||
}
|
||||
|
||||
krsort($configfiles);
|
||||
}
|
||||
|
||||
// cleanup old files
|
||||
if (
|
||||
isset($config->system->remotebackup->GDriveBackupCount)
|
||||
&& is_numeric((string)$config->system->remotebackup->GDriveBackupCount)
|
||||
) {
|
||||
$fcount = 0;
|
||||
foreach ($configfiles as $filename => $file) {
|
||||
if ($fcount >= (string)$config->system->remotebackup->GDriveBackupCount) {
|
||||
syslog(LOG_NOTICE, "remove " . $filename . " from Google Drive");
|
||||
try {
|
||||
$client->delete($file);
|
||||
} catch (Google_Service_Exception $e) {
|
||||
syslog(LOG_ERR, "unable to remove " . $filename . " from Google Drive");
|
||||
}
|
||||
}
|
||||
$fcount++;
|
||||
}
|
||||
}
|
||||
|
||||
// return filelist
|
||||
return array_keys($configfiles);
|
||||
}
|
||||
}
|
||||
|
||||
// not configured / issue, return empty list
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this provider enabled
|
||||
* @return boolean enabled status
|
||||
*/
|
||||
public function isEnabled()
|
||||
{
|
||||
$cnf = Config::getInstance();
|
||||
if ($cnf->isValid()) {
|
||||
$config = $cnf->object();
|
||||
return isset($config->system->remotebackup) && isset($config->system->remotebackup->GDriveEnabled)
|
||||
&& !empty($config->system->remotebackup->GDriveEnabled);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user