From e5d8c9dcb0bee0070e9bd24b01af4a8c4767fc59 Mon Sep 17 00:00:00 2001 From: Izalia Mae Date: Sun, 3 Mar 2024 00:20:38 -0500 Subject: [PATCH] create admin config page --- relay/database/__init__.py | 2 +- relay/database/config.py | 2 +- relay/frontend/page/admin-config.haml | 36 +++++++++++++++++++++-- relay/frontend/page/admin-instances.haml | 8 ++--- relay/frontend/page/home.haml | 4 ++- relay/frontend/style/config.css | 20 +++++++++++++ relay/views/frontend.py | 37 ++++++++++++++++++++++-- 7 files changed, 98 insertions(+), 11 deletions(-) diff --git a/relay/database/__init__.py b/relay/database/__init__.py index a55f2c8..d248713 100644 --- a/relay/database/__init__.py +++ b/relay/database/__init__.py @@ -3,7 +3,7 @@ from __future__ import annotations import bsql import typing -from .config import get_default_value +from .config import CONFIG_DEFAULTS, THEMES, get_default_value from .connection import RELAY_SOFTWARE, Connection from .schema import TABLES, VERSIONS, migrate_0 diff --git a/relay/database/config.py b/relay/database/config.py index d49f1b5..82e2e69 100644 --- a/relay/database/config.py +++ b/relay/database/config.py @@ -61,10 +61,10 @@ THEMES = { CONFIG_DEFAULTS: dict[str, tuple[str, Any]] = { 'schema-version': ('int', 20240206), + 'private-key': ('str', None), 'log-level': ('loglevel', logging.LogLevel.INFO), 'name': ('str', 'ActivityRelay'), 'note': ('str', 'Make a note about your instance here.'), - 'private-key': ('str', None), 'theme': ('str', 'default'), 'whitelist-enabled': ('bool', False) } diff --git a/relay/frontend/page/admin-config.haml b/relay/frontend/page/admin-config.haml index 6587dbe..bf3d8b8 100644 --- a/relay/frontend/page/admin-config.haml +++ b/relay/frontend/page/admin-config.haml @@ -1,5 +1,37 @@ -extends "base.haml" -set page="Config" -block content - .section - UvU + %form.section(action="/admin/config" method="POST") + #config-options + %label(for="name") << Name + %input(id = "name" name="name" placeholder="Relay Name" value="{{config.name or ''}}") + + %label(for="description") << Description + %textarea(id="description" name="note" value="{{config.note}}") << {{config.note}} + + %label(for="theme") << Color Theme + %select(id="theme" name="theme") + -for theme in themes + -if theme == config.theme + %option(value="{{theme}}" selected) -> =theme.title() + + -else + %option(value="{{theme}}") -> =theme.title() + + %label(for="log-level") << Log Level + %select(id="log-level" name="log-level") + -for level in LogLevel + -if level == config["log-level"] + %option(value="{{level.name}}" selected) -> =level.name.title() + + -else + %option(value="{{level.name}}") -> =level.name.title() + + %label(for="whitelist-enabled") << Whitelist + -if config["whitelist-enabled"] + %input(id="whitelist-enabled" name="whitelist-enabled" type="checkbox" checked) + + -else + %input(id="whitelist-enabled" name="whitelist-enabled" type="checkbox") + + %input(type="submit" value="Save") diff --git a/relay/frontend/page/admin-instances.haml b/relay/frontend/page/admin-instances.haml index 9b2c5a6..b563383 100644 --- a/relay/frontend/page/admin-instances.haml +++ b/relay/frontend/page/admin-instances.haml @@ -6,13 +6,13 @@ %form(target="/admin/instances", method="POST") #add-instance %label(for="domain") << Domain - %input(type="domain", name="domain", placeholder="Domain") + %input(type="domain", id="domain" name="domain", placeholder="Domain") %label(for="actor") << Actor URL - %input(type="url", name="actor", placeholder="Actor URL") + %input(type="url", id="actor" name="actor", placeholder="Actor URL") %label(for="inbox") << Inbox URL - %input(type="url", name="inbox", placeholder="Inbox URL") + %input(type="url", id="inbox" name="inbox", placeholder="Inbox URL") %label(for="software") << Software - %input(name="software", placeholder="software") + %input(name="software", id="software" placeholder="software") %input(type="submit" value="Add Instance") diff --git a/relay/frontend/page/home.haml b/relay/frontend/page/home.haml index efa7088..f64b489 100644 --- a/relay/frontend/page/home.haml +++ b/relay/frontend/page/home.haml @@ -2,7 +2,9 @@ -set page = "Home" -block content .section - =config.note + -for line in config.note.splitlines() + -if line + %p -> =line .section %p diff --git a/relay/frontend/style/config.css b/relay/frontend/style/config.css index e69de29..0dff253 100644 --- a/relay/frontend/style/config.css +++ b/relay/frontend/style/config.css @@ -0,0 +1,20 @@ +#config-options { + display: grid; + grid-template-columns: max-content auto; + grid-gap: var(--spacing); + margin-bottom: var(--spacing); + align-items: center; +} + +form input[type="submit"] { + display: block; + margin: 0 auto; +} + +form input[type="checkbox"] { + justify-self: left; +} + +textarea { + height: 4em; +} diff --git a/relay/views/frontend.py b/relay/views/frontend.py index 5206c67..616017c 100644 --- a/relay/views/frontend.py +++ b/relay/views/frontend.py @@ -7,6 +7,8 @@ from argon2.exceptions import VerifyMismatchError from .base import View, register_route +from ..database import CONFIG_DEFAULTS, THEMES +from ..logger import LogLevel from ..misc import ACTOR_FORMATS, Message, Response if typing.TYPE_CHECKING: @@ -18,6 +20,11 @@ UNAUTH_ROUTES = { '/login' } +CONFIG_IGNORE = ( + 'schema-version', + 'private-key' +) + @web.middleware async def handle_frontend_path(request: web.Request, handler: Coroutine) -> Response: @@ -200,11 +207,37 @@ class AdminSoftwareBans(View): @register_route('/admin/config') class AdminConfig(View): - async def get(self, request: Request) -> Response: - data = self.template.render('page/admin-config.haml', self) + async def get(self, request: Request, message: str | None = None) -> Response: + context = { + 'themes': tuple(THEMES.keys()), + 'LogLevel': LogLevel, + 'message': message + } + data = self.template.render('page/admin-config.haml', self, **context) return Response.new(data, ctype = 'html') + async def post(self, request: Request) -> Response: + form = dict(await request.post()) + + with self.database.session(True) as conn: + for key in CONFIG_DEFAULTS: + value = form.get(key) + + if key == 'whitelist-enabled': + value = bool(value) + + elif key.lower() in CONFIG_IGNORE: + continue + + if value is None: + continue + + conn.put_config(key, value) + + return await self.get(request, message = 'Updated config') + + @register_route('/style.css') class StyleCss(View): async def get(self, request: Request) -> Response: