authentik.brands.tests

Test brands

  1"""Test brands"""
  2
  3from json import loads
  4
  5from django.urls import reverse
  6from rest_framework.test import APITestCase
  7
  8from authentik.blueprints.tests import apply_blueprint
  9from authentik.brands.models import Brand
 10from authentik.core.models import Application
 11from authentik.core.tests.utils import create_test_admin_user, create_test_brand
 12from authentik.lib.generators import generate_id
 13from authentik.providers.oauth2.models import OAuth2Provider
 14from authentik.providers.saml.models import SAMLProvider
 15from authentik.tenants.flags import Flag
 16
 17
 18class TestBrands(APITestCase):
 19    """Test brands"""
 20
 21    def setUp(self):
 22        super().setUp()
 23        Brand.objects.all().delete()
 24
 25    @property
 26    def default_flags(self) -> dict[str, object]:
 27        """Get current public flags.
 28
 29        Some tests define temporary Flag subclasses, so this can't be cached in setUp.
 30        """
 31        return {flag().key: flag.get() for flag in Flag.available(visibility="public")}
 32
 33    def test_current_brand(self):
 34        """Test Current brand API"""
 35        brand = create_test_brand()
 36        self.assertJSONEqual(
 37            self.client.get(reverse("authentik_api:brand-current")).content.decode(),
 38            {
 39                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
 40                "branding_logo_themed_urls": None,
 41                "branding_favicon": "/static/dist/assets/icons/icon.png",
 42                "branding_favicon_themed_urls": None,
 43                "branding_title": "authentik",
 44                "branding_custom_css": "",
 45                "matched_domain": brand.domain,
 46                "ui_footer_links": [],
 47                "ui_theme": "automatic",
 48                "default_locale": "",
 49                "flags": self.default_flags,
 50            },
 51        )
 52
 53    def test_brand_subdomain(self):
 54        """Test Current brand API"""
 55        Brand.objects.create(domain="bar.baz", branding_title="custom")
 56        self.assertJSONEqual(
 57            self.client.get(
 58                reverse("authentik_api:brand-current"), HTTP_HOST="foo.bar.baz"
 59            ).content.decode(),
 60            {
 61                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
 62                "branding_logo_themed_urls": None,
 63                "branding_favicon": "/static/dist/assets/icons/icon.png",
 64                "branding_favicon_themed_urls": None,
 65                "branding_title": "custom",
 66                "branding_custom_css": "",
 67                "matched_domain": "bar.baz",
 68                "ui_footer_links": [],
 69                "ui_theme": "automatic",
 70                "default_locale": "",
 71                "flags": self.default_flags,
 72            },
 73        )
 74
 75    def test_fallback(self):
 76        """Test fallback brand"""
 77        self.assertJSONEqual(
 78            self.client.get(reverse("authentik_api:brand-current")).content.decode(),
 79            {
 80                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
 81                "branding_logo_themed_urls": None,
 82                "branding_favicon": "/static/dist/assets/icons/icon.png",
 83                "branding_favicon_themed_urls": None,
 84                "branding_title": "authentik",
 85                "branding_custom_css": "",
 86                "matched_domain": "fallback",
 87                "ui_footer_links": [],
 88                "ui_theme": "automatic",
 89                "default_locale": "",
 90                "flags": self.default_flags,
 91            },
 92        )
 93
 94    @apply_blueprint("default/default-brand.yaml")
 95    def test_blueprint(self):
 96        """Test Current brand API"""
 97        response = loads(self.client.get(reverse("authentik_api:brand-current")).content.decode())
 98        response.pop("flow_authentication", None)
 99        response.pop("flow_invalidation", None)
