Skip to content

Commit 16c993a

Browse files
committed
sysutils/gdrive-backup: moved here from core
PR: opnsense/core#8343
1 parent cfc1269 commit 16c993a

File tree

6 files changed

+507
-0
lines changed

6 files changed

+507
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ sysutils/apuled -- PC Engine APU LED control (development only)
9898
sysutils/cpu-microcode -- CPU microcode updates
9999
sysutils/dec-hw -- Deciso hardware specific information
100100
sysutils/dmidecode -- Display hardware information on the dashboard
101+
sysutils/gdrive-backup -- Backup configurations using Google Drive
101102
sysutils/git-backup -- Track config changes using git
102103
sysutils/hw-probe -- Collect hardware diagnostics
103104
sysutils/lcdproc-sdeclcd -- LCDProc for SDEC LCD devices

sysutils/gdrive-backup/Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
PLUGIN_NAME= gdrive-backup
2+
PLUGIN_VERSION= 1.0
3+
PLUGIN_COMMENT= Backup configurations using Google Drive
4+
PLUGIN_DEPENDS= php${PLUGIN_PHP}-google-api-php-client
5+
PLUGIN_MAINTAINER= ad@opnsense.org
6+
PLUGIN_TIER= 2
7+
8+
.include "../../Mk/plugins.mk"

sysutils/gdrive-backup/pkg-descr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
This plugin adds a backup option using Google Drive.
2+
3+
Due to the sensitive nature of the data being send to the backup,
4+
we strongly advise to not use a public service to send backups to.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
/*
4+
* Copyright (C) 2025 Deciso B.V.
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
*
13+
* 2. Redistributions in binary form must reproduce the above copyright
14+
* notice, this list of conditions and the following disclaimer in the
15+
* documentation and/or other materials provided with the distribution.
16+
*
17+
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18+
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19+
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20+
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21+
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
*/
28+
29+
/**
30+
* sync configuration via xmlrpc
31+
* @return array
32+
*/
33+
function gdrive_xmlrpc_sync()
34+
{
35+
return [[
36+
'description' => gettext('Backup - Google Drive'),
37+
'section' => 'system.remotebackup',
38+
'id' => 'remotebackup',
39+
]];
40+
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
<?php
2+
3+
/*
4+
* Copyright (C) 2015-2023 Deciso B.V.
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
*
13+
* 2. Redistributions in binary form must reproduce the above copyright
14+
* notice, this list of conditions and the following disclaimer in the
15+
* documentation and/or other materials provided with the distribution.
16+
*
17+
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18+
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19+
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20+
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
21+
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
* POSSIBILITY OF SUCH DAMAGE.
27+
*/
28+
29+
namespace Google\API;
30+
31+
/**
32+
* Class Drive wrapper around Google API for Drive support
33+
* @package Google\API
34+
*/
35+
class Drive
36+
{
37+
/**
38+
* @var null|\Google_Service_Drive service pointer
39+
*/
40+
private $service = null;
41+
42+
/**
43+
* @var null|\Google_Client pointer to client
44+
*/
45+
private $client = null;
46+
47+
/**
48+
* construct a new Drive object
49+
*/
50+
public function __construct()
51+
{
52+
// hook in Google's autoloader
53+
require_once("/usr/local/share/google-api-php-client/vendor/autoload.php");
54+
}
55+
56+
/**
57+
* login to google drive
58+
* @param $client_id
59+
* @param $privateKeyB64 P12 key placed in a base64 container
60+
*/
61+
public function login($client_id, $privateKeyB64)
62+
{
63+
openssl_pkcs12_read(base64_decode($privateKeyB64), $certinfo, "notasecret");
64+
if (empty($certinfo)) {
65+
throw new \Exception("Invalid P12 key, openssl_pkcs12_read() failed");
66+
}
67+
$this->client = new \Google_Client();
68+
69+
$service_account = [
70+
"type" => "service_account",
71+
"private_key" => $certinfo['pkey'],
72+
"client_email" => $client_id,
73+
"client_id" => $client_id,
74+
"auth_uri" => "https://accounts.google.com/o/oauth2/auth",
75+
"token_uri" => "https://oauth2.googleapis.com/token",
76+
"auth_provider_x509_cert_url" => "https://www.googleapis.com/oauth2/v1/certs"
77+
];
78+
79+
$this->client->setAuthConfig($service_account);
80+
$this->client->addScope("https://www.googleapis.com/auth/drive");
81+
$this->client->setApplicationName("OPNsense");
82+
83+
$this->service = new \Google_Service_Drive($this->client);
84+
}
85+
86+
/**
87+
* retrieve directory listing
88+
* @param $directoryId parent directory id
89+
* @param $filename title/filename of object
90+
* @return mixed list of files
91+
*/
92+
public function listFiles($directoryId, $filename = null)
93+
{
94+
$query = "'" . $directoryId . "' in parents ";
95+
if ($filename != null) {
96+
$query .= " and title in '" . $filename . "'";
97+
}
98+
return $this->service->files->listFiles(['q' => $query, 'supportsAllDrives' => true]);
99+
}
100+
101+
102+
/**
103+
* download a file by given GDrive file handle
104+
* @param $fileHandle (object from listFiles)
105+
* @return null|string
106+
*/
107+
public function download($fileHandle)
108+
{
109+
$response = $this->service->files->get($fileHandle->id, ['alt' => 'media', 'supportsAllDrives' => true]);
110+
return $response->getBody()->getContents();
111+
}
112+
113+
/**
114+
* Upload file
115+
* @param string $directoryId (parent id)
116+
* @param string $filename
117+
* @param string $content
118+
* @param string $mimetype
119+
* @return \Google_Service_Drive_DriveFile handle
120+
*/
121+
public function upload($directoryId, $filename, $content, $mimetype = 'text/plain')
122+
{
123+
124+
$file = new \Google_Service_Drive_DriveFile();
125+
$file->setName($filename);
126+
$file->setDescription($filename);
127+
$file->setMimeType('text/plain');
128+
$file->setParents([$directoryId]);
129+
130+
$createdFile = $this->service->files->create($file, [
131+
'data' => $content,
132+
'mimeType' => $mimetype,
133+
'uploadType' => 'media',
134+
'supportsAllDrives' => true
135+
]);
136+
137+
return $createdFile;
138+
}
139+
140+
/**
141+
* delete file
142+
* @param $fileHandle (object from listFiles)
143+
*/
144+
public function delete($fileHandle)
145+
{
146+
$this->service->files->delete($fileHandle['id'], ['supportsAllDrives' => true]);
147+
}
148+
}

0 commit comments

Comments
 (0)