authentik.core.tests.utils

Test Utils

  1"""Test Utils"""
  2
  3from typing import Any
  4
  5from django.contrib.auth.models import AnonymousUser
  6from django.contrib.messages.middleware import MessageMiddleware
  7from django.contrib.sessions.middleware import SessionMiddleware
  8from django.http import HttpRequest
  9from django.test import RequestFactory as BaseRequestFactory
 10from django.utils.text import slugify
 11
 12from authentik.brands.models import Brand
 13from authentik.core.models import Group, User
 14from authentik.crypto.builder import CertificateBuilder, PrivateKeyAlg
 15from authentik.crypto.models import CertificateKeyPair
 16from authentik.flows.models import Flow, FlowDesignation
 17from authentik.lib.generators import generate_id
 18
 19
 20def create_test_flow(
 21    designation: FlowDesignation = FlowDesignation.STAGE_CONFIGURATION, **kwargs
 22) -> Flow:
 23    """Generate a flow that can be used for testing"""
 24    uid = generate_id(10)
 25    return Flow.objects.create(
 26        name=uid, title=uid, slug=slugify(uid), designation=designation, **kwargs
 27    )
 28
 29
 30def create_test_user(name: str | None = None, **kwargs) -> User:
 31    """Generate a test user"""
 32    uid = generate_id(20) if not name else name
 33    kwargs.setdefault("email", f"{uid}@goauthentik.io")
 34    kwargs.setdefault("username", uid)
 35    user: User = User.objects.create(
 36        name=uid,
 37        **kwargs,
 38    )
 39    user.set_password(uid)
 40    user.save()
 41    return user
 42
 43
 44def create_test_admin_user(name: str | None = None, **kwargs) -> User:
 45    """Generate a test-admin user"""
 46    user = create_test_user(name, **kwargs)
 47    group = Group.objects.create(name=user.name or name, is_superuser=True)
 48    group.users.add(user)
 49    return user
 50
 51
 52def create_test_brand(**kwargs) -> Brand:
 53    """Generate a test brand, removing all other brands to make sure this one
 54    matches."""
 55    uid = generate_id(20)
 56    Brand.objects.all().delete()
 57    return Brand.objects.create(domain=uid, default=True, **kwargs)
 58
 59
 60def create_test_cert(alg=PrivateKeyAlg.RSA) -> CertificateKeyPair:
 61    """Generate a certificate for testing"""
 62    builder = CertificateBuilder(f"{generate_id()}.self-signed.goauthentik.io")
 63    builder.alg = alg
 64    builder.build(
 65        subject_alt_names=[f"{generate_id()}.self-signed.goauthentik.io"],
 66        validity_days=360,
 67    )
 68    builder.common_name = generate_id()
 69    return builder.save()
 70
 71
 72def dummy_get_response(request: HttpRequest):  # pragma: no cover
 73    """Dummy get_response for SessionMiddleware"""
 74    return None
 75
 76
 77class RequestFactory(BaseRequestFactory):
 78
 79    def generic(
 80        self,
 81        method: str,
 82        path: str,
 83        data: Any = "",
 84        content_type="application/octet-stream",
 85        secure=False,
 86        *,
 87        headers=None,
 88        query_params=None,
 89        **extra,
 90    ):
 91        user = extra.pop("user", None)
 92        request = super().generic(
 93            method,
 94            path,
 95            data,
 96            content_type,
 97            secure,
 98            headers=headers,
 99            query_params=query_params,
100            **extra,
101        )
102        request.user = user if user else AnonymousUser()
103
104        middleware = SessionMiddleware(dummy_get_response)
105        middleware.process_request(request)
106        request.session.save()
107        middleware = MessageMiddleware(dummy_get_response)
108        middleware.process_request(request)
109        request.session.save()
110
111        return request
def create_test_flow( designation: authentik.flows.models.FlowDesignation = FlowDesignation.STAGE_CONFIGURATION, **kwargs) -> authentik.flows.models.Flow:
21def create_test_flow(
22    designation: FlowDesignation = FlowDesignation.STAGE_CONFIGURATION, **kwargs
23) -> Flow:
24    """Generate a flow that can be used for testing"""
25    uid = generate_id(10)
26    return Flow.objects.create(
27        name=uid, title=uid, slug=slugify(uid), designation=designation, **kwargs
28    )

Generate a flow that can be used for testing

def create_test_user(name: str | None = None, **kwargs) -> authentik.core.models.User:
31def create_test_user(name: str | None = None, **kwargs) -> User:
32    """Generate a test user"""
33    uid = generate_id(20) if not name else name
34    kwargs.setdefault("email", f"{uid}@goauthentik.io")
35    kwargs.setdefault("username", uid)
36    user: User = User.objects.create(
37        name=uid,
38        **kwargs,
39    )
40    user.set_password(uid)
41    user.save()
42    return user

Generate a test user

def create_test_admin_user(name: str | None = None, **kwargs) -> authentik.core.models.User:
45def create_test_admin_user(name: str | None = None, **kwargs) -> User:
46    """Generate a test-admin user"""
47    user = create_test_user(name, **kwargs)
48    group = Group.objects.create(name=user.name or name, is_superuser=True)
49    group.users.add(user)
50    return user

Generate a test-admin user

def create_test_brand(**kwargs) -> authentik.brands.models.Brand:
53def create_test_brand(**kwargs) -> Brand:
54    """Generate a test brand, removing all other brands to make sure this one
55    matches."""
56    uid = generate_id(20)
57    Brand.objects.all().delete()
58    return Brand.objects.create(domain=uid, default=True, **kwargs)

Generate a test brand, removing all other brands to make sure this one matches.

def create_test_cert(alg=PrivateKeyAlg.RSA) -> authentik.crypto.models.CertificateKeyPair:
61def create_test_cert(alg=PrivateKeyAlg.RSA) -> CertificateKeyPair:
62    """Generate a certificate for testing"""
63    builder = CertificateBuilder(f"{generate_id()}.self-signed.goauthentik.io")
64    builder.alg = alg
65    builder.build(
66        subject_alt_names=[f"{generate_id()}.self-signed.goauthentik.io"],
67        validity_days=360,
68    )
69    builder.common_name = generate_id()
70    return builder.save()

Generate a certificate for testing

def dummy_get_response(request: django.http.request.HttpRequest):
73def dummy_get_response(request: HttpRequest):  # pragma: no cover
74    """Dummy get_response for SessionMiddleware"""
75    return None

Dummy get_response for SessionMiddleware

class RequestFactory(django.test.client.RequestFactory):
 78class RequestFactory(BaseRequestFactory):
 79
 80    def generic(
 81        self,
 82        method: str,
 83        path: str,
 84        data: Any = "",
 85        content_type="application/octet-stream",
 86        secure=False,
 87        *,
 88        headers=None,
 89        query_params=None,
 90        **extra,
 91    ):
 92        user = extra.pop("user", None)
 93        request = super().generic(
 94            method,
 95            path,
 96            data,
 97            content_type,
 98            secure,
 99            headers=headers,
100            query_params=query_params,
101            **extra,
102        )
103        request.user = user if user else AnonymousUser()
104
105        middleware = SessionMiddleware(dummy_get_response)
106        middleware.process_request(request)
107        request.session.save()
108        middleware = MessageMiddleware(dummy_get_response)
109        middleware.process_request(request)
110        request.session.save()
111
112        return request

Class that lets you create mock Request objects for use in testing.

Usage:

rf = RequestFactory() get_request = rf.get('/hello/') post_request = rf.post('/submit/', {'foo': 'bar'})

Once you have a request object you can pass it to any view function, just as if that view had been hooked up using a URLconf.

def generic( self, method: str, path: str, data: Any = '', content_type='application/octet-stream', secure=False, *, headers=None, query_params=None, **extra):
 80    def generic(
 81        self,
 82        method: str,
 83        path: str,
 84        data: Any = "",
 85        content_type="application/octet-stream",
 86        secure=False,
 87        *,
 88        headers=None,
 89        query_params=None,
 90        **extra,
 91    ):
 92        user = extra.pop("user", None)
 93        request = super().generic(
 94            method,
 95            path,
 96            data,
 97            content_type,
 98            secure,
 99            headers=headers,
100            query_params=query_params,
101            **extra,
102        )
103        request.user = user if user else AnonymousUser()
104
105        middleware = SessionMiddleware(dummy_get_response)
106        middleware.process_request(request)
107        request.session.save()
108        middleware = MessageMiddleware(dummy_get_response)
109        middleware.process_request(request)
110        request.session.save()
111
112        return request

Construct an arbitrary HTTP request.