From 162e851b312dddc0c208ace55492ee383d455a8f Mon Sep 17 00:00:00 2001 From: Chris Schnaufer Date: Fri, 22 Oct 2021 14:54:05 -0700 Subject: [PATCH 1/3] Updated timeout --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index b19881d..736905b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -80,4 +80,4 @@ ENV PYTHONPATH="${PYTHONPATH}:/app/react_frontend" \ SECRET_KEY=$SECRET_KEY \ ATLANA_USE_SCIF_WORKFLOW= -ENTRYPOINT gunicorn -w 4 -b ${WEB_SITE_URL} --access-logfile '-' main:app +ENTRYPOINT gunicorn -w 4 -b ${WEB_SITE_URL} --access-logfile '-' main:app --timeout 18000 From f44b829b0a210feaf9b2d14314d509daf57fa224 Mon Sep 17 00:00:00 2001 From: Chris Schnaufer Date: Tue, 9 Nov 2021 15:28:16 -0700 Subject: [PATCH 2/3] Env variable for additional local folders --- main.py | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 6 deletions(-) diff --git a/main.py b/main.py index 3288e6f..29849b5 100644 --- a/main.py +++ b/main.py @@ -16,8 +16,9 @@ import traceback import subprocess import sys -from typing import Union +from typing import Optional, Union from crypt import Crypt +from pathlib import Path from irods.session import iRODSSession from irods.data_object import chunks import irods.exception @@ -30,6 +31,45 @@ from workflow_definitions import WORKFLOW_DEFINITIONS +def _get_additional_folders() -> Optional[dict]: + """Returns additional user accessible folders""" + folder_defs = os.getenv('MORE_FOLDERS') + if not folder_defs: + return None + + return_defs = {} + + folder_defs = folder_defs.split(';') if ';' in folder_defs else [folder_defs] + + for one_def in folder_defs: + if ':' not in one_def: + print(f'Skipping invalid additional folder: "{one_def}"') + continue + + try: + def_name, def_path = [part.strip() for part in one_def.split(':')] + except ValueError: + print(f'ValueError exception caught while splitting additional folder: "{one_def}"') + print(' continuing processing') + continue + + if not def_name or not def_path: + print(f'Invalid additional folder missing a name or a path: "{one_def}"') + continue + + def_path = os.path.realpath(def_path) + if not os.path.isdir(def_path): + print(f'Path for additional folder "{def_path}" is not found: "{one_def}"') + print(' skipping invalid path') + continue + + if def_name in return_defs: + print(f'Current additional folder "{one_def}" overwriting previous definition "{def_name}:{return_defs[def_name]}"') + + return_defs[def_name] = def_path + + return return_defs + def _get_secret_key() -> str: """Returns a value to be used as a secret key""" cur_key = os.getenv('SECRET_KEY') @@ -86,6 +126,9 @@ def create_app(config_file: str = None) -> Flask: # Create the CORS handler cors = CORS(app, resources={r"/files": {"origins": "http://127.0.0.1:3000"}}) +# Additional folders to allow user access +ADDITIONAL_LOCAL_FOLDERS=_get_additional_folders() + # The default page to serve up DEFAULT_TEMPLATE_PAGE='index.html' @@ -1027,6 +1070,24 @@ def upload_file(): return json.dumps(loaded_filenames) +def _handle_files_get_path(working_path: str, upload_folder: str, additional_folders: dict) -> Optional[str]: + """Returns the path to search when returning server files list""" + # Check if it's an additional path as defined on startup + if len(working_path) > 1: + dir_name = Path(working_path).parts[1] + if dir_name in additional_folders: + return os.path.join(additional_folders[dir_name], working_path[len(dir_name) + 2:]) + + # Might be a user specific path + if working_path[0] == '/': + working_path = '.' + working_path + cur_path = os.path.abspath(os.path.join(upload_folder, working_path)) + if not cur_path.startswith(upload_folder): + return None + + return cur_path + + @app.route('/server/files', methods=['GET']) @cross_origin(origin='127.0.0.1:3000', headers=['Content-Type','Authorization']) def handle_files() -> tuple: @@ -1051,12 +1112,10 @@ def handle_files() -> tuple: if 'upload_folder' not in session or session['upload_folder'] is None or not os.path.isdir(session['upload_folder']): session['upload_folder'] = tempfile.mkdtemp(dir=FILE_START_PATH) + working_path = normalize_path(path) try: - working_path = normalize_path(path) - if working_path[0] == '/': - working_path = '.' + working_path - cur_path = os.path.abspath(os.path.join(session['upload_folder'], working_path)) - if not cur_path.startswith(session['upload_folder']): + cur_path = _handle_files_get_path(working_path, session['upload_folder'], ADDITIONAL_LOCAL_FOLDERS) + if not cur_path: print(f'Invalid path requested: "{path}"', flush=True) return 'Resource not found', 400 except FileNotFoundError as ex: @@ -1076,6 +1135,15 @@ def handle_files() -> tuple: 'type': 'folder' if os.path.isdir(file_path) else 'file' }) + if ADDITIONAL_LOCAL_FOLDERS and path == '/': + for one_name, _ in ADDITIONAL_LOCAL_FOLDERS.items(): + return_names.append({'name': one_name, + 'path': '/' + one_name, + 'size': 0, + 'date': '', + 'type': 'folder' + }) + return json.dumps(return_names) From 04a731611caad48d4b00af2054036702b0bcbf54 Mon Sep 17 00:00:00 2001 From: Chris Schnaufer Date: Tue, 9 Nov 2021 15:55:25 -0700 Subject: [PATCH 3/3] Updated copying files from additional local folders --- main.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 29849b5..c4ae9b7 100644 --- a/main.py +++ b/main.py @@ -491,6 +491,15 @@ def copy_server_file(auth: dict, source_path: str, dest_path: str) -> bool: """ # pylint: disable=unused-argument working_path = normalize_path(source_path) + + # Check if we have a special path + if len(working_path) > 1: + dir_name = Path(working_path).parts[1] + if ADDITIONAL_LOCAL_FOLDERS and dir_name in ADDITIONAL_LOCAL_FOLDERS: + cur_path = os.path.join(ADDITIONAL_LOCAL_FOLDERS[dir_name], working_path[len(dir_name) + 2:]) + shutil.copyfile (cur_path, dest_path) + return True + if working_path[0] == '/': working_path = '.' + working_path cur_path = os.path.abspath(os.path.join(session['upload_folder'], working_path)) @@ -1075,7 +1084,7 @@ def _handle_files_get_path(working_path: str, upload_folder: str, additional_fol # Check if it's an additional path as defined on startup if len(working_path) > 1: dir_name = Path(working_path).parts[1] - if dir_name in additional_folders: + if additional_folders and dir_name in additional_folders: return os.path.join(additional_folders[dir_name], working_path[len(dir_name) + 2:]) # Might be a user specific path