100        response.pop("flow_user_settings", None)
101        self.assertEqual(
102            response,
103            {
104                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
105                "branding_logo_themed_urls": None,
106                "branding_favicon": "/static/dist/assets/icons/icon.png",
107                "branding_favicon_themed_urls": None,
108                "branding_title": "authentik",
109                "branding_custom_css": "",
110                "matched_domain": "authentik-default",
111                "ui_footer_links": [],
112                "ui_theme": "automatic",
113                "default_locale": "",
114                "flags": self.default_flags,
115            },
116        )
117
118    @apply_blueprint("default/default-brand.yaml")
119    def test_blueprint_with_other_brand(self):
120        """Test Current brand API"""
121        Brand.objects.create(domain="bar.baz", branding_title="custom")
122        response = loads(self.client.get(reverse("authentik_api:brand-current")).content.decode())
123        response.pop("flow_authentication", None)
124        response.pop("flow_invalidation", None)
125        response.pop("flow_user_settings", None)
126        self.assertEqual(
127            response,
128            {
129                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
130                "branding_logo_themed_urls": None,
131                "branding_favicon": "/static/dist/assets/icons/icon.png",
132                "branding_favicon_themed_urls": None,
133                "branding_title": "authentik",
134                "branding_custom_css": "",
135                "matched_domain": "authentik-default",
136                "ui_footer_links": [],
137                "ui_theme": "automatic",
138                "default_locale": "",
139                "flags": self.default_flags,
140            },
141        )
142        self.assertJSONEqual(
143            self.client.get(
144                reverse("authentik_api:brand-current"), HTTP_HOST="foo.bar.baz"
145            ).content.decode(),
146            {
147                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
148                "branding_logo_themed_urls": None,
149                "branding_favicon": "/static/dist/assets/icons/icon.png",
150                "branding_favicon_themed_urls": None,
151                "branding_title": "custom",
152                "branding_custom_css": "",
153                "matched_domain": "bar.baz",
154                "ui_footer_links": [],
155                "ui_theme": "automatic",
156                "default_locale": "",
157                "flags": self.default_flags,
158            },
159        )
160
161    def test_brand_subdomain_same_suffix(self):
162        """Test Current brand API"""
163        Brand.objects.create(domain="bar.baz", branding_title="custom-weak")
164        Brand.objects.create(domain="foo.bar.baz", branding_title="custom-strong")
165        self.assertJSONEqual(
166            self.client.get(
167                reverse("authentik_api:brand-current"), HTTP_HOST="foo.bar.baz"
168            ).content.decode(),
169            {
170                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
171                "branding_logo_themed_urls": None,
172                "branding_favicon": "/static/dist/assets/icons/icon.png",
173                "branding_favicon_themed_urls": None,
174                "branding_title": "custom-strong",
175                "branding_custom_css": "",
176                "matched_domain": "foo.bar.baz",
177                "ui_footer_links": [],
178                "ui_theme": "automatic",
179                "default_locale": "",
180                "flags": self.default_flags,
181            },
182        )
183
184    def test_brand_subdomain_other_suffix(self):
185        """Test Current brand API"""
186        Brand.objects.create(domain="bar.baz", branding_title="custom-weak")
187        Brand.objects.create(domain="foo.bar.baz", branding_title="custom-strong")
188        self.assertJSONEqual(
189            self.client.get(
190                reverse("authentik_api:brand-current"), HTTP_HOST="other.bar.baz"
191            ).content.decode(),
192            {
193                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
194                "branding_logo_themed_urls": None,
195                "branding_favicon": "/static/dist/assets/icons/icon.png",
196                "branding_favicon_themed_urls": None,
197                "branding_title": "custom-weak",
198                "branding_custom_css": "",
199                "matched_domain": "bar.baz",
200                "ui_footer_links": [],
201                "ui_theme": "automatic",
202                "default_locale": "",
203                "flags": self.default_flags,
204            },
205        )
206
207    def test_create_default_multiple(self):
208        """Test attempted creation of multiple default brands"""
209        Brand.objects.create(
210            domain="foo",
211            default=True,
212            branding_title="custom",
213        )
214        user = create_test_admin_user()
215        self.client.force_login(user)
216        response = self.client.post(
217            reverse("authentik_api:brand-list"), data={"domain": "bar", "default": True}
218        )
219        self.assertEqual(response.status_code, 400)
220
221    def test_webfinger_no_app(self):
222        """Test Webfinger"""
223        create_test_brand()
224        self.assertJSONEqual(
225            self.client.get(reverse("authentik_brands:webfinger")).content.decode(), {}
226        )
227
228    def test_webfinger_not_supported(self):
229        """Test Webfinger"""
230        brand = create_test_brand()
231        provider = SAMLProvider.objects.create(
232            name=generate_id(),
233        )
234        app = Application.objects.create(name=generate_id(), slug=generate_id(), provider=provider)
235        brand.default_application = app
236        brand.save()
237        self.assertJSONEqual(
238            self.client.get(reverse("authentik_brands:webfinger")).content.decode(), {}
239        )
240
241    def test_webfinger_oidc(self):
242        """Test Webfinger"""
243        brand = create_test_brand()
244        provider = OAuth2Provider.objects.create(
245            name=generate_id(),
246        )
247        app = Application.objects.create(name=generate_id(), slug=generate_id(), provider=provider)
248        brand.default_application = app
249        brand.save()
250        self.assertJSONEqual(
251            self.client.get(reverse("authentik_brands:webfinger")).content.decode(),
252            {
253                "links": [
254                    {
255                        "href": f"http://testserver/application/o/{app.slug}/",
256                        "rel": "http://openid.net/specs/connect/1.0/issuer",
257                    }
258                ],
259                "subject": None,
260            },
261        )
262
263    def test_branding_url(self):
264        """Test branding attributes return correct values"""
265        brand = create_test_brand()
266        brand.branding_default_flow_background = "https://goauthentik.io/img/icon.png"
267        brand.branding_favicon = "https://goauthentik.io/img/icon.png"
268        brand.branding_logo = "https://goauthentik.io/img/icon.png"
269        brand.save()
270        self.assertEqual(
271            brand.branding_default_flow_background_url(), "https://goauthentik.io/img/icon.png"
272        )
273        self.assertJSONEqual(
274            self.client.get(reverse("authentik_api:brand-current")).content.decode(),
275            {
276                "branding_logo": "https://goauthentik.io/img/icon.png",
277                "branding_logo_themed_urls": None,
278                "branding_favicon": "https://goauthentik.io/img/icon.png",
279                "branding_favicon_themed_urls": None,
280                "branding_title": "authentik",
281                "branding_custom_css": "",
282                "matched_domain": brand.domain,
283                "ui_footer_links": [],
284                "ui_theme": "automatic",
285                "default_locale": "",
286                "flags": self.default_flags,
287            },
288        )
289
290    def test_custom_css(self):
291        """Test custom_css"""
292        brand = create_test_brand()
293        brand.branding_custom_css = """* {
294            font-family: "Foo bar";
295        }"""
296        brand.save()
297        res = self.client.get(reverse("authentik_core:if-user"))
298        self.assertEqual(res.status_code, 200)
299        self.assertIn(brand.branding_custom_css, res.content.decode())
class TestBrands(rest_framework.test.APITestCase):
 19class TestBrands(APITestCase):
 20    """Test brands"""
 21
 22    def setUp(self):
 23        super().setUp()
 24        Brand.objects.all().delete()
 25
 26    @property
 27    def default_flags(self) -> dict[str, object]:
 28        """Get current public flags.
 29
 30        Some tests define temporary Flag subclasses, so this can't be cached in setUp.
 31        """
 32        return {flag().key: flag.get() for flag in Flag.available(visibility="public")}
 33
 34    def test_current_brand(self):
 35        """Test Current brand API"""
 36        brand = create_test_brand()
 37        self.assertJSONEqual(
 38            self.client.get(reverse("authentik_api:brand-current")).content.decode(),
 39            {
 40                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
 41                "branding_logo_themed_urls": None,
 42                "branding_favicon": "/static/dist/assets/icons/icon.png",
 43                "branding_favicon_themed_urls": None,
 44                "branding_title": "authentik",
 45                "branding_custom_css": "",
 46                "matched_domain": brand.domain,
 47                "ui_footer_links": [],
 48                "ui_theme": "automatic",
 49                "default_locale": "",
 50                "flags": self.default_flags,
 51            },
 52        )
 53
 54    def test_brand_subdomain(self):
 55        """Test Current brand API"""
 56        Brand.objects.create(domain="bar.baz", branding_title="custom")
 57        self.assertJSONEqual(
 58            self.client.get(
 59                reverse("authentik_api:brand-current"), HTTP_HOST="foo.bar.baz"
 60            ).content.decode(),
 61            {
 62                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
 63                "branding_logo_themed_urls": None,
 64                "branding_favicon": "/static/dist/assets/icons/icon.png",
 65                "branding_favicon_themed_urls": None,
 66                "branding_title": "custom",
 67                "branding_custom_css": "",
 68                "matched_domain": "bar.baz",
 69                "ui_footer_links": [],
 70                "ui_theme": "automatic",
 71                "default_locale": "",
 72                "flags": self.default_flags,
 73            },
 74        )
 75
 76    def test_fallback(self):
 77        """Test fallback brand"""
 78        self.assertJSONEqual(
 79            self.client.get(reverse("authentik_api:brand-current")).content.decode(),
 80            {
 81                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
 82                "branding_logo_themed_urls": None,
 83                "branding_favicon": "/static/dist/assets/icons/icon.png",
 84                "branding_favicon_themed_urls": None,
 85                "branding_title": "authentik",
 86                "branding_custom_css": "",
 87                "matched_domain": "fallback",
 88                "ui_footer_links": [],
 89                "ui_theme": "automatic",
 90                "default_locale": "",
 91                "flags": self.default_flags,
 92            },
 93        )
 94
 95    @apply_blueprint("default/default-brand.yaml")
 96    def test_blueprint(self):
 97        """Test Current brand API"""
 98        response = loads(self.client.get(reverse("authentik_api:brand-current")).content.decode())
 99        response.pop("flow_authentication", None)
