add ability to update domain bans and re-add domain ban api endpoints

This commit is contained in:
Izalia Mae 2024-03-14 21:36:47 -04:00
parent 10ba039938
commit 17690268bc
5 changed files with 87 additions and 36 deletions

View file

@ -140,25 +140,6 @@ class Application(web.Application):
return '; '.join(data) + ';' return '; '.join(data) + ';'
# data = {
# 'base-uri': '\'none\'',
# 'default-src': '\'none\'',
# 'frame-ancestors': '\'none\'',
# 'font-src': f'\'self\' https://{self.config.domain}',
# 'img-src': f'\'self\' https://{self.config.domain}',
# 'style-src': f'\'self\' https://{self.config.domain} \'nonce-randomstringhere\'',
# 'media-src': f'\'self\' https://{self.config.domain}',
# 'frame-src': f'\'self\' https:',
# 'manifest-src': f'\'self\' https://{self.config.domain}',
# 'form-action': f'\'self\'',
# 'child-src': f'\'self\' https://{self.config.domain}',
# 'worker-src': f'\'self\' https://{self.config.domain}',
# 'connect-src': f'\'self\' https://{self.config.domain} wss://{self.config.domain}',
# 'script-src': f'\'self\' https://{self.config.domain}'
# }
#
# return '; '.join(f'{key} {value}' for key, value in data.items()) + ';'
def push_message(self, inbox: str, message: Message, instance: Row) -> None: def push_message(self, inbox: str, message: Message, instance: Row) -> None:
self['push_queue'].put((inbox, message, instance)) self['push_queue'].put((inbox, message, instance))
@ -305,6 +286,7 @@ async def handle_response_headers(request: web.Request, handler: Callable) -> Re
resp = await handler(request) resp = await handler(request)
resp.headers['Server'] = 'ActivityRelay' resp.headers['Server'] = 'ActivityRelay'
# Still have to figure out how csp headers work
# if resp.content_type == 'text/html': # if resp.content_type == 'text/html':
# resp.headers['Content-Security-Policy'] = Application.DEFAULT.get_csp(request) # resp.headers['Content-Security-Policy'] = Application.DEFAULT.get_csp(request)

View file

@ -2,7 +2,7 @@
-set page="Domain Bans" -set page="Domain Bans"
-block head -block head
%script(type="application/javascript" src="/static/domain_ban.js" nonce="{{view.request['hash']}}", defer) %script(type="application/javascript" src="/static/domain_ban.js" nonce="{{view.request['hash']}}")
-block content -block content
%details.section %details.section
@ -23,7 +23,7 @@
%legend << Domain Bans %legend << Domain Bans
.data-table .data-table
%table#table %table
%thead %thead
%tr %tr
%td.domain << Domain %td.domain << Domain
@ -38,11 +38,11 @@
%summary -> =ban.domain %summary -> =ban.domain
.grid-2col .grid-2col
.reason << Reason %label.reason(for="{{ban.domain}}-reason") << Reason
%textarea.reason(id="{{ban.domain}}-reason" name="reason") << {{ban.reason or ""}} %textarea.reason(id="{{ban.domain}}-reason") << {{ban.reason or ""}}
.note << Note %label.note(for="{{ban.domain}}-note") << Note
%textarea.note(id="{{ban.domain}}-note" name="note") << {{ban.note or ""}} %textarea.note(id="{{ban.domain}}-note") << {{ban.note or ""}}
%input(type="button" value="Update" onclick="update_ban('{{ban.domain}}')") %input(type="button" value="Update" onclick="update_ban('{{ban.domain}}')")
@ -50,4 +50,4 @@
=ban.created.strftime("%Y-%m-%d") =ban.created.strftime("%Y-%m-%d")
%td.remove %td.remove
%a(href="#", onclick="unban('{{ban.domain}}')" title="Unban domain") << &#10006; %a(href="#" onclick="unban('{{ban.domain}}')" title="Unban domain") << &#10006;

View file

@ -1,5 +1,9 @@
-extends "base.haml" -extends "base.haml"
-set page="Software Bans" -set page="Software Bans"
-block head
%script(type="application/javascript" src="/static/software_ban.js" nonce="{{view.request['hash']}}")
-block content -block content
%details.section %details.section
%summary << Ban Software %summary << Ban Software

