fixed error in refactoring, changed auth-system to multi token, cleanup after major change
This commit is contained in:
parent
48bf325d77
commit
4961c398a5
@ -7,13 +7,13 @@ def message(category, text):
|
|||||||
sep = " "
|
sep = " "
|
||||||
else:
|
else:
|
||||||
sep = "--"
|
sep = "--"
|
||||||
print "%s %s%s[%s]%s%s" % (
|
print("%s %s%s[%s]%s%s" % (
|
||||||
datetime.now().isoformat(),
|
datetime.now().isoformat(),
|
||||||
max(0, message.level) * " |",
|
max(0, message.level) * " |",
|
||||||
sep,
|
sep,
|
||||||
category,
|
category,
|
||||||
max(1, (14 - len(category))) * " ",
|
max(1, (14 - len(category))) * " ",
|
||||||
text)
|
text))
|
||||||
message.level = -1
|
message.level = -1
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,17 +3,17 @@ from mimetypes import guess_type
|
|||||||
from random import shuffle
|
from random import shuffle
|
||||||
|
|
||||||
from flask import Response, abort, json, jsonify, request
|
from flask import Response, abort, json, jsonify, request
|
||||||
from flask_login import current_user, login_user
|
from flask_login import current_user, login_user, logout_user
|
||||||
|
|
||||||
from floatapp import app
|
from floatapp import app
|
||||||
from floatapp.jsonp import jsonp
|
from floatapp.jsonp import jsonp
|
||||||
from floatapp.login import (admin_required, admin_user, is_authenticated,
|
from floatapp.login import (admin_required, admin_user,
|
||||||
login_required, photo_user, query_is_admin_user,
|
query_is_admin_user, load_user)
|
||||||
query_is_photo_user)
|
|
||||||
from process import send_process
|
from process import send_process
|
||||||
from TreeWalker import TreeWalker
|
from TreeWalker import TreeWalker
|
||||||
|
|
||||||
cwd = os.path.dirname(os.path.abspath(__file__))
|
cwd = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
permission_map = app.config.get('PERMISSION_MAP', [])
|
||||||
|
|
||||||
|
|
||||||
@app.route("/scan")
|
@app.route("/scan")
|
||||||
@ -23,7 +23,6 @@ def scan_photos():
|
|||||||
response = send_process([
|
response = send_process([
|
||||||
"stdbuf",
|
"stdbuf",
|
||||||
"-oL",
|
"-oL",
|
||||||
os.path.abspath(os.path.join(cwd, "../venv/bin/python")),
|
|
||||||
os.path.abspath(os.path.join(cwd, "../main.py")),
|
os.path.abspath(os.path.join(cwd, "../main.py")),
|
||||||
os.path.abspath(app.config["ALBUM_PATH"]),
|
os.path.abspath(app.config["ALBUM_PATH"]),
|
||||||
os.path.abspath(app.config["CACHE_PATH"])
|
os.path.abspath(app.config["CACHE_PATH"])
|
||||||
@ -36,20 +35,80 @@ def scan_photos():
|
|||||||
|
|
||||||
@app.route("/auth")
|
@app.route("/auth")
|
||||||
def login():
|
def login():
|
||||||
success = False
|
if request.args.get('logout'):
|
||||||
|
logout_user()
|
||||||
|
|
||||||
if current_user.is_authenticated:
|
if current_user.is_authenticated:
|
||||||
success = True
|
return 'Already logged in.'
|
||||||
elif (query_is_photo_user(request.form) or
|
|
||||||
query_is_photo_user(request.args)):
|
|
||||||
success = login_user(photo_user, remember=True)
|
|
||||||
elif (query_is_admin_user(request.form) or
|
elif (query_is_admin_user(request.form) or
|
||||||
query_is_admin_user(request.args)):
|
query_is_admin_user(request.args)):
|
||||||
success = login_user(admin_user, remember=True)
|
login_user(admin_user, remember=True)
|
||||||
if not success:
|
else:
|
||||||
abort(403)
|
user_id = (request.form.get('username') or
|
||||||
|
request.args.get('username', None))
|
||||||
|
if user_id:
|
||||||
|
login_user(load_user(user_id), remember=True)
|
||||||
|
print "logged in {}".format(user_id)
|
||||||
|
return 'You are now logged in.'
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/albums/<path:path>")
|
||||||
|
def albums(path):
|
||||||
|
if not has_permission(path):
|
||||||
|
abort(403)
|
||||||
|
|
||||||
|
return accel_redirect(
|
||||||
|
app.config["ALBUM_ACCEL"], app.config["ALBUM_PATH"], path)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/cache/<path:path>")
|
||||||
|
def cache(path):
|
||||||
|
if not has_permission(path):
|
||||||
|
abort(403)
|
||||||
|
|
||||||
|
return accel_redirect(
|
||||||
|
app.config["CACHE_ACCEL"], app.config["CACHE_PATH"], path)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/photos")
|
||||||
|
@jsonp
|
||||||
|
def photos():
|
||||||
|
f = open(os.path.join(app.config["CACHE_PATH"], "all_photos.json"), "r")
|
||||||
|
photos = json.load(f)
|
||||||
|
f.close()
|
||||||
|
photos = [photo for photo in photos if has_permission(photo)]
|
||||||
|
count = int(request.args.get("count", len(photos)))
|
||||||
|
random = request.args.get("random") == "true"
|
||||||
|
if random:
|
||||||
|
shuffle(photos)
|
||||||
|
else:
|
||||||
|
photos.reverse()
|
||||||
|
response = jsonify(photos=photos[0:count])
|
||||||
|
response.cache_control.no_cache = True
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def accel_redirect(internal, real, relative_name):
|
||||||
|
real_path = os.path.join(real, relative_name)
|
||||||
|
internal_path = os.path.join(internal, relative_name)
|
||||||
|
if not os.path.isfile(real_path):
|
||||||
|
abort(404)
|
||||||
|
mimetype = None
|
||||||
|
types = guess_type(real_path)
|
||||||
|
if len(types) != 0:
|
||||||
|
mimetype = types[0]
|
||||||
|
response = Response(mimetype=mimetype)
|
||||||
|
response.headers.add("X-Accel-Redirect", internal_path)
|
||||||
|
response.cache_control.public = True
|
||||||
|
if mimetype == "application/json":
|
||||||
|
response.cache_control.max_age = 3600
|
||||||
|
else:
|
||||||
|
response.cache_control.max_age = 29030400
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
def cache_base(path):
|
def cache_base(path):
|
||||||
path = path.replace(
|
path = path.replace(
|
||||||
'/', '-').replace(
|
'/', '-').replace(
|
||||||
@ -77,84 +136,15 @@ def cache_base(path):
|
|||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
auth_list = []
|
def has_permission(path):
|
||||||
|
for auth_path in permission_map.keys():
|
||||||
|
# this is a protected object
|
||||||
def read_auth_list():
|
if (path.startswith(auth_path) or
|
||||||
global auth_list, cwd
|
path.startswith(cache_base(auth_path))):
|
||||||
f = open(os.path.join(cwd, "auth.txt"), "r")
|
if current_user.is_anonymous:
|
||||||
paths = []
|
return False
|
||||||
for path in f:
|
if current_user.id in permission_map.get(auth_path, []):
|
||||||
path = path.strip()
|
return True
|
||||||
paths.append(path)
|
else:
|
||||||
paths.append(cache_base(path))
|
return False
|
||||||
f.close()
|
return True
|
||||||
auth_list = paths
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: Make this run via inotify
|
|
||||||
read_auth_list()
|
|
||||||
|
|
||||||
|
|
||||||
def check_permissions(path):
|
|
||||||
if not is_authenticated():
|
|
||||||
for auth_path in auth_list:
|
|
||||||
if path.startswith(auth_path):
|
|
||||||
abort(403)
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/albums/<path:path>")
|
|
||||||
def albums(path):
|
|
||||||
check_permissions(path)
|
|
||||||
return accel_redirect(
|
|
||||||
app.config["ALBUM_ACCEL"], app.config["ALBUM_PATH"], path)
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/cache/<path:path>")
|
|
||||||
def cache(path):
|
|
||||||
check_permissions(path)
|
|
||||||
return accel_redirect(
|
|
||||||
app.config["CACHE_ACCEL"], app.config["CACHE_PATH"], path)
|
|
||||||
|
|
||||||
|
|
||||||
def accel_redirect(internal, real, relative_name):
|
|
||||||
real_path = os.path.join(real, relative_name)
|
|
||||||
internal_path = os.path.join(internal, relative_name)
|
|
||||||
if not os.path.isfile(real_path):
|
|
||||||
abort(404)
|
|
||||||
mimetype = None
|
|
||||||
types = guess_type(real_path)
|
|
||||||
if len(types) != 0:
|
|
||||||
mimetype = types[0]
|
|
||||||
response = Response(mimetype=mimetype)
|
|
||||||
response.headers.add("X-Accel-Redirect", internal_path)
|
|
||||||
response.cache_control.public = True
|
|
||||||
if mimetype == "application/json":
|
|
||||||
response.cache_control.max_age = 3600
|
|
||||||
else:
|
|
||||||
response.cache_control.max_age = 29030400
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/photos")
|
|
||||||
@jsonp
|
|
||||||
def photos():
|
|
||||||
f = open(os.path.join(app.config["CACHE_PATH"], "all_photos.json"), "r")
|
|
||||||
photos = json.load(f)
|
|
||||||
f.close()
|
|
||||||
if not is_authenticated():
|
|
||||||
def allowed(photo):
|
|
||||||
for auth_path in auth_list:
|
|
||||||
if photo.startswith(auth_path):
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
photos = [photo for photo in photos if allowed(photo)]
|
|
||||||
count = int(request.args.get("count", len(photos)))
|
|
||||||
random = request.args.get("random") == "true"
|
|
||||||
if random:
|
|
||||||
shuffle(photos)
|
|
||||||
else:
|
|
||||||
photos.reverse()
|
|
||||||
response = jsonify(photos=photos[0:count])
|
|
||||||
response.cache_control.no_cache = True
|
|
||||||
return response
|
|
||||||
|
@ -9,17 +9,20 @@ class User(UserMixin):
|
|||||||
self.admin = admin
|
self.admin = admin
|
||||||
self.id = id
|
self.id = id
|
||||||
|
|
||||||
photo_user = User("user")
|
def __unicode__(self):
|
||||||
|
return u"{}".format(self.id)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.id)
|
||||||
|
|
||||||
admin_user = User("admin", True)
|
admin_user = User("admin", True)
|
||||||
|
|
||||||
|
|
||||||
@login_manager.user_loader
|
@login_manager.user_loader
|
||||||
def load_user(id):
|
def load_user(id):
|
||||||
if id == "user":
|
if id == "admin":
|
||||||
return photo_user
|
|
||||||
elif id == "admin":
|
|
||||||
return admin_user
|
return admin_user
|
||||||
return None
|
return User(id)
|
||||||
|
|
||||||
|
|
||||||
@login_manager.unauthorized_handler
|
@login_manager.unauthorized_handler
|
||||||
@ -27,17 +30,6 @@ def unauthorized():
|
|||||||
return abort(403)
|
return abort(403)
|
||||||
|
|
||||||
|
|
||||||
def login_required(fn):
|
|
||||||
@wraps(fn)
|
|
||||||
def decorated_view(*args, **kwargs):
|
|
||||||
if (query_is_admin_user(request.args) or
|
|
||||||
query_is_photo_user(request.args) or
|
|
||||||
current_user.is_authenticated):
|
|
||||||
return fn(*args, **kwargs)
|
|
||||||
return app.login_manager.unauthorized()
|
|
||||||
return decorated_view
|
|
||||||
|
|
||||||
|
|
||||||
def admin_required(fn):
|
def admin_required(fn):
|
||||||
@wraps(fn)
|
@wraps(fn)
|
||||||
def decorated_view(*args, **kwargs):
|
def decorated_view(*args, **kwargs):
|
||||||
@ -48,21 +40,8 @@ def admin_required(fn):
|
|||||||
return decorated_view
|
return decorated_view
|
||||||
|
|
||||||
|
|
||||||
def query_is_photo_user(query):
|
|
||||||
username = query.get("username", None)
|
|
||||||
password = query.get("password", None)
|
|
||||||
return username == (app.config["PHOTO_USERNAME"] and
|
|
||||||
password == app.config["PHOTO_PASSWORD"])
|
|
||||||
|
|
||||||
|
|
||||||
def query_is_admin_user(query):
|
def query_is_admin_user(query):
|
||||||
username = query.get("username", None)
|
username = query.get("username", None)
|
||||||
password = query.get("password", None)
|
password = query.get("password", None)
|
||||||
return username == (app.config["ADMIN_USERNAME"] and
|
return (username == app.config["ADMIN_USERNAME"] and
|
||||||
password == app.config["ADMIN_PASSWORD"])
|
password == app.config["ADMIN_PASSWORD"])
|
||||||
|
|
||||||
|
|
||||||
def is_authenticated():
|
|
||||||
return (query_is_admin_user(request.args) or
|
|
||||||
query_is_photo_user(request.args) or
|
|
||||||
current_user.is_authenticated)
|
|
||||||
|
@ -11,11 +11,11 @@ def main():
|
|||||||
sys.setdefaultencoding("UTF-8")
|
sys.setdefaultencoding("UTF-8")
|
||||||
|
|
||||||
if len(sys.argv) != 3:
|
if len(sys.argv) != 3:
|
||||||
print "usage: %s ALBUM_PATH CACHE_PATH" % sys.argv[0]
|
print("usage: %s ALBUM_PATH CACHE_PATH" % sys.argv[0])
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.umask(022)
|
os.umask(0o22)
|
||||||
TreeWalker(sys.argv[1], sys.argv[2])
|
TreeWalker(sys.argv[1], sys.argv[2])
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
message("keyboard", "CTRL+C pressed, quitting.")
|
message("keyboard", "CTRL+C pressed, quitting.")
|
||||||
|
@ -92,7 +92,7 @@
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
type: "GET",
|
type: "GET",
|
||||||
dataType: "text",
|
dataType: "text",
|
||||||
url: "auth?username=photos&password=" + password,
|
url: "auth?username=" + password,
|
||||||
success: function() {
|
success: function() {
|
||||||
result(true);
|
result(true);
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user