Notice: Please use this system responsibly and in accordance with all applicable laws and organizational policies.
{% if logged %} - + {% else %} -Please log in to manage your remote PCs.
+Please log in to manage your remote PCs.
{% endif %}diff --git a/src/judas_server/__main__.py b/src/judas_server/__main__.py index c8b8fdb..ce09edf 100644 --- a/src/judas_server/__main__.py +++ b/src/judas_server/__main__.py @@ -3,7 +3,7 @@ import logging as lg if __name__ == "__main__": - from judas_server.web.server import JudasWebServer + from judas_server.web.web_server import JudasWebServer lg.basicConfig( level=lg.DEBUG, diff --git a/src/judas_server/web/routes/__init__.py b/src/judas_server/web/routes/__init__.py index e69de29..2ac5931 100644 --- a/src/judas_server/web/routes/__init__.py +++ b/src/judas_server/web/routes/__init__.py @@ -0,0 +1,5 @@ +from .auth import auth_bp +from .index import index_bp +from .panel import panel_bp + +__all__ = ["auth_bp", "index_bp", "panel_bp"] diff --git a/src/judas_server/web/routes/auth.py b/src/judas_server/web/routes/auth.py new file mode 100644 index 0000000..c9043f7 --- /dev/null +++ b/src/judas_server/web/routes/auth.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +from __future__ import annotations +from typing import TYPE_CHECKING + +import flask +import flask_login + +from judas_server.web.user import User + +if TYPE_CHECKING: + from werkzeug.wrappers import Response + +auth_bp: flask.Blueprint = flask.Blueprint( + "auth", __name__, url_prefix="/auth" +) + + +@auth_bp.route("/login", methods=["GET", "POST"]) +def login() -> Response | str: + """Handles user login via password form.""" + if flask.request.method == "POST": + password = flask.request.form.get("password", "") + if password == flask.current_app.config["PASSWORD"]: + user = User("admin") + flask_login.login_user(user) + next_page = flask.request.args.get("next") + return flask.redirect(next_page or flask.url_for("index.index")) + # return flask.redirect(flask.url_for("panel.panel")) + else: + return flask.render_template( + "login.html", + error="Invalid password. Please try again.", + ) + return flask.render_template("login.html") + + +@auth_bp.route("/logout") +@flask_login.login_required +def logout() -> Response: + """Logs out the current user.""" + flask_login.logout_user() + return flask.redirect(flask.url_for("index.index")) diff --git a/src/judas_server/web/routes/index.py b/src/judas_server/web/routes/index.py new file mode 100644 index 0000000..7f0c0b6 --- /dev/null +++ b/src/judas_server/web/routes/index.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import annotations +from typing import TYPE_CHECKING + +import flask +import flask_login + + +if TYPE_CHECKING: + from werkzeug.wrappers import Response + +index_bp: flask.Blueprint = flask.Blueprint("index", __name__) + + +@index_bp.route("/") +def index() -> Response | str: + """Renders the index page.""" + return flask.render_template( + "index.html", logged=flask_login.current_user.is_authenticated + ) diff --git a/src/judas_server/web/routes/panel.py b/src/judas_server/web/routes/panel.py new file mode 100644 index 0000000..73c3962 --- /dev/null +++ b/src/judas_server/web/routes/panel.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +from __future__ import annotations +from typing import TYPE_CHECKING + +import flask +import flask_login + + +if TYPE_CHECKING: + from werkzeug.wrappers import Response + +panel_bp: flask.Blueprint = flask.Blueprint( + "panel", __name__, url_prefix="/panel" +) + + +@panel_bp.route("/") +@flask_login.login_required +def panel() -> str: + """Renders the main panel page with PC details. + + Returns: + Rendered HTML template with PC details. + """ + return flask.render_template( + "panel.html", username=flask_login.current_user.id, pcs={} + ) diff --git a/src/judas_server/web/static/css/palette.css b/src/judas_server/web/static/css/palette.css new file mode 100644 index 0000000..db0a307 --- /dev/null +++ b/src/judas_server/web/static/css/palette.css @@ -0,0 +1,80 @@ +:root { + --ctp-rosewater: #f5e0dc; + --ctp-rosewater-rgb: 245 224 220; + --ctp-rosewater-hsl: 9.600 55.556% 91.176%; + --ctp-flamingo: #f2cdcd; + --ctp-flamingo-rgb: 242 205 205; + --ctp-flamingo-hsl: 0.000 58.730% 87.647%; + --ctp-pink: #f5c2e7; + --ctp-pink-rgb: 245 194 231; + --ctp-pink-hsl: 316.471 71.831% 86.078%; + --ctp-mauve: #cba6f7; + --ctp-mauve-rgb: 203 166 247; + --ctp-mauve-hsl: 267.407 83.505% 80.980%; + --ctp-red: #f38ba8; + --ctp-red-rgb: 243 139 168; + --ctp-red-hsl: 343.269 81.250% 74.902%; + --ctp-maroon: #eba0ac; + --ctp-maroon-rgb: 235 160 172; + --ctp-maroon-hsl: 350.400 65.217% 77.451%; + --ctp-peach: #fab387; + --ctp-peach-rgb: 250 179 135; + --ctp-peach-hsl: 22.957 92.000% 75.490%; + --ctp-yellow: #f9e2af; + --ctp-yellow-rgb: 249 226 175; + --ctp-yellow-hsl: 41.351 86.047% 83.137%; + --ctp-green: #a6e3a1; + --ctp-green-rgb: 166 227 161; + --ctp-green-hsl: 115.455 54.098% 76.078%; + --ctp-teal: #94e2d5; + --ctp-teal-rgb: 148 226 213; + --ctp-teal-hsl: 170.000 57.353% 73.333%; + --ctp-sky: #89dceb; + --ctp-sky-rgb: 137 220 235; + --ctp-sky-hsl: 189.184 71.014% 72.941%; + --ctp-sapphire: #74c7ec; + --ctp-sapphire-rgb: 116 199 236; + --ctp-sapphire-hsl: 198.500 75.949% 69.020%; + --ctp-blue: #89b4fa; + --ctp-blue-rgb: 137 180 250; + --ctp-blue-hsl: 217.168 91.870% 75.882%; + --ctp-lavender: #b4befe; + --ctp-lavender-rgb: 180 190 254; + --ctp-lavender-hsl: 231.892 97.368% 85.098%; + --ctp-text: #cdd6f4; + --ctp-text-rgb: 205 214 244; + --ctp-text-hsl: 226.154 63.934% 88.039%; + --ctp-subtext1: #bac2de; + --ctp-subtext1-rgb: 186 194 222; + --ctp-subtext1-hsl: 226.667 35.294% 80.000%; + --ctp-subtext0: #a6adc8; + --ctp-subtext0-rgb: 166 173 200; + --ctp-subtext0-hsl: 227.647 23.611% 71.765%; + --ctp-overlay2: #9399b2; + --ctp-overlay2-rgb: 147 153 178; + --ctp-overlay2-hsl: 228.387 16.757% 63.725%; + --ctp-overlay1: #7f849c; + --ctp-overlay1-rgb: 127 132 156; + --ctp-overlay1-hsl: 229.655 12.775% 55.490%; + --ctp-overlay0: #6c7086; + --ctp-overlay0-rgb: 108 112 134; + --ctp-overlay0-hsl: 230.769 10.744% 47.451%; + --ctp-surface2: #585b70; + --ctp-surface2-rgb: 88 91 112; + --ctp-surface2-hsl: 232.500 12.000% 39.216%; + --ctp-surface1: #45475a; + --ctp-surface1-rgb: 69 71 90; + --ctp-surface1-hsl: 234.286 13.208% 31.176%; + --ctp-surface0: #313244; + --ctp-surface0-rgb: 49 50 68; + --ctp-surface0-hsl: 236.842 16.239% 22.941%; + --ctp-base: #1e1e2e; + --ctp-base-rgb: 30 30 46; + --ctp-base-hsl: 240.000 21.053% 14.902%; + --ctp-mantle: #181825; + --ctp-mantle-rgb: 24 24 37; + --ctp-mantle-hsl: 240.000 21.311% 11.961%; + --ctp-crust: #11111b; + --ctp-crust-rgb: 17 17 27; + --ctp-crust-hsl: 240.000 22.727% 8.627%; +} diff --git a/src/judas_server/web/static/css/style.css b/src/judas_server/web/static/css/style.css index 8ca23c8..c0a9a23 100644 --- a/src/judas_server/web/static/css/style.css +++ b/src/judas_server/web/static/css/style.css @@ -1,22 +1,4 @@ -:root { - --nord-bg0: #2e3440; - --nord-bg1: #3b4252; - --nord-bg2: #434c5e; - --nord-bg3: #4c566a; - --nord-fg0: #eceff4; - --nord-fg1: #e5e9f0; - --nord-fg2: #d8dee9; - --nord-acc0: #8fbcbb; - --nord-acc1: #88c0d0; - --nord-acc2: #81a1c1; - --nord-acc3: #5e81ac; - --nord-aur0: #bf616a; - --nord-aur1: #d08770; - --nord-aur2: #ebcb8b; - --nord-aur3: #a3be8c; - --nord-aur4: #b48ead; - -} +@import "palette.css"; * { margin: 0; @@ -25,22 +7,22 @@ } body { - background-color: var(--nord-aur4); + background-color: var(--ctp-base); font-family: monospace, sans-serif !important; - color: var(--nord-fg0); + color: var(--ctp-text); } input { font-family: inherit; color: #eceff4; - background-color: var(--nord-bg2); + background-color: var(--ctp-crust); border: none; border-radius: 0.25rem; padding: 0.25rem; } a { - color: var(--nord-acc0); + color: var(--ctp-blue); text-decoration: none; } @@ -54,8 +36,8 @@ header { display: flex; justify-content: space-between; align-items: center; - background-color: var(--nord-bg0); - color: var(--nord-fg0); + background-color: var(--ctp-mantle); + /* color: var(--ctp-text); */ padding: 1rem; } @@ -64,34 +46,34 @@ main { flex-direction: column; gap: 1rem; padding: 1rem; - background-color: var(--nord-bg1); + /* background-color: var(--ctp-base); */ flex-grow: 1; text-align: center; } header a { text-decoration: none; - color: var(--nord-fg0); + /* color: var(--nord-fg0); */ } .button { display: inline-block; padding: 0.5rem 1rem; - background-color: var(--nord-acc0); - color: var(--nord-bg0); + background-color: var(--ctp-lavender); + color: var(--ctp-base); border: none; border-radius: 0.25rem; text-decoration: none; transition: 0.3s ease-in-out; } -.button a:hover { - color: var(--nord-bg0); - text-decoration: none; -} +/* .button a:hover { */ +/* color: var(--nord-bg0); */ +/* text-decoration: none; */ +/* } */ .button:hover { - background-color: var(--nord-acc2); + background-color: var(--ctp-mauve); cursor: pointer; } @@ -106,9 +88,9 @@ header a { justify-content: center; margin: 1rem; padding: 1rem; - background-color: var(--nord-aur0); - color: var(--nord-fg0); - border: 6px solid var(--nord-aur1); + background-color: var(--ctp-surface0); + color: var(--ctp-red); + border: 6px solid var(--ctp-red); border-radius: 24px; } @@ -117,9 +99,9 @@ header a { width: 100%; } -.select-table{ +.select-table { border-collapse: collapse; - border: 2px solid var(--nord-fg0); + border: 2px solid var(--ctp-surface0); } .select-table thead { @@ -131,18 +113,18 @@ header a { .select-table th, .select-table td { padding: 0.5rem; text-align: center; - border: 1px solid var(--nord-fg1); + border: 1px solid var(--ctp-surface0); border-collapse: collapse; } .select-table th { - background-color: var(--nord-bg2); + background-color: var(--ctp-surface1); color: var(--nord-fg0); } .select-table a { display: block; - color: var(--nord-acc0); + /* color: var(--nord-acc0); */ text-decoration: none; transition: 0.1s ease-in-out; } @@ -152,23 +134,23 @@ header a { } .select-table tr:hover { - background-color: var(--nord-acc1); + background-color: var(--ctp-surface0); } .select-table tr:hover a { - color: var(--nord-bg0); + color: var(--ctp-base); } .red-bg { - background-color: var(--nord-aur0); + background-color: var(--ctp-red); } .yellow-bg { - background-color: var(--nord-aur2); + background-color: var(--ctp-yellow); } .green-bg { - background-color: var(--nord-aur3); + background-color: var(--ctp-green); } .button-container { @@ -183,24 +165,24 @@ header a { } .link:hover { - color: var(--nord-acc2); + color: var(--ctp-blue); } .details-table tr td:first-child { font-weight: 900; - background-color: var(--nord-bg3); + background-color: var(--ctp-surface0); white-space: nowrap; width: 1%; } .details-table { border-collapse: collapse; - border: 2px solid var(--nord-fg0); + border: 2px solid var(--ctp-surface1); } .details-table th, .details-table td { padding: 0.5rem; text-align: left; - border: 1px solid var(--nord-fg1); + border: 1px solid var(--ctp-text); border-collapse: collapse; -} \ No newline at end of file +} diff --git a/src/judas_server/web/templates/details.html b/src/judas_server/web/templates/details.html index 81c4f6c..778af20 100644 --- a/src/judas_server/web/templates/details.html +++ b/src/judas_server/web/templates/details.html @@ -9,7 +9,7 @@
Notice: Please use this system responsibly and in accordance with all applicable laws and organizational policies.
{% if logged %} - + {% else %} -Please log in to manage your remote PCs.
+Please log in to manage your remote PCs.
{% endif %}