1
0
mirror of https://github.com/mail-in-a-box/mailinabox.git synced 2025-04-29 04:17:07 +00:00

Finalized B2 Storage backend.

Finalized the work needed on the backup script for B2 Storage, and fixed
a couple issues with the UI.
This commit is contained in:
Carson Page 2017-10-17 11:34:35 -05:00
parent aa09a46ee0
commit 0397480f50
2 changed files with 33 additions and 17 deletions

View File

@ -474,12 +474,13 @@ def list_target_files(config):
return [(key.name[len(path):], key.size) for key in bucket.list(prefix=path)] return [(key.name[len(path):], key.size) for key in bucket.list(prefix=path)]
elif target.scheme == "b2": elif target.scheme == "b2":
(auth_token, api_url) = b2_perform_authentication(target.username, target.password) api = b2_perform_authentication(target.username, target.password)
if api == None: if api == None:
raise ValueError("B2 authentication failed for unknown reason.") raise ValueError("B2 authentication failed for unknown reason.")
(auth_token, api_url) = api
bucket_id = b2_get_bucket_id(target.username, api_url, auth_token, target.hostname) bucket_id = b2_get_bucket_id(target.username, api_url, auth_token, target.hostname)
return b2_list_files(target.username, api_url, auth_token, bucket_id, target.path)
else: else:
raise ValueError(config["target"]) raise ValueError(config["target"])
@ -492,7 +493,7 @@ def b2_perform_authentication(acc_id, app_key):
import json import json
# Formulate the authtoken according to B2 Storage API Spec # Formulate the authtoken according to B2 Storage API Spec
auth_token = base64.b64encode((acc_id + ":" + app_key).encode('utf-8')) auth_token = "Basic" + base64.b64encode((acc_id + ":" + app_key).encode('utf-8')).decode('utf-8')
headers = {'Authorization': auth_token} headers = {'Authorization': auth_token}
req = Request("https://api.backblazeb2.com/b2api/v1/b2_authorize_account", headers=headers) req = Request("https://api.backblazeb2.com/b2api/v1/b2_authorize_account", headers=headers)
@ -502,6 +503,7 @@ def b2_perform_authentication(acc_id, app_key):
return (data['authorizationToken'], data['apiUrl']) return (data['authorizationToken'], data['apiUrl'])
except HTTPError as e: except HTTPError as e:
e_data = json.loads(e.read().decode('utf-8')) e_data = json.loads(e.read().decode('utf-8'))
print(e_data)
if e_data['code'] == 'unauthorized': if e_data['code'] == 'unauthorized':
raise ValueError("Invalid key pair, or B2 has not been enabled, or the user is suspended.") raise ValueError("Invalid key pair, or B2 has not been enabled, or the user is suspended.")
elif e_data['code'] == 'missing_phone_number': elif e_data['code'] == 'missing_phone_number':
@ -523,14 +525,9 @@ def b2_perform_request(acc_id, api_url, auth_token, method, data):
req_data = None req_data = None
req = Request("{0}/b2api/v1/{1}".format(api_url, method), data=req_data, headers = { 'Authorization': auth_token}) req = Request("{0}/b2api/v1/{1}".format(api_url, method), data=req_data, headers = { 'Authorization': auth_token})
try: with urlopen(req) as res:
with urlopen(req) as res: data = json.loads(res.read().decode('utf-8'))
data = json.loads(res.read().decode('utf-8')) return data
return data
except HTTPError as e:
raise e
except:
raise ValueError("B2 Storage: Unknown error occured")
def b2_get_bucket_id(acc_id, api_url, auth_token, bucket_name): def b2_get_bucket_id(acc_id, api_url, auth_token, bucket_name):
from urllib.error import HTTPError from urllib.error import HTTPError
@ -545,6 +542,23 @@ def b2_get_bucket_id(acc_id, api_url, auth_token, bucket_name):
if e_data['code'] == 'bad_request': if e_data['code'] == 'bad_request':
raise ValueError("B2 Storage: Account ID does not exist") raise ValueError("B2 Storage: Account ID does not exist")
def b2_list_files(acc_id, api_url, auth_token, bucket_id, path):
from urllib.error import HTTPError
if len(path) > 1:
path = path[1:] if path[0] == '/' else path
else:
path = ''
try:
file_list = b2_perform_request(acc_id, api_url, auth_token, 'b2_list_file_names', {
'bucketId': bucket_id,
'prefix': path
})['files']
file_list = [x for x in file_list if x['action'] == 'upload']
return [(key['fileName'][len(path) + 1:], key['size']) for key in file_list]
except HTTPError as e:
raise ValueError("B2 Storage: Could not list files")
def backup_set_custom(env, target, target_user, target_pass, min_age): def backup_set_custom(env, target, target_user, target_pass, min_age):
config = get_backup_config(env, for_save=True) config = get_backup_config(env, for_save=True)

