Skip to content

Commit

Permalink
Merge pull request #365 from hammerlab/secure-unique
Browse files Browse the repository at this point in the history
Ensure unique filenames when uploading VCFs
  • Loading branch information
danvk committed Dec 5, 2014
2 parents 7dceea3 + 1d2a575 commit e4440ba
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 5 deletions.
19 changes: 19 additions & 0 deletions cycledash/helpers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
"""Module containing helper methods for the app in general."""
import os
import re

from flask import jsonify
from werkzeug.utils import secure_filename


RE_CAMELCASE_1 = re.compile('((?!^)[A-Z](?=[a-z0-9][^A-Z])|(?<=[a-z])[A-Z])')
Expand Down Expand Up @@ -71,3 +73,20 @@ def make_error_response(error, message):
response = jsonify({'error': error, 'message': message})
response.status_code = 400
return response


def get_secure_unique_filename(filename, tmp_dir):
"""Returns a safe, absolute path to a non-existent file.
This is just like werkzeug.secure_filename, except that it will modify the
file name to ensure that the file it returns doesn't already exists.
"""
# keep adding different digits to the file name until it doesn't exist.
count = 0
while True:
prefix = str(count) if count else ''
dest_filename = secure_filename(prefix + filename)
path = os.path.join(tmp_dir, dest_filename)
if not os.path.exists(path):
return path
count += 1
8 changes: 3 additions & 5 deletions cycledash/views.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
"""Defines all views for CycleDash."""
import collections
import json
import os

from celery import chain
from flask import (request, redirect, Response, render_template, jsonify,
url_for, abort)
import requests
from werkzeug.utils import secure_filename

from cycledash import app, db
import cycledash.genotypes as gt
from cycledash.helpers import prepare_request_data, update_object, make_error_response
from cycledash.helpers import prepare_request_data, update_object, \
make_error_response, get_secure_unique_filename
from cycledash.validations import UpdateRunSchema, CreateRunSchema

import workers.indexer
Expand Down Expand Up @@ -106,9 +105,8 @@ def upload():
if not f.filename.endswith('.vcf'):
return make_error_response('Invalid extension', 'File must end with .vcf')

dest_filename = secure_filename(f.filename)
tmp_dir = app.config['TEMPORARY_DIR']
dest_path = os.path.join(tmp_dir, dest_filename)
dest_path = get_secure_unique_filename(f.filename, tmp_dir)
f.save(dest_path)

return 'file://' + dest_path

0 comments on commit e4440ba

Please sign in to comment.