Fix #879: Admins can now add custom CSS from their pod settings

environments/review-front-brok-oyrjvg/deployments/2100
Eliot Berriot 2019-07-03 11:06:13 +02:00
rodzic 78ab153734
commit 7897c8ac7f
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: DD6965E2476E5C27
5 zmienionych plików z 84 dodań i 1 usunięć

Wyświetl plik

@ -1,5 +1,6 @@
import html
import requests
import xml.sax.saxutils
from django import http
from django.conf import settings
@ -51,7 +52,13 @@ def serve_spa(request):
# let's inject our meta tags in the HTML
head += "\n" + "\n".join(render_tags(final_tags)) + "\n</head>"
css = get_custom_css() or ""
if css:
# We add the style add the end of the body to ensure it has the highest
# priority (since it will come after other stylesheets)
body, tail = tail.split("</body>", 1)
css = "<style>{}</style>".format(css)
tail = body + "\n" + css + "\n</body>" + tail
return http.HttpResponse(head + tail)
@ -128,6 +135,14 @@ def get_request_head_tags(request):
return match.func(request, *match.args, **match.kwargs)
def get_custom_css():
css = preferences.get("ui__custom_css").strip()
if not css:
return
return xml.sax.saxutils.escape(css)
class SPAFallbackMiddleware:
def __init__(self, get_response):
self.get_response = get_response

Wyświetl plik

@ -4,6 +4,7 @@ from dynamic_preferences.registries import global_preferences_registry
raven = types.Section("raven")
instance = types.Section("instance")
ui = types.Section("ui")
@global_preferences_registry.register
@ -98,3 +99,19 @@ class InstanceNodeinfoStatsEnabled(types.BooleanPreference):
"Disable this if you don't want to share usage and library statistics "
"in the nodeinfo endpoint but don't want to disable it completely."
)
@global_preferences_registry.register
class CustomCSS(types.StringPreference):
show_in_api = True
section = ui
name = "custom_css"
verbose_name = "Custom CSS code"
default = ""
help_text = (
"Custom CSS code, to be included in a <style> tag on all pages. "
"Loading third-party resources such as fonts or images can affect the performance "
"of the app and the privacy of your users."
)
widget = widgets.Textarea
field_kwargs = {"required": False}

Wyświetl plik

@ -141,3 +141,47 @@ def test_get_route_head_tags(mocker, settings):
assert tags == match.func.return_value
match.func.assert_called_once_with(request, *[], **{"pk": 42})
resolve.assert_called_once_with(request.path, urlconf=settings.SPA_URLCONF)
def test_serve_spa_includes_custom_css(mocker, no_api_auth):
request = mocker.Mock(path="/")
mocker.patch.object(
middleware,
"get_spa_html",
return_value="<html><head></head><body></body></html>",
)
mocker.patch.object(middleware, "get_default_head_tags", return_value=[])
mocker.patch.object(middleware, "get_request_head_tags", return_value=[])
get_custom_css = mocker.patch.object(
middleware, "get_custom_css", return_value="body { background: black; }"
)
response = middleware.serve_spa(request)
assert response.status_code == 200
expected = [
"<html><head>\n\n</head><body>",
"<style>body { background: black; }</style>",
"</body></html>",
]
get_custom_css.assert_called_once_with()
assert response.content == "\n".join(expected).encode()
@pytest.mark.parametrize(
"custom_css, expected",
[
("body { background: black; }", "body { background: black; }"),
(
"body { injection: </style> & Hello",
"body { injection: &lt;/style&gt; &amp; Hello",
),
(
'body { background: url("image/url"); }',
'body { background: url("image/url"); }',
),
],
)
def test_get_custom_css(preferences, custom_css, expected):
preferences["ui__custom_css"] = custom_css
assert middleware.get_custom_css() == expected

Wyświetl plik

@ -0,0 +1 @@
Admins can now add custom CSS from their pod settings (#879)

Wyświetl plik

@ -84,6 +84,7 @@ export default {
let federationLabel = this.$pgettext('Content/Admin/Menu', 'Federation')
let subsonicLabel = this.$pgettext('Content/Admin/Menu', 'Subsonic')
let statisticsLabel = this.$pgettext('Content/Admin/Menu', 'Statistics')
let uiLabel = this.$pgettext('Content/Admin/Menu', 'User Interface')
let errorLabel = this.$pgettext('Content/Admin/Menu', 'Error reporting')
return [
{
@ -134,6 +135,11 @@ export default {
id: "subsonic",
settings: ["subsonic__enabled"]
},
{
label: uiLabel,
id: "ui",
settings: ["ui__custom_css"]
},
{
label: statisticsLabel,
id: "statistics",