diff options
-rw-r--r-- | assets/admin.css | 45 | ||||
-rw-r--r-- | backend/Admin.py | 65 | ||||
-rw-r--r-- | interface/admin_delete.tmpl | 35 | ||||
-rw-r--r-- | interface/admin_dirs.tmpl | 40 | ||||
-rw-r--r-- | interface/admin_files.tmpl | 31 |
5 files changed, 210 insertions, 6 deletions
diff --git a/assets/admin.css b/assets/admin.css new file mode 100644 index 0000000..4fdc5fb --- /dev/null +++ b/assets/admin.css @@ -0,0 +1,45 @@ +#dirlisting { + text-align: left; +} + +#create { + text-align: center; + padding: 2em 2em 0 2em; +} + +#message { + padding: 2em; + font-weight: bold; + font-size: 120%; + color: #302; + background-color: #df2266; + border-radius: 1em; + margin: 1em auto; + width: 50%; +} + +div.entry { + padding: 0.5em; + margin: 0.5em; + background-color: #4467ae55; + display: flex; + vertical-align: center; +} + +div.entry a.button { + padding: 0.5em; + background-color: #c8e; + text-decoration: none; + margin-left: 0.5em; + display: block; + border-radius: 0.5em; +} + +a.delete { + background-color: #f79 !important; +} + +a.directory { + text-decoration: none; + color: #aade88; +} diff --git a/backend/Admin.py b/backend/Admin.py index b88f4c7..a844aff 100644 --- a/backend/Admin.py +++ b/backend/Admin.py @@ -1,9 +1,62 @@ +import jinja2 +import os + import config -from utils import redirect +import utils + +template_factory = jinja2.Environment(loader=jinja2.FileSystemLoader('../interface/')) + +admin_dirs = template_factory.get_template("admin_dirs.tmpl") +admin_files = template_factory.get_template("admin_files.tmpl") +admin_delete = template_factory.get_template("admin_delete.tmpl") def route(path, env, post): - user = config.Auth.get(env) - if not user: - return redirect("/") - # TBD - return ["Admin panel for " + user["user"], [('Content-Type','text/html')], "200 OK"] + auth = config.Auth.get(env) + if not auth: + print("No authorized user for admin access") + return utils.redirect("/") + + # Directory overview + if len(path) == 1: + errmsg = None + if post and "new" in post: + try: + dirname = utils.sanitize_filename(post["new"][0]) + os.mkdir(utils.userdir(auth["user"]) + dirname) + except FileExistsError: + errmsg = "This directory already exists" + except ValueError: + errmsg = "The directory name was invalid" + + dirs = utils.dirlisting(utils.userdir(auth["user"]), False, True) + return [admin_dirs.render({"user": auth["user"], "listing": dirs, "error": errmsg}), [("Content-Type", "text/html")], "200 OK"] + + # File listing + if len(path) == 2 and path[1]: + directory = utils.userdir(auth["user"]) + utils.sanitize_filename(path[1]) + "/" + if not os.path.isdir(directory): + return utils.redirect("/admin") + files = utils.dirlisting(directory, True, False) + return [admin_files.render({"user": auth["user"], "listing": files, "directory": utils.sanitize_filename(path[1])}), [("Content-Type", "text/html")], "200 OK"] + + # Alias management / Limits config + # TODO + + # Renaming + # TODO + + # Deletion + if len(path) == 3 and path[2] == "delete": + directory = utils.userdir(auth["user"]) + utils.sanitize_filename(path[1]) + "/" + if not os.path.isdir(directory): + return utils.redirect("/admin") + files = utils.dirlisting(directory, True, False) + if len(files) == 0 or env.get("QUERY_STRING", "") == "confirm": + # TODO remove contents + # TODO remove aliases + os.rmdir(directory) + return utils.redirect("/admin") + return [admin_delete.render({"user": auth["user"], "listing": files, "directory": utils.sanitize_filename(path[1])}), [("Content-Type", "text/html")], "200 OK"] + + # Default case for admin / fallthrough + return utils.redirect("/") diff --git a/interface/admin_delete.tmpl b/interface/admin_delete.tmpl new file mode 100644 index 0000000..bf6d8a2 --- /dev/null +++ b/interface/admin_delete.tmpl @@ -0,0 +1,35 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="robots" content="noindex,nofollow" /> + <title>cargohold</title> + <link rel="stylesheet" href="/assets/cargohold.css" /> + <link rel="stylesheet" href="/assets/admin.css" /> + <link rel="icon" href="/assets/cargohold.ico" /> + </head> + <body> + <div id="header"> + cargohold - Administration + </div> + <div id="container"> + <div id="message"> + This will delete the directory <span class="highlight">{{ directory }}</span>. + <br /> + This directory still contains {{ listing | length }} files. + </div> + <div id="dirlisting"> + {% for file in listing %} + <div class="entry"> + <a class="file" href="#">{{ file.name }}</a> + </div> + {% endfor %} + </div> + <div id="action"> + <a class="button" href="/admin">Cancel</a> + <a class="button delete" href="?confirm">Confirm & delete</a> + </div> + </div> + </body> +</html> diff --git a/interface/admin_dirs.tmpl b/interface/admin_dirs.tmpl new file mode 100644 index 0000000..cebaa62 --- /dev/null +++ b/interface/admin_dirs.tmpl @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="robots" content="noindex,nofollow" /> + <title>cargohold</title> + <link rel="stylesheet" href="/assets/cargohold.css" /> + <link rel="stylesheet" href="/assets/admin.css" /> + <link rel="icon" href="/assets/cargohold.ico" /> + </head> + <body> + <div id="header"> + cargohold - Administration + </div> + <div id="container"> + {% if error %} + <div id="error"> + {{ error }} + </div> + {% endif %} + <div id="create"> + <form action="/admin" method="POST"> + <input type="text" name="new" placeholder="Create new folder" /> + <input type="submit" name="create" value="Create" /> + </form> + </div> + <div id="dirlisting"> + {% for dir in listing %} + <div class="entry"> + <a class="directory" href="/admin/{{dir.name}}">{{dir.name}}</a> + <a class="button" href="/admin/{{dir.name}}/rename">Rename</a> + <a class="button" href="/admin/{{dir.name}}/aliases">Aliases</a> + <a class="delete button" href="/admin/{{dir.name}}/delete">Delete</a> + </div> + {% endfor %} + </div> + </div> + </body> +</html> diff --git a/interface/admin_files.tmpl b/interface/admin_files.tmpl new file mode 100644 index 0000000..76b63d5 --- /dev/null +++ b/interface/admin_files.tmpl @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="robots" content="noindex,nofollow" /> + <title>cargohold</title> + <link rel="stylesheet" href="/assets/cargohold.css" /> + <link rel="stylesheet" href="/assets/admin.css" /> + <link rel="icon" href="/assets/cargohold.ico" /> + </head> + <body> + <div id="header"> + cargohold - Administration + </div> + <div id="container"> + {% if message %} + <div id="message"> + {{ message }} + </div> + {% endif %} + <div id="dirlisting"> + {% for file in listing %} + <div class="entry"> + <a class="file" href="#">{{ file.name }}</a> + </div> + {% endfor %} + </div> + </div> + </body> +</html> |