From 4f6f421b403abbf02225bbefc274dfda7eb00490 Mon Sep 17 00:00:00 2001 From: Ville Rantanen Date: Fri, 26 Jan 2018 22:07:45 +0200 Subject: [PATCH] css tuning. disallow too large zips --- code/app.py | 40 +++++++++++++++++++++++++++++--------- code/static/css/styles.css | 14 +++++++++++++ code/templates/list.html | 2 +- data/config.json.example | 4 +++- 4 files changed, 49 insertions(+), 11 deletions(-) diff --git a/code/app.py b/code/app.py index 41bcf97..0059d79 100644 --- a/code/app.py +++ b/code/app.py @@ -18,6 +18,7 @@ config_values = json.load(open(os.getenv('FLEES_CONFIG'),'rt')) app.config['UPLOAD_FOLDER'] = config_values['data_folder'] app.config['SHARES_FILE'] = config_values['shares_file'] app.config['ZIP_FOLDER'] = config_values['zip_folder'] +app.config['MAX_ZIP_SIZE'] = config_values['max_zip_size'] # megabytes app.config['DATE_FORMAT'] = config_values['date_format'] app.config['UID'] = config_values['uid'] app.config['DEBUG'] = config_values['debug'] @@ -102,7 +103,10 @@ def list_view(name, password = None): return share files = [] for file in sorted(os.listdir(share['path'])): - status = file_stat(os.path.join(share['path'],file)) + fp = os.path.join(share['path'],file) + if os.path.isdir(fp): + continue + status = file_stat(fp) status.update({ 'token': get_direct_token(share, file) }) @@ -173,10 +177,13 @@ def download_zip(name,password = None): (ok,share) = get_share(name) if not ok: return share + folder_size = get_folder_size(share['path']) + if folder_size/(1024*1024) > app.config['MAX_ZIP_SIZE']: + return "Maximum ZIP size exceeded", 400 zip_clean() zip_path = zip_share(share) return send_file( - zip_path, + zip_path, as_attachment = True, attachment_filename = name + ".zip" ) @@ -216,6 +223,18 @@ def get_direct_token(share, filename): share['pass_hash'].encode('utf-8') + filename.encode('utf-8') ).hexdigest() +def get_folder_size(path): + + total_size = 0 + for filename in os.listdir(path): + fp = os.path.join(path, filename) + if os.path.isdir(fp): + continue + total_size += os.path.getsize( + fp + ) + return total_size + def get_or_none(d,key): if key in d: @@ -227,7 +246,7 @@ def get_or_none(d,key): def get_share(name, require_auth = True): share = [x for x in g.shares if x['name'] == name] if len(share) < 1: - return (False,'No such share') + return (False,redirect(url_for('authenticate',name=name))) share = share[0] if is_expired(share): return (False, 'Share has expired') @@ -274,23 +293,26 @@ def print_debug(s): def zip_share(share): - + if not os.path.exists(app.config['ZIP_FOLDER']): os.makedirs(app.config['ZIP_FOLDER']) os.chown(app.config['ZIP_FOLDER'], app.config['UID'], -1) zip_path = os.path.join( app.config['ZIP_FOLDER'], - "%s-%d.zip"%( - share['name'], + "%s-%d.zip"%( + share['name'], time.time() ) ) zf = zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) for file in sorted(os.listdir(share['path'])): - print_debug(os.path.join(share['path'],file)) + fp = os.path.join(share['path'], file) + if os.path.isdir(fp): + continue + print_debug(fp) zf.write( - os.path.join(share['path'],file), + fp, arcname = os.path.join(share['name'],file) ) zf.close() @@ -309,7 +331,7 @@ def zip_clean(): ).st_mtime if mtime + 3600 < time.time(): os.remove(os.path.join(app.config['ZIP_FOLDER'],file)) - + if __name__ == "__main__": app.run(debug=True) diff --git a/code/static/css/styles.css b/code/static/css/styles.css index 42fc7c0..20a87fc 100755 --- a/code/static/css/styles.css +++ b/code/static/css/styles.css @@ -23,6 +23,7 @@ a:link { #footer { position: absolute; bottom: 0; + left: 9vw; width: 80vw; height: 23px; background: #f3f3fb; @@ -63,16 +64,29 @@ tr:nth-child(even) { border: 4px solid lightslategray; background-color: #f3f3fb; line-height: 1.5em; + position: relative; } #list_menu ul { margin-top: 0px; + margin-bottom: 0px; +} +#list_upload { + margin-bottom: 0.5em; +} +#list_upload_select { + width: 200px; +} +#list_upload_button { + position: absolute; + right: 8px; } #list_table { border-collapse: collapse; margin-left: 2em; line-height: 1.5em; + margin-bottom: 33px; } .direct { diff --git a/code/templates/list.html b/code/templates/list.html index 7eafc08..3045601 100644 --- a/code/templates/list.html +++ b/code/templates/list.html @@ -5,7 +5,7 @@
- +
diff --git a/data/config.json.example b/data/config.json.example index eacdd82..3974d3d 100644 --- a/data/config.json.example +++ b/data/config.json.example @@ -2,7 +2,8 @@ "__comment": [ "workers: number of parallel processes. single long upload reserves a process.", "timeout: seconds for process to last. single long upload cant take longer than this.", - "uid: Docker runs as root, this changes owner of written files. -1 to skip chowning" + "uid: Docker runs as root, this changes owner of written files. -1 to skip chowning", + "max_zip_size: dont allow zip downloads if folder size exceeds this many megabytes" ], "workers": 8, "timeout": 3600, @@ -11,6 +12,7 @@ "data_folder": "data", "shares_file": "data/shares.json", "zip_folder": "data/.zip", + "max_zip_size": 1000, "date_format": "%Y-%m-%d %H:%M", "debug": false }