View file

@ -3,9 +3,9 @@ function create_ban_object(domain, reason, note) {
text += `<summary>${domain}</summary>\n`; text += `<summary>${domain}</summary>\n`;
text += '<div class="grid-2col">\n'; text += '<div class="grid-2col">\n';
text += `<label for="${domain}-reason" class="reason">Reason</label>\n`; text += `<label for="${domain}-reason" class="reason">Reason</label>\n`;
text += `<textarea id="${domain}-reason" class="reason" name="reason">${reason}</textarea>\n`; text += `<textarea id="${domain}-reason" class="reason">${reason}</textarea>\n`;
text += `<label for="${domain}-note" class="note">Note</label>\n`; text += `<label for="${domain}-note" class="note">Note</label>\n`;
text += `<textarea id="${domain}-note" class="note" name="note">${note}</textarea>\n`; text += `<textarea id="${domain}-note" class="note">${note}</textarea>\n`;
text += `<input type="button" value="Update" onclick="update_ban(\"${domain}\"")">`; text += `<input type="button" value="Update" onclick="update_ban(\"${domain}\"")">`;
text += '</details>'; text += '</details>';
@ -14,7 +14,7 @@ function create_ban_object(domain, reason, note) {
async function ban() { async function ban() {
var table = document.getElementById("table"); var table = document.querySelector("table");
var row = table.insertRow(-1); var row = table.insertRow(-1);
var elems = { var elems = {
@ -59,25 +59,42 @@ async function ban() {
elems.reason.value = null; elems.reason.value = null;
elems.note.value = null; elems.note.value = null;
document.querySelectorAll("details.section").forEach((elem) => { row.querySelector("details").open = false;
elem.open = false;
});
} }
async function update_ban(domain) { async function update_ban(domain) {
var row = document.getElementById(domain); var row = document.getElementById(domain);
var elems = {
"reason": row.querySelector("textarea.reason"),
"note": row.querySelector("textarea.note")
}
var values = {
"domain": domain,
"reason": elems.reason.value,
"note": elems.note.value
}
try {
await client.request("PATCH", "v1/domain_ban", values)
} catch (error) {
alert(error);
return;
}
row.querySelector("details").open = false;
} }
async function unban(domain) { async function unban(domain) {
console.log(domain);
try { try {
await client.unban(domain); await client.unban(domain);
} catch (err) { } catch (error) {
alert(err); alert(error);
return; return;
} }

View file

@ -274,6 +274,54 @@ class DomainBan(View):
return Response.new(bans, ctype = 'json') return Response.new(bans, ctype = 'json')
async def post(self, request: Request) -> Response:
data = await self.get_api_data(['domain'], ['note', 'reason'])
if isinstance(data, Response):
return data
with self.database.session() as conn:
if conn.get_domain_ban(data['domain']):
return Response.new_error(400, 'Domain already banned', 'json')
ban = conn.put_domain_ban(**data)
return Response.new(ban, ctype = 'json')
async def patch(self, request: Request) -> Response:
with self.database.session() as conn:
data = await self.get_api_data(['domain'], ['note', 'reason'])
if isinstance(data, Response):
return data
if not conn.get_domain_ban(data['domain']):
return Response.new_error(404, 'Domain not banned', 'json')
if not any([data.get('note'), data.get('reason')]):
return Response.new_error(400, 'Must include note and/or reason parameters', 'json')
ban = conn.update_domain_ban(**data)
return Response.new(ban, ctype = 'json')
async def delete(self, request: Request) -> Response:
with self.database.session() as conn:
data = await self.get_api_data(['domain'], [])
if isinstance(data, Response):
return data
if not conn.get_domain_ban(data['domain']):
return Response.new_error(404, 'Domain not banned', 'json')
conn.del_domain_ban(data['domain'])
return Response.new({'message': 'Unbanned domain'}, ctype = 'json')
@register_route('/api/v1/software_ban') @register_route('/api/v1/software_ban')
class SoftwareBan(View): class SoftwareBan(View):
async def get(self, request: Request) -> Response: async def get(self, request: Request) -> Response: