diff --git a/relay/frontend/page/admin-domain_bans.haml b/relay/frontend/page/admin-domain_bans.haml index fc5010a..ddf1947 100644 --- a/relay/frontend/page/admin-domain_bans.haml +++ b/relay/frontend/page/admin-domain_bans.haml @@ -21,7 +21,7 @@ %thead %tr %td.domain << Instance - %td << Joined + %td << Date %td.remove %tbody diff --git a/relay/frontend/page/admin-software_bans.haml b/relay/frontend/page/admin-software_bans.haml index c215fc8..efe6f12 100644 --- a/relay/frontend/page/admin-software_bans.haml +++ b/relay/frontend/page/admin-software_bans.haml @@ -1,5 +1,48 @@ -extends "base.haml" -set page="Software Bans" -block content - .section - UvU + %details.section + %summary << Ban Software + %form(action="/admin/software_bans", method="POST") + #add-software + %label(for="name") << Name + %input(id="name" name="name" placeholder="Name") + + %label(for="reason") << Ban Reason + %textarea(id="reason" name="reason") << {{""}} + + %label(for="note") << Admin Note + %textarea(id="note" name="note") << {{""}} + + %input(type="submit" value="Ban Software") + + #software.section + %table + %thead + %tr + %td.name << Instance + %td << Date + %td.remove + + %tbody + -for ban in bans + %tr + %td.name + %details + %summary -> =ban.name + %form(action="/admin/software_bans" method="POST") + .items + .reason << Reason + %textarea.reason(id="reason" name="reason") << {{ban.reason or ""}} + + .note << Note + %textarea.note(id="note" name="note") << {{ban.note or ""}} + + %input(type="hidden" name="name", value="{{ban.name}}") + %input(type="submit" value="Update") + + %td.date + =ban.created.strftime("%Y-%m-%d") + + %td.remove + %a(href="/admin/software_bans/delete/{{ban.name}}" title="Unban software") << ✖ diff --git a/relay/frontend/style/software_bans.css b/relay/frontend/style/software_bans.css index e69de29..c3109b1 100644 --- a/relay/frontend/style/software_bans.css +++ b/relay/frontend/style/software_bans.css @@ -0,0 +1,32 @@ +form input[type="submit"] { + display: block; + margin: 0 auto; +} + +textarea { + height: calc(5em); +} + +table .items { + display: grid; + grid-template-columns: max-content auto; + grid-gap: var(--spacing); + margin-top: var(--spacing); +} + +#software .name{ + width: 100%; +} + +#software .date { + width: max-content; + text-align: right; +} + +#add-software { + display: grid; + grid-template-columns: max-content auto; + grid-gap: var(--spacing); + margin-top: var(--spacing); + margin-bottom: var(--spacing); +} diff --git a/relay/views/frontend.py b/relay/views/frontend.py index 3f90234..089751d 100644 --- a/relay/views/frontend.py +++ b/relay/views/frontend.py @@ -230,7 +230,6 @@ class AdminDomainBans(View): async def post(self, request: Request) -> Response: data = await request.post() - print(data) if not data['domain']: return await self.get(request, error = 'Missing domain') @@ -267,11 +266,62 @@ class AdminDomainBansDelete(View): @register_route('/admin/software_bans') class AdminSoftwareBans(View): - async def get(self, request: Request) -> Response: - data = self.template.render('page/admin-software_bans.haml', self) + async def get(self, + request: Request, + error: str | None = None, + message: str | None = None) -> Response: + + with self.database.session() as conn: + context = { + 'bans': tuple(conn.execute('SELECT * FROM software_bans ORDER BY name ASC').all()) + } + + if error: + context['error'] = error + + if message: + context['message'] = message + + data = self.template.render('page/admin-software_bans.haml', self, **context) return Response.new(data, ctype = 'html') + async def post(self, request: Request) -> Response: + data = await request.post() + + if not data['name']: + return await self.get(request, error = 'Missing name') + + with self.database.session(True) as conn: + if (ban := conn.get_software_ban(data['name'])): + conn.update_software_ban( + data['name'], + data.get('reason'), + data.get('note') + ) + + else: + conn.put_software_ban( + data['name'], + data.get('reason'), + data.get('note') + ) + + return await self.get(request, message = "Added/updated software ban") + + +@register_route('/admin/software_bans/delete/{name}') +class AdminSoftwareBansDelete(View): + async def get(self, request: Request, name: str) -> Response: + with self.database.session() as conn: + if not (conn.get_software_ban(name)): + return await AdminSoftwareBans.run("GET", request, message = 'Software ban not found') + + conn.del_software_ban(name) + + return await AdminSoftwareBans.run("GET", request, message = 'Unbanned software') + + @register_route('/admin/config') class AdminConfig(View): async def get(self, request: Request, message: str | None = None) -> Response: