mirror of
https://git.pleroma.social/pleroma/relay.git
synced 2024-11-23 23:17:58 +00:00
Compare commits
No commits in common. "2a866eaaaa2413f6f93e2a6851d5f4e65f189b50" and "e6831f04eb545ef662f2ca560755380b5ad6daf5" have entirely different histories.
2a866eaaaa
...
e6831f04eb
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
||||||
import bsql
|
import bsql
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
from .config import CONFIG_DEFAULTS, THEMES, get_default_value
|
from .config import get_default_value
|
||||||
from .connection import RELAY_SOFTWARE, Connection
|
from .connection import RELAY_SOFTWARE, Connection
|
||||||
from .schema import TABLES, VERSIONS, migrate_0
|
from .schema import TABLES, VERSIONS, migrate_0
|
||||||
|
|
||||||
|
|
|
@ -61,10 +61,10 @@ THEMES = {
|
||||||
|
|
||||||
CONFIG_DEFAULTS: dict[str, tuple[str, Any]] = {
|
CONFIG_DEFAULTS: dict[str, tuple[str, Any]] = {
|
||||||
'schema-version': ('int', 20240206),
|
'schema-version': ('int', 20240206),
|
||||||
'private-key': ('str', None),
|
|
||||||
'log-level': ('loglevel', logging.LogLevel.INFO),
|
'log-level': ('loglevel', logging.LogLevel.INFO),
|
||||||
'name': ('str', 'ActivityRelay'),
|
'name': ('str', 'ActivityRelay'),
|
||||||
'note': ('str', 'Make a note about your instance here.'),
|
'note': ('str', 'Make a note about your instance here.'),
|
||||||
|
'private-key': ('str', None),
|
||||||
'theme': ('str', 'default'),
|
'theme': ('str', 'default'),
|
||||||
'whitelist-enabled': ('bool', False)
|
'whitelist-enabled': ('bool', False)
|
||||||
}
|
}
|
||||||
|
|
|
@ -266,10 +266,10 @@ class Connection(SqlConnection):
|
||||||
|
|
||||||
params = {}
|
params = {}
|
||||||
|
|
||||||
if reason is not None:
|
if reason:
|
||||||
params['reason'] = reason
|
params['reason'] = reason
|
||||||
|
|
||||||
if note is not None:
|
if note:
|
||||||
params['note'] = note
|
params['note'] = note
|
||||||
|
|
||||||
statement = Update('domain_bans', params)
|
statement = Update('domain_bans', params)
|
||||||
|
@ -321,10 +321,10 @@ class Connection(SqlConnection):
|
||||||
|
|
||||||
params = {}
|
params = {}
|
||||||
|
|
||||||
if reason is not None:
|
if reason:
|
||||||
params['reason'] = reason
|
params['reason'] = reason
|
||||||
|
|
||||||
if note is not None:
|
if note:
|
||||||
params['note'] = note
|
params['note'] = note
|
||||||
|
|
||||||
statement = Update('software_bans', params)
|
statement = Update('software_bans', params)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
-macro menu_item(name, path)
|
-macro menu_item(name, path)
|
||||||
-if view.request.path == path or (path != "/" and view.request.path.startswith(path))
|
-if view.request.path == path
|
||||||
%a.button(href="{{path}}" active="true") -> =name
|
%a.button(active="true") -> =name
|
||||||
|
|
||||||
-else
|
-else
|
||||||
%a.button(href="{{path}}") -> =name
|
%a.button(href="{{path}}") -> =name
|
||||||
|
@ -69,15 +69,8 @@
|
||||||
const menu_open = document.getElementById("menu-open");
|
const menu_open = document.getElementById("menu-open");
|
||||||
const menu_close = document.getElementById("menu-close");
|
const menu_close = document.getElementById("menu-close");
|
||||||
|
|
||||||
menu_open.addEventListener("click", (event) => {
|
menu_open.addEventListener("click", (event) => {menu.attributes.visible.nodeValue = "true"});
|
||||||
var new_value = menu.attributes.visible.nodeValue === "true" ? "false" : "true";
|
menu_close.addEventListener("click", (event) => {menu.attributes.visible.nodeValue = "false"});
|
||||||
menu.attributes.visible.nodeValue = new_value;
|
|
||||||
});
|
|
||||||
|
|
||||||
menu_close.addEventListener("click", (event) => {
|
|
||||||
menu.attributes.visible.nodeValue = "false"
|
|
||||||
});
|
|
||||||
|
|
||||||
body.addEventListener("click", (event) => {
|
body.addEventListener("click", (event) => {
|
||||||
if (event.target === menu_open) {
|
if (event.target === menu_open) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,37 +1,5 @@
|
||||||
-extends "base.haml"
|
-extends "base.haml"
|
||||||
-set page="Config"
|
-set page="Config"
|
||||||
-block content
|
-block content
|
||||||
%form.section(action="/admin/config" method="POST")
|
.section
|
||||||
#config-options
|
UvU
|
||||||
%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")
|
|
||||||
|
|
|
@ -1,48 +1,5 @@
|
||||||
-extends "base.haml"
|
-extends "base.haml"
|
||||||
-set page="Domain Bans"
|
-set page="Domain Bans"
|
||||||
-block content
|
-block content
|
||||||
%details.section
|
.section
|
||||||
%summary << Ban Domain
|
UvU
|
||||||
%form(action="/admin/domain_bans", method="POST")
|
|
||||||
#add-domain
|
|
||||||
%label(for="domain") << Domain
|
|
||||||
%input(type="domain" id="domain" name="domain" placeholder="Domain")
|
|
||||||
|
|
||||||
%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 Domain")
|
|
||||||
|
|
||||||
#domains.section
|
|
||||||
%table
|
|
||||||
%thead
|
|
||||||
%tr
|
|
||||||
%td.domain << Instance
|
|
||||||
%td.date << Joined
|
|
||||||
%td.remove
|
|
||||||
|
|
||||||
%tbody
|
|
||||||
-for ban in bans
|
|
||||||
%tr
|
|
||||||
%td.domain
|
|
||||||
%details
|
|
||||||
%summary -> =ban.domain
|
|
||||||
%form(action="/admin/domain_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="domain", value="{{ban.domain}}")
|
|
||||||
%input(type="submit" value="Update")
|
|
||||||
|
|
||||||
%td.date
|
|
||||||
=ban.created.strftime("%Y-%m-%d")
|
|
||||||
|
|
||||||
%td.remove
|
|
||||||
%a(href="/admin/domain_bans/delete/{{ban.domain}}" title="Unban domain") << ✖
|
|
||||||
|
|
|
@ -6,13 +6,13 @@
|
||||||
%form(target="/admin/instances", method="POST")
|
%form(target="/admin/instances", method="POST")
|
||||||
#add-instance
|
#add-instance
|
||||||
%label(for="domain") << Domain
|
%label(for="domain") << Domain
|
||||||
%input(type="domain", id="domain" name="domain", placeholder="Domain")
|
%input(type="domain", name="domain", placeholder="Domain")
|
||||||
%label(for="actor") << Actor URL
|
%label(for="actor") << Actor URL
|
||||||
%input(type="url", id="actor" name="actor", placeholder="Actor URL")
|
%input(type="url", name="actor", placeholder="Actor URL")
|
||||||
%label(for="inbox") << Inbox URL
|
%label(for="inbox") << Inbox URL
|
||||||
%input(type="url", id="inbox" name="inbox", placeholder="Inbox URL")
|
%input(type="url", name="inbox", placeholder="Inbox URL")
|
||||||
%label(for="software") << Software
|
%label(for="software") << Software
|
||||||
%input(name="software", id="software" placeholder="software")
|
%input(name="software", placeholder="software")
|
||||||
|
|
||||||
%input(type="submit" value="Add Instance")
|
%input(type="submit" value="Add Instance")
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,7 @@
|
||||||
-set page = "Home"
|
-set page = "Home"
|
||||||
-block content
|
-block content
|
||||||
.section
|
.section
|
||||||
-for line in config.note.splitlines()
|
=config.note
|
||||||
-if line
|
|
||||||
%p -> =line
|
|
||||||
|
|
||||||
.section
|
.section
|
||||||
%p
|
%p
|
||||||
|
|
|
@ -133,8 +133,9 @@ table tbody td {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#menu > a[active="true"]:not(:hover) {
|
#menu > a[active="true"] {
|
||||||
background-color: var(--primary-hover);
|
cursor: default;
|
||||||
|
background-color: var(--background);
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
#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;
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
#domains table {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#domains .domain {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#domains .date {
|
|
||||||
width: max-content;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
#domains thead td {
|
|
||||||
text-align: center !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
#add-domain {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: max-content auto;
|
|
||||||
grid-gap: var(--spacing);
|
|
||||||
margin-top: var(--spacing);
|
|
||||||
margin-bottom: var(--spacing);
|
|
||||||
}
|
|
|
@ -12,8 +12,7 @@ from ..misc import Response
|
||||||
|
|
||||||
if typing.TYPE_CHECKING:
|
if typing.TYPE_CHECKING:
|
||||||
from collections.abc import Callable, Coroutine, Generator
|
from collections.abc import Callable, Coroutine, Generator
|
||||||
from bsql import Database
|
from tinysql import Database
|
||||||
from typing import Self
|
|
||||||
from ..application import Application
|
from ..application import Application
|
||||||
from ..cache import Cache
|
from ..cache import Cache
|
||||||
from ..config import Config
|
from ..config import Config
|
||||||
|
@ -29,7 +28,7 @@ def register_route(*paths: str) -> Callable:
|
||||||
for path in paths:
|
for path in paths:
|
||||||
VIEWS.append([path, view])
|
VIEWS.append([path, view])
|
||||||
|
|
||||||
return view
|
return View
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,14 +43,8 @@ class View(AbstractView):
|
||||||
return self._run_handler(handler).__await__()
|
return self._run_handler(handler).__await__()
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
async def _run_handler(self, handler: Coroutine) -> Response:
|
||||||
async def run(cls: type[Self], method: str, request: Request, **kwargs: Any) -> Self:
|
return await handler(self.request, **self.request.match_info)
|
||||||
view = cls(request)
|
|
||||||
return await view.handlers[method](request, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
async def _run_handler(self, handler: Coroutine, **kwargs: Any) -> Response:
|
|
||||||
return await handler(self.request, **self.request.match_info, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
|
|
|
@ -7,8 +7,6 @@ from argon2.exceptions import VerifyMismatchError
|
||||||
|
|
||||||
from .base import View, register_route
|
from .base import View, register_route
|
||||||
|
|
||||||
from ..database import CONFIG_DEFAULTS, THEMES
|
|
||||||
from ..logger import LogLevel
|
|
||||||
from ..misc import ACTOR_FORMATS, Message, Response
|
from ..misc import ACTOR_FORMATS, Message, Response
|
||||||
|
|
||||||
if typing.TYPE_CHECKING:
|
if typing.TYPE_CHECKING:
|
||||||
|
@ -20,11 +18,6 @@ UNAUTH_ROUTES = {
|
||||||
'/login'
|
'/login'
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG_IGNORE = (
|
|
||||||
'schema-version',
|
|
||||||
'private-key'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@web.middleware
|
@web.middleware
|
||||||
async def handle_frontend_path(request: web.Request, handler: Coroutine) -> Response:
|
async def handle_frontend_path(request: web.Request, handler: Coroutine) -> Response:
|
||||||
|
@ -186,85 +179,18 @@ class AdminInstancesDelete(View):
|
||||||
|
|
||||||
@register_route('/admin/whitelist')
|
@register_route('/admin/whitelist')
|
||||||
class AdminWhitelist(View):
|
class AdminWhitelist(View):
|
||||||
async def get(self,
|
async def get(self, request: Request) -> Response:
|
||||||
request: Request,
|
data = self.template.render('page/admin-whitelist.haml', self)
|
||||||
error: str | None = None,
|
|
||||||
message: str | None = None) -> Response:
|
|
||||||
|
|
||||||
with self.database.session() as conn:
|
|
||||||
context = {
|
|
||||||
'domains': tuple(conn.execute('SELECT * FROM whitelist').all())
|
|
||||||
}
|
|
||||||
|
|
||||||
if error:
|
|
||||||
context['error'] = error
|
|
||||||
|
|
||||||
if message:
|
|
||||||
context['message'] = message
|
|
||||||
|
|
||||||
data = self.template.render('page/admin-whitelist.haml', self, **context)
|
|
||||||
return Response.new(data, ctype = 'html')
|
return Response.new(data, ctype = 'html')
|
||||||
|
|
||||||
|
|
||||||
@register_route('/admin/domain_bans')
|
@register_route('/admin/domain_bans')
|
||||||
class AdminDomainBans(View):
|
class AdminDomainBans(View):
|
||||||
async def get(self,
|
async def get(self, request: Request) -> Response:
|
||||||
request: Request,
|
data = self.template.render('page/admin-domain_bans.haml', self)
|
||||||
error: str | None = None,
|
|
||||||
message: str | None = None) -> Response:
|
|
||||||
|
|
||||||
with self.database.session() as conn:
|
|
||||||
context = {
|
|
||||||
'bans': tuple(conn.execute('SELECT * FROM domain_bans ORDER BY domain ASC').all())
|
|
||||||
}
|
|
||||||
|
|
||||||
if error:
|
|
||||||
context['error'] = error
|
|
||||||
|
|
||||||
if message:
|
|
||||||
context['message'] = message
|
|
||||||
|
|
||||||
data = self.template.render('page/admin-domain_bans.haml', self, **context)
|
|
||||||
return Response.new(data, ctype = 'html')
|
return Response.new(data, ctype = 'html')
|
||||||
|
|
||||||
|
|
||||||
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')
|
|
||||||
|
|
||||||
with self.database.session(True) as conn:
|
|
||||||
if (ban := conn.get_domain_ban(data['domain'])):
|
|
||||||
conn.update_domain_ban(
|
|
||||||
data['domain'],
|
|
||||||
data.get('reason'),
|
|
||||||
data.get('note')
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
conn.put_domain_ban(
|
|
||||||
data['domain'],
|
|
||||||
data.get('reason'),
|
|
||||||
data.get('note')
|
|
||||||
)
|
|
||||||
|
|
||||||
return await self.get(request, message = "Added/updated domain ban")
|
|
||||||
|
|
||||||
|
|
||||||
@register_route('/admin/domain_bans/delete/{domain}')
|
|
||||||
class AdminDomainBansDelete(View):
|
|
||||||
async def get(self, request: Request, domain: str) -> Response:
|
|
||||||
with self.database.session() as conn:
|
|
||||||
if not (conn.get_domain_ban(domain)):
|
|
||||||
return await AdminDomainBans.run("GET", request, message = 'Domain ban not found')
|
|
||||||
|
|
||||||
conn.del_domain_ban(domain)
|
|
||||||
|
|
||||||
return await AdminDomainBans.run("GET", request, message = 'Unbanned domain')
|
|
||||||
|
|
||||||
|
|
||||||
@register_route('/admin/software_bans')
|
@register_route('/admin/software_bans')
|
||||||
class AdminSoftwareBans(View):
|
class AdminSoftwareBans(View):
|
||||||
async def get(self, request: Request) -> Response:
|
async def get(self, request: Request) -> Response:
|
||||||
|
@ -274,37 +200,11 @@ class AdminSoftwareBans(View):
|
||||||
|
|
||||||
@register_route('/admin/config')
|
@register_route('/admin/config')
|
||||||
class AdminConfig(View):
|
class AdminConfig(View):
|
||||||
async def get(self, request: Request, message: str | None = None) -> Response:
|
async def get(self, request: Request) -> Response:
|
||||||
context = {
|
data = self.template.render('page/admin-config.haml', self)
|
||||||
'themes': tuple(THEMES.keys()),
|
|
||||||
'LogLevel': LogLevel,
|
|
||||||
'message': message
|
|
||||||
}
|
|
||||||
data = self.template.render('page/admin-config.haml', self, **context)
|
|
||||||
return Response.new(data, ctype = 'html')
|
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')
|
@register_route('/style.css')
|
||||||
class StyleCss(View):
|
class StyleCss(View):
|
||||||
async def get(self, request: Request) -> Response:
|
async def get(self, request: Request) -> Response:
|
||||||
|
|
|
@ -2,7 +2,7 @@ aiohttp>=3.9.1
|
||||||
aiohttp-swagger[performance]==1.0.16
|
aiohttp-swagger[performance]==1.0.16
|
||||||
aputils@https://git.barkshark.xyz/barkshark/aputils/archive/0.1.7.tar.gz
|
aputils@https://git.barkshark.xyz/barkshark/aputils/archive/0.1.7.tar.gz
|
||||||
argon2-cffi==23.1.0
|
argon2-cffi==23.1.0
|
||||||
barkshark-sql@https://git.barkshark.xyz/barkshark/bsql/archive/499649a736fd22eb3752ce38fd7304a9b8432ab9.tar.gz
|
barkshark-sql@https://git.barkshark.xyz/barkshark/bsql/archive/0.1.1.tar.gz
|
||||||
click>=8.1.2
|
click>=8.1.2
|
||||||
hamlish-jinja@https://git.barkshark.xyz/barkshark/hamlish-jinja/archive/0.3.5.tar.gz
|
hamlish-jinja@https://git.barkshark.xyz/barkshark/hamlish-jinja/archive/0.3.5.tar.gz
|
||||||
hiredis==2.3.2
|
hiredis==2.3.2
|
||||||
|
|
Loading…
Reference in a new issue