100        response.pop("flow_invalidation", None)
101        response.pop("flow_user_settings", None)
102        self.assertEqual(
103            response,
104            {
105                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
106                "branding_logo_themed_urls": None,
107                "branding_favicon": "/static/dist/assets/icons/icon.png",
108                "branding_favicon_themed_urls": None,
109                "branding_title": "authentik",
110                "branding_custom_css": "",
111                "matched_domain": "authentik-default",
112                "ui_footer_links": [],
113                "ui_theme": "automatic",
114                "default_locale": "",
115                "flags": self.default_flags,
116            },
117        )
118
119    @apply_blueprint("default/default-brand.yaml")
120    def test_blueprint_with_other_brand(self):
121        """Test Current brand API"""
122        Brand.objects.create(domain="bar.baz", branding_title="custom")
123        response = loads(self.client.get(reverse("authentik_api:brand-current")).content.decode())
124        response.pop("flow_authentication", None)
125        response.pop("flow_invalidation", None)
126        response.pop("flow_user_settings", None)
127        self.assertEqual(
128            response,
129            {
130                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
131                "branding_logo_themed_urls": None,
132                "branding_favicon": "/static/dist/assets/icons/icon.png",
133                "branding_favicon_themed_urls": None,
134                "branding_title": "authentik",
135                "branding_custom_css": "",
136                "matched_domain": "authentik-default",
137                "ui_footer_links": [],
138                "ui_theme": "automatic",
139                "default_locale": "",
140                "flags": self.default_flags,
141            },
142        )
143        self.assertJSONEqual(
144            self.client.get(
145                reverse("authentik_api:brand-current"), HTTP_HOST="foo.bar.baz"
146            ).content.decode(),
147            {
148                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
149                "branding_logo_themed_urls": None,
150                "branding_favicon": "/static/dist/assets/icons/icon.png",
151                "branding_favicon_themed_urls": None,
152                "branding_title": "custom",
153                "branding_custom_css": "",
154                "matched_domain": "bar.baz",
155                "ui_footer_links": [],
156                "ui_theme": "automatic",
157                "default_locale": "",
158                "flags": self.default_flags,
159            },
160        )
161
162    def test_brand_subdomain_same_suffix(self):
163        """Test Current brand API"""
164        Brand.objects.create(domain="bar.baz", branding_title="custom-weak")
165        Brand.objects.create(domain="foo.bar.baz", branding_title="custom-strong")
166        self.assertJSONEqual(
167            self.client.get(
168                reverse("authentik_api:brand-current"), HTTP_HOST="foo.bar.baz"
169            ).content.decode(),
170            {
171                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
172                "branding_logo_themed_urls": None,
173                "branding_favicon": "/static/dist/assets/icons/icon.png",
174                "branding_favicon_themed_urls": None,
175                "branding_title": "custom-strong",
176                "branding_custom_css": "",
177                "matched_domain": "foo.bar.baz",
178                "ui_footer_links": [],
179                "ui_theme": "automatic",
180                "default_locale": "",
181                "flags": self.default_flags,
182            },
183        )
184
185    def test_brand_subdomain_other_suffix(self):
186        """Test Current brand API"""
187        Brand.objects.create(domain="bar.baz", branding_title="custom-weak")
188        Brand.objects.create(domain="foo.bar.baz", branding_title="custom-strong")
189        self.assertJSONEqual(
190            self.client.get(
191                reverse("authentik_api:brand-current"), HTTP_HOST="other.bar.baz"
192            ).content.decode(),
193            {
194                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
195                "branding_logo_themed_urls": None,
196                "branding_favicon": "/static/dist/assets/icons/icon.png",
197                "branding_favicon_themed_urls": None,
198                "branding_title": "custom-weak",
199                "branding_custom_css": "",
200                "matched_domain": "bar.baz",
201                "ui_footer_links": [],
202                "ui_theme": "automatic",
203                "default_locale": "",
204                "flags": self.default_flags,
205            },
206        )
207
208    def test_create_default_multiple(self):
209        """Test attempted creation of multiple default brands"""
210        Brand.objects.create(
211            domain="foo",
212            default=True,
213            branding_title="custom",
214        )
215        user = create_test_admin_user()
216        self.client.force_login(user)
217        response = self.client.post(
218            reverse("authentik_api:brand-list"), data={"domain": "bar", "default": True}
219        )
220        self.assertEqual(response.status_code, 400)
221
222    def test_webfinger_no_app(self):
223        """Test Webfinger"""
224        create_test_brand()
225        self.assertJSONEqual(
226            self.client.get(reverse("authentik_brands:webfinger")).content.decode(), {}
227        )
228
229    def test_webfinger_not_supported(self):
230        """Test Webfinger"""
231        brand = create_test_brand()
232        provider = SAMLProvider.objects.create(
233            name=generate_id(),
234        )
235        app = Application.objects.create(name=generate_id(), slug=generate_id(), provider=provider)
236        brand.default_application = app
237        brand.save()
238        self.assertJSONEqual(
239            self.client.get(reverse("authentik_brands:webfinger")).content.decode(), {}
240        )
241
242    def test_webfinger_oidc(self):
243        """Test Webfinger"""
244        brand = create_test_brand()
245        provider = OAuth2Provider.objects.create(
246            name=generate_id(),
247        )
248        app = Application.objects.create(name=generate_id(), slug=generate_id(), provider=provider)
249        brand.default_application = app
250        brand.save()
251        self.assertJSONEqual(
252            self.client.get(reverse("authentik_brands:webfinger")).content.decode(),
253            {
254                "links": [
255                    {
256                        "href": f"http://testserver/application/o/{app.slug}/",
257                        "rel": "http://openid.net/specs/connect/1.0/issuer",
258                    }
259                ],
260                "subject": None,
261            },
262        )
263
264    def test_branding_url(self):
265        """Test branding attributes return correct values"""
266        brand = create_test_brand()
267        brand.branding_default_flow_background = "https://goauthentik.io/img/icon.png"
268        brand.branding_favicon = "https://goauthentik.io/img/icon.png"
269        brand.branding_logo = "https://goauthentik.io/img/icon.png"
270        brand.save()
271        self.assertEqual(
272            brand.branding_default_flow_background_url(), "https://goauthentik.io/img/icon.png"
273        )
274        self.assertJSONEqual(
275            self.client.get(reverse("authentik_api:brand-current")).content.decode(),
276            {
277                "branding_logo": "https://goauthentik.io/img/icon.png",
278                "branding_logo_themed_urls": None,
279                "branding_favicon": "https://goauthentik.io/img/icon.png",
280                "branding_favicon_themed_urls": None,
281                "branding_title": "authentik",
282                "branding_custom_css": "",
283                "matched_domain": brand.domain,
284                "ui_footer_links": [],
285                "ui_theme": "automatic",
286                "default_locale": "",
287                "flags": self.default_flags,
288            },
289        )
290
291    def test_custom_css(self):
292        """Test custom_css"""
293        brand = create_test_brand()
294        brand.branding_custom_css = """* {
295            font-family: "Foo bar";
296        }"""
297        brand.save()
298        res = self.client.get(reverse("authentik_core:if-user"))
299        self.assertEqual(res.status_code, 200)
300        self.assertIn(brand.branding_custom_css, res.content.decode())

Test brands

def setUp(self):
22    def setUp(self):
23        super().setUp()
24        Brand.objects.all().delete()

Hook method for setting up the test fixture before exercising it.

default_flags: dict[str, object]
26    @property
27    def default_flags(self) -> dict[str, object]:
28        """Get current public flags.
29
30        Some tests define temporary Flag subclasses, so this can't be cached in setUp.
31        """
32        return {flag().key: flag.get() for flag in Flag.available(visibility="public")}

Get current public flags.

Some tests define temporary Flag subclasses, so this can't be cached in setUp.

def test_current_brand(self):
34    def test_current_brand(self):
35        """Test Current brand API"""
36        brand = create_test_brand()
37        self.assertJSONEqual(
38            self.client.get(reverse("authentik_api:brand-current")).content.decode(),
39            {
40                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
41                "branding_logo_themed_urls": None,
42                "branding_favicon": "/static/dist/assets/icons/icon.png",
43                "branding_favicon_themed_urls": None,
44                "branding_title": "authentik",
45                "branding_custom_css": "",
46                "matched_domain": brand.domain,
47                "ui_footer_links": [],
48                "ui_theme": "automatic",
49                "default_locale": "",
50                "flags": self.default_flags,
51            },
52        )

Test Current brand API

def test_brand_subdomain(self):
54    def test_brand_subdomain(self):
55        """Test Current brand API"""
56        Brand.objects.create(domain="bar.baz", branding_title="custom")
57        self.assertJSONEqual(
58            self.client.get(
59                reverse("authentik_api:brand-current"), HTTP_HOST="foo.bar.baz"
60            ).content.decode(),
61            {
62                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
63                "branding_logo_themed_urls": None,
64                "branding_favicon": "/static/dist/assets/icons/icon.png",
65                "branding_favicon_themed_urls": None,
66                "branding_title": "custom",
67                "branding_custom_css": "",
68                "matched_domain": "bar.baz",
69                "ui_footer_links": [],
70                "ui_theme": "automatic",
71                "default_locale": "",
72                "flags": self.default_flags,
73            },
74        )

Test Current brand API

def test_fallback(self):
76    def test_fallback(self):
77        """Test fallback brand"""
78        self.assertJSONEqual(
79            self.client.get(reverse("authentik_api:brand-current")).content.decode(),
80            {
81                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
82                "branding_logo_themed_urls": None,
83                "branding_favicon": "/static/dist/assets/icons/icon.png",
84                "branding_favicon_themed_urls": None,
85                "branding_title": "authentik",
86                "branding_custom_css": "",
87                "matched_domain": "fallback",
88                "ui_footer_links": [],
89                "ui_theme": "automatic",
90                "default_locale": "",
91                "flags": self.default_flags,
92            },
93        )

Test fallback brand

@apply_blueprint('default/default-brand.yaml')
def test_blueprint(self):
 95    @apply_blueprint("default/default-brand.yaml")
 96    def test_blueprint(self):
 97        """Test Current brand API"""
 98        response = loads(self.client.get(reverse("authentik_api:brand-current")).content.decode())
 99        response.pop("flow_authentication", None)
100        response.pop("flow_invalidation", None)
101        response.pop("flow_user_settings", None)
102        self.assertEqual(
103            response,
104            {
105                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
106                "branding_logo_themed_urls": None,
107                "branding_favicon": "/static/dist/assets/icons/icon.png",
108                "branding_favicon_themed_urls": None,
109                "branding_title": "authentik",
110                "branding_custom_css": "",
111                "matched_domain": "authentik-default",
112                "ui_footer_links": [],
113                "ui_theme": "automatic",
114                "default_locale": "",
115                "flags": self.default_flags,
116            },
117        )

Test Current brand API

@apply_blueprint('default/default-brand.yaml')
def test_blueprint_with_other_brand(self):
119    @apply_blueprint("default/default-brand.yaml")
120    def test_blueprint_with_other_brand(self):
121        """Test Current brand API"""
122        Brand.objects.create(domain="bar.baz", branding_title="custom")
123        response = loads(self.client.get(reverse("authentik_api:brand-current")).content.decode())
124        response.pop("flow_authentication", None)
125        response.pop("flow_invalidation", None)
126        response.pop("flow_user_settings", None)
127        self.assertEqual(
128            response,
129            {
130                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
131                "branding_logo_themed_urls": None,
132                "branding_favicon": "/static/dist/assets/icons/icon.png",
133                "branding_favicon_themed_urls": None,
134                "branding_title": "authentik",
135                "branding_custom_css": "",
136                "matched_domain": "authentik-default",
137                "ui_footer_links": [],
138                "ui_theme": "automatic",
139                "default_locale": "",
140                "flags": self.default_flags,
141            },
142        )
143        self.assertJSONEqual(
144            self.client.get(
145                reverse("authentik_api:brand-current"), HTTP_HOST="foo.bar.baz"
146            ).content.decode(),
147            {
148                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
149                "branding_logo_themed_urls": None,
150                "branding_favicon": "/static/dist/assets/icons/icon.png",
151                "branding_favicon_themed_urls": None,
152                "branding_title": "custom",
153                "branding_custom_css": "",
154                "matched_domain": "bar.baz",
155                "ui_footer_links": [],
156                "ui_theme": "automatic",
157                "default_locale": "",
158                "flags": self.default_flags,
159            },
160        )

