From cbd1d01203e789d4c6b5f49f73fddd41275cdaa2 Mon Sep 17 00:00:00 2001 From: Kelly McDonald Date: Wed, 5 May 2021 11:30:08 -0400 Subject: [PATCH] Add URL to the study_info('documents') script fixes #321 - I merged in branches that fix #320 and #297 320-add-default-for-file-data-get 297-filename-in-documents --- crc/api.yml | 35 +++++++++++++++++++ crc/api/file.py | 17 +++++++++ crc/services/study_service.py | 12 +++++++ .../data/file_data_store/file_data_store.bpmn | 4 +++ tests/test_file_datastore.py | 2 ++ 5 files changed, 70 insertions(+) diff --git a/crc/api.yml b/crc/api.yml index 980d6d13..81d45f3a 100644 --- a/crc/api.yml +++ b/crc/api.yml @@ -705,6 +705,41 @@ paths: type: string format: binary example: '' + /file/{file_id}/download : + parameters : + - name : file_id + in : path + required : true + description : The id of the File requested + schema : + type : integer + - name : auth_token + in : query + required : true + description : User Auth Toeken + schema : + type : string + - name : version + in : query + required : false + description : The version of the file, or none for latest version + schema : + type : integer + get : + operationId : crc.api.file.get_file_data_link + summary : Returns only the file contents + security: [] + tags : + - Files + responses : + '200' : + description : Returns the actual file + content : + application/octet-stream : + schema : + type : string + format : binary + example : '' /file/{file_id}/data: parameters: - name: file_id diff --git a/crc/api/file.py b/crc/api/file.py index 743d6327..619fd7ec 100644 --- a/crc/api/file.py +++ b/crc/api/file.py @@ -6,6 +6,7 @@ from flask import send_file from crc import session from crc.api.common import ApiError +from crc.api.user import verify_token from crc.models.api_models import DocumentDirectory, DocumentDirectorySchema from crc.models.file import FileSchema, FileModel, File, FileModelSchema, FileDataModel, FileType from crc.models.workflow import WorkflowSpecModel @@ -179,6 +180,22 @@ def get_file_data(file_id, version=None): ) +def get_file_data_link(file_id, auth_token, version=None): + if not verify_token(auth_token): + raise ApiError('not_authenticated', 'You need to include an authorization token in the URL with this') + file_data = FileService.get_file_data(file_id, version) + if file_data is None: + raise ApiError('no_such_file', 'The file id you provided does not exist') + return send_file( + io.BytesIO(file_data.data), + attachment_filename=file_data.file_model.name, + mimetype=file_data.file_model.content_type, + cache_timeout=-1, # Don't cache these files on the browser. + last_modified=file_data.date_created, + as_attachment = True + ) + + def get_file_info(file_id): file_model = session.query(FileModel).filter_by(id=file_id).with_for_update().first() if file_model is None: diff --git a/crc/services/study_service.py b/crc/services/study_service.py index 7774d2cc..4aa7a0a5 100644 --- a/crc/services/study_service.py +++ b/crc/services/study_service.py @@ -1,7 +1,9 @@ +import urllib from copy import copy from datetime import datetime from typing import List +import flask import requests from SpiffWorkflow import WorkflowException from SpiffWorkflow.exceptions import WorkflowTaskExecException @@ -288,9 +290,19 @@ class StudyService(object): doc_files = FileService.get_files_for_study(study_id=study_id, irb_doc_code=code) doc['count'] = len(doc_files) doc['files'] = [] + + # when we run tests - it doesn't look like the user is available + # so we return a bogus token + token = 'not_available' + if hasattr(flask.g,'user'): + token = flask.g.user.encode_auth_token() for file in doc_files: doc['files'].append({'file_id': file.id, 'name': file.name, + 'url': app.config['APPLICATION_ROOT']+ + 'file/' + str(file.id) + + '/download?auth_token='+ + urllib.parse.quote_plus(token), 'workflow_id': file.workflow_id}) # update the document status to match the status of the workflow it is in. diff --git a/tests/data/file_data_store/file_data_store.bpmn b/tests/data/file_data_store/file_data_store.bpmn index 9af77bb0..ddc9e987 100644 --- a/tests/data/file_data_store/file_data_store.bpmn +++ b/tests/data/file_data_store/file_data_store.bpmn @@ -18,6 +18,10 @@ fileid = documents['UVACompl_PRCAppr'].files[0]['file_id'] +fileurl = documents['UVACompl_PRCAppr'].files[0]['url'] + +filename = documents['UVACompl_PRCAppr'].files[0]['name'] + file_data_set(file_id=fileid,key='test',value='me') diff --git a/tests/test_file_datastore.py b/tests/test_file_datastore.py index 2b95519e..1a10eea7 100644 --- a/tests/test_file_datastore.py +++ b/tests/test_file_datastore.py @@ -27,6 +27,8 @@ class TestFileDatastore(BaseTest): processor = WorkflowProcessor(workflow) processor.do_engine_steps() task_data = processor.bpmn_workflow.last_task.data + self.assertTrue(str(task_data['fileid']) in task_data['fileurl']) + self.assertEqual(task_data['filename'],'anything.png') self.assertEqual(task_data['output'], 'me') self.assertEqual(task_data['output2'], 'nope')