aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/admin.css45
-rw-r--r--backend/Admin.py65
-rw-r--r--interface/admin_delete.tmpl35
-rw-r--r--interface/admin_dirs.tmpl40
-rw-r--r--interface/admin_files.tmpl31
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 &amp; 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>