Test Current brand API

def test_brand_subdomain_same_suffix(self):
162    def test_brand_subdomain_same_suffix(self):
163        """Test Current brand API"""
164        Brand.objects.create(domain="bar.baz", branding_title="custom-weak")
165        Brand.objects.create(domain="foo.bar.baz", branding_title="custom-strong")
166        self.assertJSONEqual(
167            self.client.get(
168                reverse("authentik_api:brand-current"), HTTP_HOST="foo.bar.baz"
169            ).content.decode(),
170            {
171                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
172                "branding_logo_themed_urls": None,
173                "branding_favicon": "/static/dist/assets/icons/icon.png",
174                "branding_favicon_themed_urls": None,
175                "branding_title": "custom-strong",
176                "branding_custom_css": "",
177                "matched_domain": "foo.bar.baz",
178                "ui_footer_links": [],
179                "ui_theme": "automatic",
180                "default_locale": "",
181                "flags": self.default_flags,
182            },
183        )

Test Current brand API

def test_brand_subdomain_other_suffix(self):
185    def test_brand_subdomain_other_suffix(self):
186        """Test Current brand API"""
187        Brand.objects.create(domain="bar.baz", branding_title="custom-weak")
188        Brand.objects.create(domain="foo.bar.baz", branding_title="custom-strong")
189        self.assertJSONEqual(
190            self.client.get(
191                reverse("authentik_api:brand-current"), HTTP_HOST="other.bar.baz"
192            ).content.decode(),
193            {
194                "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
195                "branding_logo_themed_urls": None,
196                "branding_favicon": "/static/dist/assets/icons/icon.png",
197                "branding_favicon_themed_urls": None,
198                "branding_title": "custom-weak",
199                "branding_custom_css": "",
200                "matched_domain": "bar.baz",
201                "ui_footer_links": [],
202                "ui_theme": "automatic",
203                "default_locale": "",
204                "flags": self.default_flags,
205            },
206        )