View File

@ -121,13 +121,13 @@
<div class="form-group backup-target-b2"> <div class="form-group backup-target-b2">
<label for="backup-target-user" class="col-sm-2 control-label">B2 Account Id</label> <label for="backup-target-user" class="col-sm-2 control-label">B2 Account Id</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input type="text" class="form-control" rows="1" id="backup-target-user"> <input type="text" class="form-control" rows="1" id="backup-target-b2-user">
</div> </div>
</div> </div>
<div class="form-group backup-target-b2"> <div class="form-group backup-target-b2">
<label for="backup-target-pass" class="col-sm-2 control-label">B2 Application Key</label> <label for="backup-target-pass" class="col-sm-2 control-label">B2 Application Key</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input type="text" class="form-control" rows="1" id="backup-target-pass"> <input type="text" class="form-control" rows="1" id="backup-target-b2-pass">
</div> </div>
</div> </div>
<!-- Common --> <!-- Common -->
@ -163,7 +163,7 @@
function toggle_form() { function toggle_form() {
var target_type = $("#backup-target-type").val(); var target_type = $("#backup-target-type").val();
$(".backup-target-local, .backup-target-rsync, .backup-target-s3").hide(); $(".backup-target-local, .backup-target-rsync, .backup-target-s3, .backup-target-b2").hide();
$(".backup-target-" + target_type).show(); $(".backup-target-" + target_type).show();
} }
@ -264,7 +264,9 @@ function show_custom_backup() {
} else if (r.target.substring(0, 5) == "b2://") { } else if (r.target.substring(0, 5) == "b2://") {
$("#backup-target-type").val("b2"); $("#backup-target-type").val("b2");
var hostpath = r.target.substring(5).split('@'); var hostpath = r.target.substring(5).split('@');
var host = hostpath.shift(); var usernamepass = hostpath.shift().split(":");
$("#backup-target-rsync-b2-user").val(usernamepass[0]);
$("#backup-target-rsync-b2-user").val(usernamepass[1]);
$("#backup-target-b2-path").val(hostpath.join('/')); $("#backup-target-b2-path").val(hostpath.join('/'));
} }
toggle_form() toggle_form()
@ -283,7 +285,7 @@ function set_custom_backup() {
target = "s3://" + $("#backup-target-s3-host").val() + "/" + $("#backup-target-s3-path").val(); target = "s3://" + $("#backup-target-s3-host").val() + "/" + $("#backup-target-s3-path").val();
else if (target_type == "b2") else if (target_type == "b2")
target = "b2://" + $("#backup-target-b2-user").val() + ":" target = "b2://" + $("#backup-target-b2-user").val() + ":"
+ $("#backup-target-b2-pass").val() + "@" + $("#backup-target-b2-path"); + $("#backup-target-b2-pass").val() + "@" + $("#backup-target-b2-path").val();
else if (target_type == "rsync") { else if (target_type == "rsync") {
target = "rsync://" + $("#backup-target-rsync-user").val() + "@" + $("#backup-target-rsync-host").val() target = "rsync://" + $("#backup-target-rsync-user").val() + "@" + $("#backup-target-rsync-host").val()
+ "/" + $("#backup-target-rsync-path").val(); + "/" + $("#backup-target-rsync-path").val();