From 7668316916149e66129e7a3c5a140c012d96a1dd Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Tue, 4 Mar 2014 09:16:15 +0530 Subject: [PATCH] only system manager can download backups --- frappe/app.py | 2 ++ frappe/installer.py | 4 ++-- frappe/patches.txt | 1 + frappe/utils/__init__.py | 30 +++++++++++++++++++++++++++++- frappe/utils/backups.py | 2 +- 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/frappe/app.py b/frappe/app.py index 2039877aea..b369c14b53 100644 --- a/frappe/app.py +++ b/frappe/app.py @@ -58,6 +58,8 @@ def application(request): frappe.handler.handle() elif frappe.request.path.startswith("/api/"): frappe.api.handle() + elif request.path.startswith('/backups'): + frappe.utils.download_backup(request.path) elif frappe.local.request.method in ('GET', 'HEAD'): frappe.website.render.render(frappe.request.path[1:]) else: diff --git a/frappe/installer.py b/frappe/installer.py index 59765f98fe..2224443253 100755 --- a/frappe/installer.py +++ b/frappe/installer.py @@ -167,9 +167,9 @@ def get_conf_params(db_name=None, db_password=None): def make_site_dirs(): site_public_path = os.path.join(frappe.local.site_path, 'public') + site_private_path = os.path.join(frappe.local.site_path, 'private') for dir_path in ( - os.path.join(site_public_path, 'backups'), - os.path.join(site_public_path, 'locks'), + os.path.join(site_private_path, 'backups'), os.path.join(site_public_path, 'files')): if not os.path.exists(dir_path): os.makedirs(dir_path) diff --git a/frappe/patches.txt b/frappe/patches.txt index cce8683f7f..7ac78cee1b 100644 --- a/frappe/patches.txt +++ b/frappe/patches.txt @@ -18,3 +18,4 @@ execute:frappe.reset_perms("Module Def") frappe.patches.4_0.rename_sitemap_to_route frappe.patches.4_0.set_website_route_idx execute:import frappe.installer;frappe.installer.make_site_dirs() #2014-02-19 +frappe.patches.4_0.private_backups diff --git a/frappe/utils/__init__.py b/frappe/utils/__init__.py index 8ede88bc85..802f6aecac 100644 --- a/frappe/utils/__init__.py +++ b/frappe/utils/__init__.py @@ -7,8 +7,11 @@ from __future__ import unicode_literals from werkzeug.test import Client import os import re +import mimetypes import urllib - +from werkzeug.wsgi import wrap_file +from werkzeug.wrappers import Response +from werkzeug.exceptions import NotFound, Unauthorized import frappe no_value_fields = ['Section Break', 'Column Break', 'HTML', 'Table', 'FlexTable', @@ -930,3 +933,28 @@ def touch_file(path): def get_test_client(): from frappe.app import application return Client(application) + +def download_backup(path): + try: + frappe.only_for(("System Manager", "Administrator")) + except frappe.PermissionError: + raise Unauthorized + send_private_file(path) + +def send_private_file(path): + path = path[1:] if path.startswith('/') else path + path = os.path.join(frappe.local.conf.get('private_path', 'private'), path) + + if frappe.local.request.headers.get('X-Use-X-Accel-Redirect'): + path = '/' + path + frappe.local._response.headers['X-Accel-Redirect'] = path + else: + filename = os.path.basename(path) + filepath = get_site_path(path) + try: + f = open(filepath, 'rb') + except IOError: + raise NotFound + frappe.local._response = Response(wrap_file(frappe.local.request.environ, f)) + frappe.local._response.headers.add('Content-Disposition', 'attachment', filename=filename) + frappe.local._response.headers['Content-Type'] = mimetypes.guess_type(filename)[0] or 'application/octet-stream' diff --git a/frappe/utils/backups.py b/frappe/utils/backups.py index 60346193b3..17c6831cf6 100644 --- a/frappe/utils/backups.py +++ b/frappe/utils/backups.py @@ -191,7 +191,7 @@ def is_file_old(db_file_name, older_than=24): def get_backup_path(): import os - backup_path = frappe.utils.get_site_path(conf.get("backup_path", "public/backups")) + backup_path = frappe.utils.get_site_path(conf.get("backup_path", "private/backups")) return backup_path #-------------------------------------------------------------------------------