From 4c92fdfb6caa2ec6a1755c21fad0cecc9698f58c Mon Sep 17 00:00:00 2001
From: Patrick Jentsch <p.jentsch@uni-bielefeld.de>
Date: Wed, 2 Dec 2020 14:26:17 +0100
Subject: [PATCH] Fix file path management and download bugs

---
 web/app/corpora/views.py |  8 ++++----
 web/app/jobs/views.py    | 13 +++++--------
 web/app/models.py        |  5 +++--
 3 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/web/app/corpora/views.py b/web/app/corpora/views.py
index 95f8681d..3bf1d7e6 100644
--- a/web/app/corpora/views.py
+++ b/web/app/corpora/views.py
@@ -234,7 +234,7 @@ def download_corpus_file(corpus_id, corpus_file_id):
             or current_user.is_administrator()):
         abort(403)
     return send_from_directory(as_attachment=True,
-                               directory=corpus_file.corpus.path,
+                               directory=os.path.dirname(corpus_file.path),
                                filename=corpus_file.filename)
 
 
@@ -382,8 +382,7 @@ def inspect_query_result(query_result_id):
     inspect_display_options_form = InspectDisplayOptionsForm(
         prefix='inspect-display-options-form'
     )
-    query_result_file_path = os.path.join(query_result.path, query_result.filename)  # noqa
-    with open(query_result_file_path, 'r') as query_result_file:
+    with open(query_result.path, 'r') as query_result_file:
         query_result_file_content = json.load(query_result_file)
     return render_template('corpora/query_results/inspect.html.j2',
                            query_result=query_result,
@@ -413,5 +412,6 @@ def download_query_result(query_result_id):
     if not (query_result.creator == current_user
             or current_user.is_administrator()):
         abort(403)
-    return send_from_directory(as_attachment=True, directory=query_result.path,
+    return send_from_directory(as_attachment=True,
+                               directory=os.path.dirname(query_result.path),
                                filename=query_result.filename)
diff --git a/web/app/jobs/views.py b/web/app/jobs/views.py
index 739f153c..ffb5df15 100644
--- a/web/app/jobs/views.py
+++ b/web/app/jobs/views.py
@@ -5,6 +5,7 @@ from . import jobs
 from . import tasks
 from ..decorators import admin_required
 from ..models import Job, JobInput, JobResult
+import os
 
 
 @jobs.route('/<int:job_id>')
@@ -32,14 +33,12 @@ def delete_job(job_id):
 @jobs.route('/<int:job_id>/inputs/<int:job_input_id>/download')
 @login_required
 def download_job_input(job_id, job_input_id):
-    job_input = JobInput.query.get_or_404(job_input_id)
-    if not job_input.job_id == job_id:
-        abort(404)
+    job_input = JobInput.query.filter(JobInput.job_id == job_id, JobInput.id == job_input_id).first_or_404()  # noqa
     if not (job_input.job.creator == current_user
             or current_user.is_administrator()):
         abort(403)
     return send_from_directory(as_attachment=True,
-                               directory=job_input.job.path,
+                               directory=os.path.dirname(job_input.path),
                                filename=job_input.filename)
 
 
@@ -59,12 +58,10 @@ def restart(job_id):
 @jobs.route('/<int:job_id>/results/<int:job_result_id>/download')
 @login_required
 def download_job_result(job_id, job_result_id):
-    job_result = JobResult.query.get_or_404(job_result_id)
-    if not job_result.job_id == job_id:
-        abort(404)
+    job_result = JobResult.query.filter(JobResult.job_id == job_id, JobResult.id == job_result_id).first_or_404()  # noqa
     if not (job_result.job.creator == current_user
             or current_user.is_administrator()):
         abort(403)
     return send_from_directory(as_attachment=True,
-                               directory=job_result.job.path,
+                               directory=os.path.dirname(job_result.path),
                                filename=job_result.filename)
diff --git a/web/app/models.py b/web/app/models.py
index 4dd9dba9..4ca7095f 100644
--- a/web/app/models.py
+++ b/web/app/models.py
@@ -311,7 +311,7 @@ class JobResult(db.Model):
 
     @property
     def path(self):
-        return os.path.join(self.job.path, self.filename)
+        return os.path.join(self.job.path, 'output', self.filename)
 
     def __repr__(self):
         '''
@@ -561,7 +561,8 @@ class QueryResult(db.Model):
 
     @property
     def path(self):
-        return os.path.join(self.creator.path, 'query_results', str(self.id))
+        return os.path.join(
+            self.creator.path, 'query_results', str(self.id), self.filename)
 
     def delete(self):
         shutil.rmtree(self.path, ignore_errors=True)
-- 
GitLab