Test Current brand API

def test_create_default_multiple(self):
208    def test_create_default_multiple(self):
209        """Test attempted creation of multiple default brands"""
210        Brand.objects.create(
211            domain="foo",
212            default=True,
213            branding_title="custom",
214        )
215        user = create_test_admin_user()
216        self.client.force_login(user)
217        response = self.client.post(
218            reverse("authentik_api:brand-list"), data={"domain": "bar", "default": True}
219        )
220        self.assertEqual(response.status_code, 400)

Test attempted creation of multiple default brands

def test_webfinger_no_app(self):
222    def test_webfinger_no_app(self):
223        """Test Webfinger"""
224        create_test_brand()
225        self.assertJSONEqual(
226            self.client.get(reverse("authentik_brands:webfinger")).content.decode(), {}
227        )

Test Webfinger

def test_webfinger_not_supported(self):
229    def test_webfinger_not_supported(self):
230        """Test Webfinger"""
231        brand = create_test_brand()
232        provider = SAMLProvider.objects.create(
233            name=generate_id(),
234        )
235        app = Application.objects.create(name=generate_id(), slug=generate_id(), provider=provider)
236        brand.default_application = app
237        brand.save()
238        self.assertJSONEqual(
239            self.client.get(reverse("authentik_brands:webfinger")).content.decode(), {}
240        )

Test Webfinger

def test_webfinger_oidc(self):
242    def test_webfinger_oidc(self):
243        """Test Webfinger"""
244        brand = create_test_brand()
245        provider = OAuth2Provider.objects.create(
246            name=generate_id(),
247        )
248        app = Application.objects.create(name=generate_id(), slug=generate_id(), provider=provider)
249        brand.default_application = app
250        brand.save()
251        self.assertJSONEqual(
252            self.client.get(reverse("authentik_brands:webfinger")).content.decode(),
253            {
254                "links": [
255                    {
256                        "href": f"http://testserver/application/o/{app.slug}/",
257                        "rel": "http://openid.net/specs/connect/1.0/issuer",
258                    }
259                ],
260                "subject": None,
261            },
262        )

Test Webfinger

def test_branding_url(self):
264    def test_branding_url(self):
265        """Test branding attributes return correct values"""
266        brand = create_test_brand()
267        brand.branding_default_flow_background = "https://goauthentik.io/img/icon.png"
268        brand.branding_favicon = "https://goauthentik.io/img/icon.png"
269        brand.branding_logo = "https://goauthentik.io/img/icon.png"
270        brand.save()
271        self.assertEqual(
272            brand.branding_default_flow_background_url(), "https://goauthentik.io/img/icon.png"
273        )
274        self.assertJSONEqual(
275            self.client.get(reverse("authentik_api:brand-current")).content.decode(),
276            {
277                "branding_logo": "https://goauthentik.io/img/icon.png",
278                "branding_logo_themed_urls": None,
279                "branding_favicon": "https://goauthentik.io/img/icon.png",
280                "branding_favicon_themed_urls": None,
281                "branding_title": "authentik",
282                "branding_custom_css": "",
283                "matched_domain": brand.domain,
284                "ui_footer_links": [],
285                "ui_theme": "automatic",
286                "default_locale": "",
287                "flags": self.default_flags,
288            },
289        )

Test branding attributes return correct values

def test_custom_css(self):
291    def test_custom_css(self):
292        """Test custom_css"""
293        brand = create_test_brand()
294        brand.branding_custom_css = """* {
295            font-family: "Foo bar";
296        }"""
297        brand.save()
298        res = self.client.get(reverse("authentik_core:if-user"))
299        self.assertEqual(res.status_code, 200)
300        self.assertIn(brand.branding_custom_css, res.content.decode())

Test custom_css