direct links
This commit is contained in:
@@ -29,5 +29,7 @@ location /flees/ {
|
||||
- http://host/download/[share name]/[hashed password]/[filename]
|
||||
- upload with curl (etc.)
|
||||
- curl -F file=@my.file http://host/upload/[share name]/[hashed password]
|
||||
- "direct link" is a sharing link that does not require other passwords, and is unique to each file.
|
||||
(there should be no danger in sharing a file, and the password to rest of the files leaking)
|
||||
|
||||
|
||||
|
||||
60
code/app.py
60
code/app.py
@@ -93,7 +93,13 @@ def list_view(name, password = None):
|
||||
return share
|
||||
files = []
|
||||
for file in sorted(os.listdir(share['path'])):
|
||||
files.append(file_stat(os.path.join(share['path'],file)))
|
||||
status = file_stat(os.path.join(share['path'],file))
|
||||
status.update({
|
||||
'token': get_direct_token(share, file)
|
||||
})
|
||||
files.append(status)
|
||||
# direct share links not allowed if password isnt set
|
||||
allow_direct = get_or_none(share,'direct_links') if get_or_none(share,'pass_hash') else False
|
||||
return render_template(
|
||||
"list.html",
|
||||
name = share['name'],
|
||||
@@ -102,7 +108,7 @@ def list_view(name, password = None):
|
||||
public = get_or_none(share,'public'),
|
||||
upload = get_or_none(share,'upload'),
|
||||
overwrite = get_or_none(share,'overwrite'),
|
||||
direct = get_or_none(share,'direct_links'),
|
||||
direct = allow_direct,
|
||||
expire = get_or_none(share,'expire')
|
||||
)
|
||||
|
||||
@@ -115,12 +121,27 @@ def logout(name, password = None):
|
||||
name = name
|
||||
)
|
||||
|
||||
@app.route('/direct/<name>/<password>/<filename>', methods=['GET'])
|
||||
def download_direct(name,password,filename):
|
||||
if password != None:
|
||||
session[name] = password
|
||||
(ok,share) = get_share(name, require_auth = False)
|
||||
if not ok:
|
||||
return share
|
||||
token = get_direct_token(share, filename)
|
||||
if token == None:
|
||||
return 'Cannot generate token', 400
|
||||
if password != token:
|
||||
return 'Incorrect token', 403
|
||||
file_path = os.path.join(share['path'], filename)
|
||||
if not os.path.exists(file_path):
|
||||
return 'no such file', 404
|
||||
return send_from_directory(directory=share['path'], filename=filename)
|
||||
|
||||
|
||||
@app.route('/download/<name>/<password>/<filename>', methods=['GET'])
|
||||
@app.route('/download/<name>/<filename>', methods=['GET'])
|
||||
def download_file(name,filename,password = None):
|
||||
if password != None:
|
||||
session[name] = password
|
||||
(ok,share) = get_share(name)
|
||||
if not ok:
|
||||
return share
|
||||
@@ -151,6 +172,12 @@ def file_date_human(num):
|
||||
).strftime(app.config['DATE_FORMAT'])
|
||||
|
||||
|
||||
def get_direct_token(share, filename):
|
||||
if not 'pass_hash' in share:
|
||||
return None
|
||||
return hashlib.sha1(
|
||||
share['pass_hash'].encode('utf-8') + filename.encode('utf-8')
|
||||
).hexdigest()
|
||||
|
||||
|
||||
def get_or_none(d,key):
|
||||
@@ -159,7 +186,8 @@ def get_or_none(d,key):
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_share(name):
|
||||
|
||||
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')
|
||||
@@ -167,16 +195,18 @@ def get_share(name):
|
||||
if is_expired(share):
|
||||
return (False, 'Share has expired')
|
||||
authenticated = True
|
||||
if 'pass_hash' in share:
|
||||
authenticated = False
|
||||
if name in session:
|
||||
if session[name] == share['pass_hash']:
|
||||
authenticated = True
|
||||
if 'pass_plain' in share:
|
||||
authenticated = False
|
||||
if name in session:
|
||||
if session[name] == hashlib.sha1(share['pass_plain'].encode('utf-8')).hexdigest():
|
||||
authenticated = True
|
||||
if require_auth:
|
||||
if 'pass_plain' in share:
|
||||
authenticated = False
|
||||
if name in session:
|
||||
if session[name] == hashlib.sha1(share['pass_plain'].encode('utf-8')).hexdigest():
|
||||
authenticated = True
|
||||
if 'pass_hash' in share:
|
||||
authenticated = False
|
||||
if name in session:
|
||||
if session[name] == share['pass_hash']:
|
||||
authenticated = True
|
||||
|
||||
if not authenticated:
|
||||
return (False,redirect(url_for('authenticate',name=name)))
|
||||
if not 'path' in share:
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
<tr>
|
||||
<td><a href="{{ url_for('download_file', name = name, filename = entry.name) }}">{{ entry.name }}</a>
|
||||
{% if direct %}
|
||||
<a href="{{ url_for('download_file', name = name, password = password, filename = entry.name ) }}" title="Direct share link">❖</a>
|
||||
<a href="{{ url_for('download_direct', name = name, password = entry.token, filename = entry.name ) }}" title="Direct share link">❖</a>
|
||||
{% endif %}
|
||||
<td class=td_right>{{ entry.size|safe }}
|
||||
<td>{{ entry.mtime|safe }}
|
||||
|
||||
Reference in New Issue
Block a user