diff --git a/.github/workflows/ci-main.yml b/.github/workflows/ci-main.yml index 400527b3e..43cf736e0 100644 --- a/.github/workflows/ci-main.yml +++ b/.github/workflows/ci-main.yml @@ -89,8 +89,8 @@ jobs: # Copy current, latest config to local cp authentik/lib/default.yml local.env.yml git checkout $(git describe --abbrev=0 --match 'version/*') - git checkout ${{ steps.ev.outputs.branchName }} -- .github - git checkout ${{ steps.ev.outputs.branchName }} -- scripts + git checkout $GITHUB_HEAD_REF -- .github + git checkout $GITHUB_HEAD_REF -- scripts - name: prepare env: INSTALL: ${{ steps.cache-pipenv.outputs.cache-hit }} @@ -104,7 +104,7 @@ jobs: run: | set -x git fetch - git checkout ${{ steps.ev.outputs.branchName }} + git checkout $GITHUB_HEAD_REF pipenv sync --dev - name: prepare env: diff --git a/Pipfile b/Pipfile index 6fc515d27..b5a72ec52 100644 --- a/Pipfile +++ b/Pipfile @@ -8,7 +8,10 @@ boto3 = "*" celery = "*" channels = "*" channels-redis = "*" +codespell = "*" +colorama = "*" dacite = "*" +deepmerge = "*" defusedxml = "*" django = "*" django-dbbackup = { git = 'https://github.com/django-dbbackup/django-dbbackup.git', ref = '9d1909c30a3271c8c9c8450add30d6e0b996e145' } @@ -23,6 +26,7 @@ djangorestframework = "*" djangorestframework-guardian = "*" docker = "*" drf-spectacular = "*" +duo-client = "*" facebook-sdk = "*" geoip2 = "*" gunicorn = "*" @@ -40,19 +44,15 @@ service_identity = "*" structlog = "*" swagger-spec-validator = "*" twisted = "==21.7.0" +ua-parser = "*" urllib3 = {extras = ["secure"],version = "*"} uvicorn = {extras = ["standard"],version = "*"} webauthn = "*" xmlsec = "*" -duo-client = "*" -ua-parser = "*" -deepmerge = "*" -colorama = "*" -codespell = "*" [dev-packages] bandit = "*" -black = "==21.9b0" +black = "==21.11b1" bump2version = "*" colorama = "*" coverage = {extras = ["toml"],version = "*"} @@ -60,5 +60,6 @@ pylint = "*" pylint-django = "*" pytest = "*" pytest-django = "*" -selenium = "*" +pytest-randomly = "*" requests-mock = "*" +selenium = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 5242e915b..1301af647 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "2955828c31ceb0f8266987b5a34cb31d2718d856997a384e7c0a92374ddfaa10" + "sha256": "a5f447dcd7be11f8f36de5a849b89cca40d21bdc8d0098f34d6112c58e0a2236" }, "pipfile-spec": 6, "requires": {}, @@ -301,7 +301,7 @@ "sha256:e019de665e2bcf9c2b64e2e5aa025fa991da8720daa3c1138cadd2fd1856aed0", "sha256:f7af805c321bfa1ce6714c51f254e0d5bb5e5834039bc17db7ebe3a4cec9492b" ], - "markers": "python_version >= '3'", + "markers": "python_full_version >= '3.5.0'", "version": "==2.0.7" }, "click": { @@ -317,7 +317,7 @@ "sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667", "sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035" ], - "markers": "python_full_version >= '3.6.2' and python_full_version < '4.0.0'", + "markers": "python_version < '4' and python_full_version >= '3.6.2'", "version": "==0.3.0" }, "click-plugins": { @@ -370,6 +370,7 @@ "sha256:684993ff6f67000a56454b41bdc7e015429732d65a52d06385b6e9de6181c71e", "sha256:6fbbbb8aab4053fa018984bb0e95a16faeb051dd8cca15add2a27e267ba02b58", "sha256:8982c19bb90a4fa2aad3d635c6d71814e38b643649b4000a8419f8691f20ac44", + "sha256:9511416e85e449fe1de73f7f99b21b3aa04fba4c4d335d30c486ba3756e3a2a6", "sha256:97199a13b772e74cdcdb03760c32109c808aff7cd49c29e9cf4b7754bb725d1d", "sha256:a776bae1629c8d7198396fd93ec0265f8dd2341c553dc32b976168aaf0e6a636", "sha256:aa94d617a4cd4cdf4af9b5af65100c036bce22280ebb15d8b5262e8273ebc6ba", @@ -380,6 +381,7 @@ "sha256:f6a5a85beb33e57998dc605b9dbe7deaa806385fdf5c4810fb849fcd04640c81", "sha256:f92556f94e476c1b616e6daec5f7ddded2c082efa7cee7f31c7aeda615906ed8" ], + "markers": "python_version >= '3.6'", "version": "==36.0.0" }, "dacite": { @@ -741,7 +743,7 @@ "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417", "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2" ], - "markers": "python_version >= '3.5'", + "markers": "python_full_version >= '3.5.0'", "version": "==0.5.1" }, "jmespath": { @@ -774,7 +776,7 @@ "sha256:52312adda60d92ba45b325f2c1505924656389222005f7e089718e1ad03bc07f" ], "index": "pypi", - "version": "==19.15.0" + "version": "==v19.15.0" }, "ldap3": { "hashes": [ @@ -1266,11 +1268,11 @@ }, "redis": { "hashes": [ - "sha256:bc6832367d60e1a5f94d75314fc46e8ce6f07fee8e532ee1bfafaf4887f8b4bb", - "sha256:cc642f70e0ebddce960818ba35776af6a18487cc38f66deace68d55b97e6e3cf" + "sha256:c8481cf414474e3497ec7971a1ba9b998c8efad0f0d289a009a5bbef040894f9", + "sha256:ccf692811f2c1fc7a92b466aa2599e4a6d2d73d5f736a2c70be600657c0da34a" ], "markers": "python_version >= '3.6'", - "version": "==4.0.1" + "version": "==4.0.2" }, "requests": { "hashes": [ @@ -1321,6 +1323,14 @@ "index": "pypi", "version": "==21.1.0" }, + "setuptools": { + "hashes": [ + "sha256:157d21de9d055ab9e8ea3186d91e7f4f865e11f42deafa952d90842671fc2576", + "sha256:4adde3d1e1c89bde1c643c64d89cdd94cbfd8c75252ee459d4500bccb9c7d05d" + ], + "markers": "python_version >= '3.6'", + "version": "==59.2.0" + }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", @@ -1334,7 +1344,7 @@ "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae", "sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d" ], - "markers": "python_version >= '3.5'", + "markers": "python_full_version >= '3.5.0'", "version": "==0.4.2" }, "structlog": { @@ -1354,9 +1364,7 @@ "version": "==2.7.4" }, "twisted": { - "extras": [ - "tls" - ], + "extras": [], "hashes": [ "sha256:13c1d1d2421ae556d91e81e66cf0d4f4e4e1e4a36a0486933bee4305c6a4fb9b", "sha256:2cd652542463277378b0d349f47c62f20d9306e57d1247baabd6d1d38a109006" @@ -1775,11 +1783,11 @@ }, "black": { "hashes": [ - "sha256:380f1b5da05e5a1429225676655dddb96f5ae8c75bdf91e53d798871b902a115", - "sha256:7de4cfc7eb6b710de325712d40125689101d21d25283eed7e9998722cf10eb91" + "sha256:802c6c30b637b28645b7fde282ed2569c0cd777dbe493a41b6a03c1d903f99ac", + "sha256:a042adbb18b3262faad5aff4e834ff186bb893f95ba3a8013f09de1e5569def2" ], "index": "pypi", - "version": "==21.9b0" + "version": "==21.11b1" }, "bump2version": { "hashes": [ @@ -1856,7 +1864,7 @@ "sha256:e019de665e2bcf9c2b64e2e5aa025fa991da8720daa3c1138cadd2fd1856aed0", "sha256:f7af805c321bfa1ce6714c51f254e0d5bb5e5834039bc17db7ebe3a4cec9492b" ], - "markers": "python_version >= '3'", + "markers": "python_full_version >= '3.5.0'", "version": "==2.0.7" }, "click": { @@ -1944,6 +1952,7 @@ "sha256:684993ff6f67000a56454b41bdc7e015429732d65a52d06385b6e9de6181c71e", "sha256:6fbbbb8aab4053fa018984bb0e95a16faeb051dd8cca15add2a27e267ba02b58", "sha256:8982c19bb90a4fa2aad3d635c6d71814e38b643649b4000a8419f8691f20ac44", + "sha256:9511416e85e449fe1de73f7f99b21b3aa04fba4c4d335d30c486ba3756e3a2a6", "sha256:97199a13b772e74cdcdb03760c32109c808aff7cd49c29e9cf4b7754bb725d1d", "sha256:a776bae1629c8d7198396fd93ec0265f8dd2341c553dc32b976168aaf0e6a636", "sha256:aa94d617a4cd4cdf4af9b5af65100c036bce22280ebb15d8b5262e8273ebc6ba", @@ -1954,6 +1963,7 @@ "sha256:f6a5a85beb33e57998dc605b9dbe7deaa806385fdf5c4810fb849fcd04640c81", "sha256:f92556f94e476c1b616e6daec5f7ddded2c082efa7cee7f31c7aeda615906ed8" ], + "markers": "python_version >= '3.6'", "version": "==36.0.0" }, "gitdb": { @@ -1987,6 +1997,14 @@ ], "version": "==3.3" }, + "importlib-metadata": { + "hashes": [ + "sha256:53ccfd5c134223e497627b9815d5030edf77d2ed573922f7a0b8f8bb81a1c100", + "sha256:75bdec14c397f528724c1bfd9709d660b33a4d2e77387a3358f20b848bb5e5fb" + ], + "markers": "python_version < '3.10'", + "version": "==4.8.2" + }, "iniconfig": { "hashes": [ "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", @@ -1999,7 +2017,7 @@ "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7", "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951" ], - "markers": "python_version < '4.0' and python_full_version >= '3.6.1'", + "markers": "python_version < '4' and python_full_version >= '3.6.1'", "version": "==5.10.1" }, "lazy-object-proxy": { @@ -2161,6 +2179,14 @@ "index": "pypi", "version": "==4.4.0" }, + "pytest-randomly": { + "hashes": [ + "sha256:2c0a332c4b124e372e2473803bcc91ec87797664f4955afef2b844c0021662b1", + "sha256:cbd5c50b7c41491c202c71a3df33a75619d610a4f5c34aa2bd02ac30fce7cd43" + ], + "index": "pypi", + "version": "==3.10.2" + }, "pyyaml": { "hashes": [ "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", @@ -2272,10 +2298,18 @@ }, "selenium": { "hashes": [ - "sha256:c942b166a21ce9c9065ad249b54059e926d39f9000167b5ca0fa4950d2ef9a82" + "sha256:27e7b64df961d609f3d57237caa0df123abbbe22d038f2ec9e332fb90ec1a939" ], "index": "pypi", - "version": "==4.0.0" + "version": "==4.1.0" + }, + "setuptools": { + "hashes": [ + "sha256:157d21de9d055ab9e8ea3186d91e7f4f865e11f42deafa952d90842671fc2576", + "sha256:4adde3d1e1c89bde1c643c64d89cdd94cbfd8c75252ee459d4500bccb9c7d05d" + ], + "markers": "python_version >= '3.6'", + "version": "==59.2.0" }, "six": { "hashes": [ @@ -2431,6 +2465,14 @@ ], "markers": "python_full_version >= '3.6.1'", "version": "==1.0.0" + }, + "zipp": { + "hashes": [ + "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832", + "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc" + ], + "markers": "python_version >= '3.6'", + "version": "==3.6.0" } } } diff --git a/authentik/core/tests/test_applications_api.py b/authentik/core/tests/test_applications_api.py index 81e8171ac..ecdace6d8 100644 --- a/authentik/core/tests/test_applications_api.py +++ b/authentik/core/tests/test_applications_api.py @@ -3,7 +3,8 @@ from django.urls import reverse from django.utils.encoding import force_str from rest_framework.test import APITestCase -from authentik.core.models import Application, User +from authentik.core.models import Application +from authentik.core.tests.utils import create_test_admin_user from authentik.policies.dummy.models import DummyPolicy from authentik.policies.models import PolicyBinding @@ -12,7 +13,7 @@ class TestApplicationsAPI(APITestCase): """Test applications API""" def setUp(self) -> None: - self.user = User.objects.get(username="akadmin") + self.user = create_test_admin_user() self.allowed = Application.objects.create(name="allowed", slug="allowed") self.denied = Application.objects.create(name="denied", slug="denied") PolicyBinding.objects.create( diff --git a/authentik/core/tests/test_authenticated_sessions_api.py b/authentik/core/tests/test_authenticated_sessions_api.py index f258cacac..b204dfe1f 100644 --- a/authentik/core/tests/test_authenticated_sessions_api.py +++ b/authentik/core/tests/test_authenticated_sessions_api.py @@ -6,6 +6,7 @@ from django.utils.encoding import force_str from rest_framework.test import APITestCase from authentik.core.models import User +from authentik.core.tests.utils import create_test_admin_user class TestAuthenticatedSessionsAPI(APITestCase): @@ -13,7 +14,7 @@ class TestAuthenticatedSessionsAPI(APITestCase): def setUp(self) -> None: super().setUp() - self.user = User.objects.get(username="akadmin") + self.user = create_test_admin_user() self.other_user = User.objects.create(username="normal-user") def test_list(self): diff --git a/authentik/core/tests/test_impersonation.py b/authentik/core/tests/test_impersonation.py index 9a5bbdd22..12d309d59 100644 --- a/authentik/core/tests/test_impersonation.py +++ b/authentik/core/tests/test_impersonation.py @@ -5,6 +5,7 @@ from django.test.testcases import TestCase from django.urls import reverse from authentik.core.models import User +from authentik.core.tests.utils import create_test_admin_user class TestImpersonation(TestCase): @@ -13,14 +14,14 @@ class TestImpersonation(TestCase): def setUp(self) -> None: super().setUp() self.other_user = User.objects.create(username="to-impersonate") - self.akadmin = User.objects.get(username="akadmin") + self.user = create_test_admin_user() def test_impersonate_simple(self): """test simple impersonation and un-impersonation""" # test with an inactive user to ensure that still works self.other_user.is_active = False self.other_user.save() - self.client.force_login(self.akadmin) + self.client.force_login(self.user) self.client.get( reverse( @@ -32,13 +33,13 @@ class TestImpersonation(TestCase): response = self.client.get(reverse("authentik_api:user-me")) response_body = loads(response.content.decode()) self.assertEqual(response_body["user"]["username"], self.other_user.username) - self.assertEqual(response_body["original"]["username"], self.akadmin.username) + self.assertEqual(response_body["original"]["username"], self.user.username) self.client.get(reverse("authentik_core:impersonate-end")) response = self.client.get(reverse("authentik_api:user-me")) response_body = loads(response.content.decode()) - self.assertEqual(response_body["user"]["username"], self.akadmin.username) + self.assertEqual(response_body["user"]["username"], self.user.username) self.assertNotIn("original", response_body) def test_impersonate_denied(self): @@ -46,7 +47,7 @@ class TestImpersonation(TestCase): self.client.force_login(self.other_user) self.client.get( - reverse("authentik_core:impersonate-init", kwargs={"user_id": self.akadmin.pk}) + reverse("authentik_core:impersonate-init", kwargs={"user_id": self.user.pk}) ) response = self.client.get(reverse("authentik_api:user-me")) diff --git a/authentik/core/tests/test_property_mapping_api.py b/authentik/core/tests/test_property_mapping_api.py index bb3bcf2ca..d5e74f626 100644 --- a/authentik/core/tests/test_property_mapping_api.py +++ b/authentik/core/tests/test_property_mapping_api.py @@ -6,7 +6,8 @@ from rest_framework.serializers import ValidationError from rest_framework.test import APITestCase from authentik.core.api.propertymappings import PropertyMappingSerializer -from authentik.core.models import PropertyMapping, User +from authentik.core.models import PropertyMapping +from authentik.core.tests.utils import create_test_admin_user class TestPropertyMappingAPI(APITestCase): @@ -17,7 +18,7 @@ class TestPropertyMappingAPI(APITestCase): self.mapping = PropertyMapping.objects.create( name="dummy", expression="""return {'foo': 'bar'}""" ) - self.user = User.objects.get(username="akadmin") + self.user = create_test_admin_user() self.client.force_login(self.user) def test_test_call(self): diff --git a/authentik/core/tests/test_providers_api.py b/authentik/core/tests/test_providers_api.py index dbfba2594..0b09686b9 100644 --- a/authentik/core/tests/test_providers_api.py +++ b/authentik/core/tests/test_providers_api.py @@ -2,7 +2,8 @@ from django.urls import reverse from rest_framework.test import APITestCase -from authentik.core.models import PropertyMapping, User +from authentik.core.models import PropertyMapping +from authentik.core.tests.utils import create_test_admin_user class TestProvidersAPI(APITestCase): @@ -13,7 +14,7 @@ class TestProvidersAPI(APITestCase): self.mapping = PropertyMapping.objects.create( name="dummy", expression="""return {'foo': 'bar'}""" ) - self.user = User.objects.get(username="akadmin") + self.user = create_test_admin_user() self.client.force_login(self.user) def test_types(self): diff --git a/authentik/core/tests/test_token_api.py b/authentik/core/tests/test_token_api.py index 191d1498a..9c9dbcbd5 100644 --- a/authentik/core/tests/test_token_api.py +++ b/authentik/core/tests/test_token_api.py @@ -8,6 +8,7 @@ from rest_framework.test import APITestCase from authentik.core.models import USER_ATTRIBUTE_TOKEN_EXPIRING, Token, TokenIntents, User from authentik.core.tasks import clean_expired_models +from authentik.core.tests.utils import create_test_admin_user class TestTokenAPI(APITestCase): @@ -16,7 +17,7 @@ class TestTokenAPI(APITestCase): def setUp(self) -> None: super().setUp() self.user = User.objects.create(username="testuser") - self.admin = User.objects.get(username="akadmin") + self.admin = create_test_admin_user() self.client.force_login(self.user) def test_token_create(self): diff --git a/authentik/core/tests/test_users_api.py b/authentik/core/tests/test_users_api.py index 28b4a00e4..49a794960 100644 --- a/authentik/core/tests/test_users_api.py +++ b/authentik/core/tests/test_users_api.py @@ -3,7 +3,8 @@ from django.urls.base import reverse from rest_framework.test import APITestCase from authentik.core.models import USER_ATTRIBUTE_CHANGE_EMAIL, USER_ATTRIBUTE_CHANGE_USERNAME, User -from authentik.flows.models import Flow, FlowDesignation +from authentik.core.tests.utils import create_test_admin_user, create_test_flow, create_test_tenant +from authentik.flows.models import FlowDesignation from authentik.stages.email.models import EmailStage from authentik.tenants.models import Tenant @@ -12,7 +13,7 @@ class TestUsersAPI(APITestCase): """Test Users API""" def setUp(self) -> None: - self.admin = User.objects.get(username="akadmin") + self.admin = create_test_admin_user() self.user = User.objects.create(username="test-user") def test_update_self(self): @@ -69,10 +70,8 @@ class TestUsersAPI(APITestCase): def test_recovery(self): """Test user recovery link (no recovery flow set)""" - flow = Flow.objects.create( - name="test", title="test", slug="test", designation=FlowDesignation.RECOVERY - ) - tenant: Tenant = Tenant.objects.first() + flow = create_test_flow(FlowDesignation.RECOVERY) + tenant: Tenant = create_test_tenant() tenant.flow_recovery = flow tenant.save() self.client.force_login(self.admin) @@ -99,10 +98,8 @@ class TestUsersAPI(APITestCase): """Test user recovery link (no email stage)""" self.user.email = "foo@bar.baz" self.user.save() - flow = Flow.objects.create( - name="test", title="test", slug="test", designation=FlowDesignation.RECOVERY - ) - tenant: Tenant = Tenant.objects.first() + flow = create_test_flow(designation=FlowDesignation.RECOVERY) + tenant: Tenant = create_test_tenant() tenant.flow_recovery = flow tenant.save() self.client.force_login(self.admin) @@ -115,10 +112,8 @@ class TestUsersAPI(APITestCase): """Test user recovery link""" self.user.email = "foo@bar.baz" self.user.save() - flow = Flow.objects.create( - name="test", title="test", slug="test", designation=FlowDesignation.RECOVERY - ) - tenant: Tenant = Tenant.objects.first() + flow = create_test_flow(FlowDesignation.RECOVERY) + tenant: Tenant = create_test_tenant() tenant.flow_recovery = flow tenant.save() diff --git a/authentik/core/tests/utils.py b/authentik/core/tests/utils.py new file mode 100644 index 000000000..a0c05370a --- /dev/null +++ b/authentik/core/tests/utils.py @@ -0,0 +1,55 @@ +"""Test Utils""" +from typing import Optional + +from django.utils.text import slugify + +from authentik.core.models import Group, User +from authentik.crypto.builder import CertificateBuilder +from authentik.crypto.models import CertificateKeyPair +from authentik.flows.models import Flow, FlowDesignation +from authentik.lib.generators import generate_id +from authentik.tenants.models import Tenant + + +def create_test_flow(designation: FlowDesignation = FlowDesignation.STAGE_CONFIGURATION) -> Flow: + """Generate a flow that can be used for testing""" + uid = generate_id(10) + return Flow.objects.create( + name=uid, + title=uid, + slug=slugify(uid), + designation=designation, + ) + + +def create_test_admin_user(name: Optional[str] = None) -> User: + """Generate a test-admin user""" + uid = generate_id(20) if not name else name + group = Group.objects.create(name=uid, is_superuser=True) + user = User.objects.create( + username=uid, + name=uid, + email=f"{uid}@goauthentik.io", + ) + group.users.add(user) + return user + + +def create_test_tenant() -> Tenant: + """Generate a test tenant, removing all other tenants to make sure this one + matches.""" + uid = generate_id(20) + Tenant.objects.all().delete() + return Tenant.objects.create(domain=uid, default=True) + + +def create_test_cert() -> CertificateKeyPair: + """Generate a certificate for testing""" + CertificateKeyPair.objects.filter(name="goauthentik.io").delete() + builder = CertificateBuilder() + builder.common_name = "goauthentik.io" + builder.build( + subject_alt_names=["goauthentik.io"], + validity_days=360, + ) + return builder.save() diff --git a/authentik/crypto/tests.py b/authentik/crypto/tests.py index 8ab5704ae..f621b0f0d 100644 --- a/authentik/crypto/tests.py +++ b/authentik/crypto/tests.py @@ -5,11 +5,10 @@ from django.urls import reverse from rest_framework.test import APITestCase from authentik.core.api.used_by import DeleteAction -from authentik.core.models import User +from authentik.core.tests.utils import create_test_admin_user, create_test_cert, create_test_flow from authentik.crypto.api import CertificateKeyPairSerializer from authentik.crypto.builder import CertificateBuilder from authentik.crypto.models import CertificateKeyPair -from authentik.flows.models import Flow from authentik.lib.generators import generate_key from authentik.providers.oauth2.models import OAuth2Provider @@ -28,7 +27,7 @@ class TestCrypto(APITestCase): def test_serializer(self): """Test API Validation""" - keypair = CertificateKeyPair.objects.first() + keypair = create_test_cert() self.assertTrue( CertificateKeyPairSerializer( data={ @@ -65,7 +64,7 @@ class TestCrypto(APITestCase): def test_builder_api(self): """Test Builder (via API)""" - self.client.force_login(User.objects.get(username="akadmin")) + self.client.force_login(create_test_admin_user()) self.client.post( reverse("authentik_api:certificatekeypair-generate"), data={"common_name": "foo", "subject_alt_name": "bar,baz", "validity_days": 3}, @@ -74,7 +73,7 @@ class TestCrypto(APITestCase): def test_builder_api_invalid(self): """Test Builder (via API) (invalid)""" - self.client.force_login(User.objects.get(username="akadmin")) + self.client.force_login(create_test_admin_user()) response = self.client.post( reverse("authentik_api:certificatekeypair-generate"), data={}, @@ -83,7 +82,7 @@ class TestCrypto(APITestCase): def test_list(self): """Test API List""" - self.client.force_login(User.objects.get(username="akadmin")) + self.client.force_login(create_test_admin_user()) response = self.client.get( reverse( "authentik_api:certificatekeypair-list", @@ -93,8 +92,8 @@ class TestCrypto(APITestCase): def test_certificate_download(self): """Test certificate export (download)""" - self.client.force_login(User.objects.get(username="akadmin")) - keypair = CertificateKeyPair.objects.first() + self.client.force_login(create_test_admin_user()) + keypair = create_test_cert() response = self.client.get( reverse( "authentik_api:certificatekeypair-view-certificate", @@ -114,8 +113,8 @@ class TestCrypto(APITestCase): def test_private_key_download(self): """Test private_key export (download)""" - self.client.force_login(User.objects.get(username="akadmin")) - keypair = CertificateKeyPair.objects.first() + self.client.force_login(create_test_admin_user()) + keypair = create_test_cert() response = self.client.get( reverse( "authentik_api:certificatekeypair-view-private-key", @@ -135,15 +134,15 @@ class TestCrypto(APITestCase): def test_used_by(self): """Test used_by endpoint""" - self.client.force_login(User.objects.get(username="akadmin")) - keypair = CertificateKeyPair.objects.first() + self.client.force_login(create_test_admin_user()) + keypair = create_test_cert() provider = OAuth2Provider.objects.create( name="test", client_id="test", client_secret=generate_key(), - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), redirect_uris="http://localhost", - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=keypair, ) response = self.client.get( reverse( diff --git a/authentik/events/tests/test_api.py b/authentik/events/tests/test_api.py index 5d9074bbd..1225d0665 100644 --- a/authentik/events/tests/test_api.py +++ b/authentik/events/tests/test_api.py @@ -3,7 +3,7 @@ from django.urls import reverse from rest_framework.test import APITestCase -from authentik.core.models import User +from authentik.core.tests.utils import create_test_admin_user from authentik.events.models import ( Event, EventAction, @@ -17,7 +17,7 @@ class TestEventsAPI(APITestCase): """Test Event API""" def setUp(self) -> None: - self.user = User.objects.get(username="akadmin") + self.user = create_test_admin_user() self.client.force_login(self.user) def test_top_n(self): diff --git a/authentik/events/tests/test_middleware.py b/authentik/events/tests/test_middleware.py index ed91193cf..1bd667d06 100644 --- a/authentik/events/tests/test_middleware.py +++ b/authentik/events/tests/test_middleware.py @@ -3,7 +3,8 @@ from django.urls import reverse from rest_framework.test import APITestCase -from authentik.core.models import Application, User +from authentik.core.models import Application +from authentik.core.tests.utils import create_test_admin_user from authentik.events.models import Event, EventAction @@ -12,7 +13,7 @@ class TestEventsMiddleware(APITestCase): def setUp(self) -> None: super().setUp() - self.user = User.objects.get(username="akadmin") + self.user = create_test_admin_user() self.client.force_login(self.user) def test_create(self): diff --git a/authentik/flows/management/commands/benchmark.py b/authentik/flows/management/commands/benchmark.py index fec2cfd31..01271024c 100644 --- a/authentik/flows/management/commands/benchmark.py +++ b/authentik/flows/management/commands/benchmark.py @@ -10,7 +10,7 @@ from django.test import RequestFactory from structlog.stdlib import get_logger from authentik import __version__ -from authentik.core.models import User +from authentik.core.tests.utils import create_test_admin_user from authentik.flows.models import Flow from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlanner @@ -68,7 +68,7 @@ class Command(BaseCommand): # pragma: no cover def benchmark_flows(self, proc_count): """Get full recovery link""" flow = Flow.objects.get(slug="default-authentication-flow") - user = User.objects.get(username="akadmin") + user = create_test_admin_user() manager = Manager() return_dict = manager.dict() diff --git a/authentik/flows/tests/test_api.py b/authentik/flows/tests/test_api.py index 5eaeff42a..b2ee2d734 100644 --- a/authentik/flows/tests/test_api.py +++ b/authentik/flows/tests/test_api.py @@ -2,7 +2,7 @@ from django.urls import reverse from rest_framework.test import APITestCase -from authentik.core.models import User +from authentik.core.tests.utils import create_test_admin_user from authentik.flows.api.stages import StageSerializer, StageViewSet from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding, Stage from authentik.policies.dummy.models import DummyPolicy @@ -47,7 +47,7 @@ class TestFlowsAPI(APITestCase): def test_api_diagram(self): """Test flow diagram.""" - user = User.objects.get(username="akadmin") + user = create_test_admin_user() self.client.force_login(user) flow = Flow.objects.create( @@ -77,7 +77,7 @@ class TestFlowsAPI(APITestCase): def test_api_diagram_no_stages(self): """Test flow diagram with no stages.""" - user = User.objects.get(username="akadmin") + user = create_test_admin_user() self.client.force_login(user) flow = Flow.objects.create( @@ -93,7 +93,7 @@ class TestFlowsAPI(APITestCase): def test_types(self): """Test Stage's types endpoint""" - user = User.objects.get(username="akadmin") + user = create_test_admin_user() self.client.force_login(user) response = self.client.get( diff --git a/authentik/flows/tests/test_inspector.py b/authentik/flows/tests/test_inspector.py index febec1560..94804cef3 100644 --- a/authentik/flows/tests/test_inspector.py +++ b/authentik/flows/tests/test_inspector.py @@ -6,7 +6,7 @@ from django.test.client import RequestFactory from django.urls.base import reverse from rest_framework.test import APITestCase -from authentik.core.models import User +from authentik.core.tests.utils import create_test_admin_user from authentik.flows.challenge import ChallengeTypes from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding, InvalidResponseAction from authentik.stages.dummy.models import DummyStage @@ -18,7 +18,7 @@ class TestFlowInspector(APITestCase): def setUp(self): self.request_factory = RequestFactory() - self.admin = User.objects.get(username="akadmin") + self.admin = create_test_admin_user() self.client.force_login(self.admin) def test(self): @@ -77,7 +77,7 @@ class TestFlowInspector(APITestCase): self.client.post( reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}), - {"uid_field": "akadmin"}, + {"uid_field": self.admin.username}, follow=True, ) @@ -89,5 +89,5 @@ class TestFlowInspector(APITestCase): self.assertEqual(content["plans"][0]["current_stage"]["stage_obj"]["name"], "ident") self.assertEqual(content["current_plan"]["current_stage"]["stage_obj"]["name"], "dummy2") self.assertEqual( - content["current_plan"]["plan_context"]["pending_user"]["username"], "akadmin" + content["current_plan"]["plan_context"]["pending_user"]["username"], self.admin.username ) diff --git a/authentik/flows/tests/test_views_helper.py b/authentik/flows/tests/test_views_helper.py index 53322aa18..24b7392aa 100644 --- a/authentik/flows/tests/test_views_helper.py +++ b/authentik/flows/tests/test_views_helper.py @@ -2,6 +2,7 @@ from django.test import TestCase from django.urls import reverse +from authentik.core.tests.utils import create_test_flow from authentik.flows.models import Flow, FlowDesignation from authentik.flows.planner import FlowPlan from authentik.flows.views.executor import SESSION_KEY_PLAN @@ -12,9 +13,8 @@ class TestHelperView(TestCase): def test_default_view(self): """Test that ToDefaultFlow returns the expected URL""" - flow = Flow.objects.filter( - designation=FlowDesignation.INVALIDATION, - ).first() + Flow.objects.filter(designation=FlowDesignation.INVALIDATION).delete() + flow = create_test_flow(FlowDesignation.INVALIDATION) response = self.client.get( reverse("authentik_flows:default-invalidation"), ) @@ -24,9 +24,8 @@ class TestHelperView(TestCase): def test_default_view_invalid_plan(self): """Test that ToDefaultFlow returns the expected URL (with an invalid plan)""" - flow = Flow.objects.filter( - designation=FlowDesignation.INVALIDATION, - ).first() + Flow.objects.filter(designation=FlowDesignation.INVALIDATION).delete() + flow = create_test_flow(FlowDesignation.INVALIDATION) plan = FlowPlan(flow_pk=flow.pk.hex + "aa") session = self.client.session session[SESSION_KEY_PLAN] = plan diff --git a/authentik/lib/tests/test_evaluator.py b/authentik/lib/tests/test_evaluator.py index eb61be90a..44cc6e299 100644 --- a/authentik/lib/tests/test_evaluator.py +++ b/authentik/lib/tests/test_evaluator.py @@ -1,7 +1,7 @@ """Test Evaluator base functions""" from django.test import TestCase -from authentik.core.models import User +from authentik.core.tests.utils import create_test_admin_user from authentik.lib.expression.evaluator import BaseEvaluator @@ -19,12 +19,11 @@ class TestEvaluator(TestCase): def test_user_by(self): """Test expr_user_by""" - self.assertIsNotNone(BaseEvaluator.expr_user_by(username="akadmin")) + user = create_test_admin_user() + self.assertIsNotNone(BaseEvaluator.expr_user_by(username=user.username)) self.assertIsNone(BaseEvaluator.expr_user_by(username="bar")) self.assertIsNone(BaseEvaluator.expr_user_by(foo="bar")) def test_is_group_member(self): """Test expr_is_group_member""" - self.assertFalse( - BaseEvaluator.expr_is_group_member(User.objects.get(username="akadmin"), name="test") - ) + self.assertFalse(BaseEvaluator.expr_is_group_member(create_test_admin_user(), name="test")) diff --git a/authentik/lib/tests/test_http.py b/authentik/lib/tests/test_http.py index 3eaa38d2c..046fcab3c 100644 --- a/authentik/lib/tests/test_http.py +++ b/authentik/lib/tests/test_http.py @@ -1,7 +1,8 @@ """Test HTTP Helpers""" from django.test import RequestFactory, TestCase -from authentik.core.models import USER_ATTRIBUTE_CAN_OVERRIDE_IP, Token, TokenIntents, User +from authentik.core.models import USER_ATTRIBUTE_CAN_OVERRIDE_IP, Token, TokenIntents +from authentik.core.tests.utils import create_test_admin_user from authentik.lib.utils.http import OUTPOST_REMOTE_IP_HEADER, OUTPOST_TOKEN_HEADER, get_client_ip from authentik.lib.views import bad_request_message @@ -10,7 +11,7 @@ class TestHTTP(TestCase): """Test HTTP Helpers""" def setUp(self) -> None: - self.user = User.objects.get(username="akadmin") + self.user = create_test_admin_user() self.factory = RequestFactory() def test_bad_request_message(self): diff --git a/authentik/outposts/tests/test_api.py b/authentik/outposts/tests/test_api.py index dc7cb57bb..f074b56b1 100644 --- a/authentik/outposts/tests/test_api.py +++ b/authentik/outposts/tests/test_api.py @@ -2,8 +2,8 @@ from django.urls import reverse from rest_framework.test import APITestCase -from authentik.core.models import PropertyMapping, User -from authentik.flows.models import Flow +from authentik.core.models import PropertyMapping +from authentik.core.tests.utils import create_test_admin_user, create_test_flow from authentik.outposts.api.outposts import OutpostSerializer from authentik.outposts.models import OutpostType, default_outpost_config from authentik.providers.ldap.models import LDAPProvider @@ -18,7 +18,7 @@ class TestOutpostServiceConnectionsAPI(APITestCase): self.mapping = PropertyMapping.objects.create( name="dummy", expression="""return {'foo': 'bar'}""" ) - self.user = User.objects.get(username="akadmin") + self.user = create_test_admin_user() self.client.force_login(self.user) def test_outpost_validaton(self): @@ -30,7 +30,7 @@ class TestOutpostServiceConnectionsAPI(APITestCase): "config": default_outpost_config(), "providers": [ ProxyProvider.objects.create( - name="test", authorization_flow=Flow.objects.first() + name="test", authorization_flow=create_test_flow() ).pk ], } @@ -43,7 +43,7 @@ class TestOutpostServiceConnectionsAPI(APITestCase): "config": default_outpost_config(), "providers": [ LDAPProvider.objects.create( - name="test", authorization_flow=Flow.objects.first() + name="test", authorization_flow=create_test_flow() ).pk ], } @@ -60,9 +60,7 @@ class TestOutpostServiceConnectionsAPI(APITestCase): def test_outpost_config(self): """Test Outpost's config field""" - provider = ProxyProvider.objects.create( - name="test", authorization_flow=Flow.objects.first() - ) + provider = ProxyProvider.objects.create(name="test", authorization_flow=create_test_flow()) invalid = OutpostSerializer(data={"name": "foo", "providers": [provider.pk], "config": ""}) self.assertFalse(invalid.is_valid()) self.assertIn("config", invalid.errors) diff --git a/authentik/outposts/tests/test_sa.py b/authentik/outposts/tests/test_sa.py index 761cbabe0..de73071ae 100644 --- a/authentik/outposts/tests/test_sa.py +++ b/authentik/outposts/tests/test_sa.py @@ -4,8 +4,7 @@ from django.contrib.auth.management import create_permissions from django.test import TestCase from guardian.models import UserObjectPermission -from authentik.crypto.models import CertificateKeyPair -from authentik.flows.models import Flow +from authentik.core.tests.utils import create_test_cert, create_test_flow from authentik.outposts.models import Outpost, OutpostType from authentik.providers.proxy.models import ProxyProvider @@ -23,7 +22,7 @@ class OutpostTests(TestCase): name="test", internal_host="http://localhost", external_host="http://localhost", - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), ) outpost: Outpost = Outpost.objects.create( name="test", @@ -45,7 +44,7 @@ class OutpostTests(TestCase): self.assertEqual(permissions[1].object_pk, str(provider.pk)) # Provider requires a certificate-key-pair, user should have permissions for it - keypair = CertificateKeyPair.objects.first() + keypair = create_test_cert() provider.certificate = keypair provider.save() permissions = UserObjectPermission.objects.filter(user=outpost.user).order_by( diff --git a/authentik/policies/tests/test_bindings_api.py b/authentik/policies/tests/test_bindings_api.py index 51be90073..17046d6ca 100644 --- a/authentik/policies/tests/test_bindings_api.py +++ b/authentik/policies/tests/test_bindings_api.py @@ -2,7 +2,7 @@ from django.urls import reverse from rest_framework.test import APITestCase -from authentik.core.models import Group, User +from authentik.core.tests.utils import create_test_admin_user from authentik.policies.models import PolicyBindingModel @@ -12,8 +12,8 @@ class TestBindingsAPI(APITestCase): def setUp(self) -> None: super().setUp() self.pbm = PolicyBindingModel.objects.create() - self.group = Group.objects.first() - self.user = User.objects.get(username="akadmin") + self.user = create_test_admin_user() + self.group = self.user.ak_groups.first() self.client.force_login(self.user) def test_valid_binding(self): diff --git a/authentik/policies/tests/test_policies_api.py b/authentik/policies/tests/test_policies_api.py index 53ec110a6..3266462b5 100644 --- a/authentik/policies/tests/test_policies_api.py +++ b/authentik/policies/tests/test_policies_api.py @@ -2,7 +2,7 @@ from django.urls import reverse from rest_framework.test import APITestCase -from authentik.core.models import User +from authentik.core.tests.utils import create_test_admin_user from authentik.policies.dummy.models import DummyPolicy @@ -12,7 +12,7 @@ class TestPoliciesAPI(APITestCase): def setUp(self) -> None: super().setUp() self.policy = DummyPolicy.objects.create(name="dummy", result=True) - self.user = User.objects.get(username="akadmin") + self.user = create_test_admin_user() self.client.force_login(self.user) def test_test_call(self): diff --git a/authentik/providers/oauth2/tests/test_api.py b/authentik/providers/oauth2/tests/test_api.py index 6830a09e2..fd854ad1a 100644 --- a/authentik/providers/oauth2/tests/test_api.py +++ b/authentik/providers/oauth2/tests/test_api.py @@ -2,8 +2,7 @@ from django.urls import reverse from rest_framework.test import APITestCase -from authentik.core.models import User -from authentik.flows.models import Flow, FlowDesignation +from authentik.core.tests.utils import create_test_admin_user, create_test_flow from authentik.providers.oauth2.models import JWTAlgorithms @@ -12,7 +11,7 @@ class TestOAuth2ProviderAPI(APITestCase): def setUp(self) -> None: super().setUp() - self.user = User.objects.get(username="akadmin") + self.user = create_test_admin_user() self.client.force_login(self.user) def test_validate(self): @@ -24,9 +23,7 @@ class TestOAuth2ProviderAPI(APITestCase): data={ "name": "test", "jwt_alg": str(JWTAlgorithms.RS256), - "authorization_flow": Flow.objects.filter(designation=FlowDesignation.AUTHORIZATION) - .first() - .pk, + "authorization_flow": create_test_flow().pk, }, ) self.assertJSONEqual( diff --git a/authentik/providers/oauth2/tests/test_authorize.py b/authentik/providers/oauth2/tests/test_authorize.py index cbf4d0978..cc6cb64a4 100644 --- a/authentik/providers/oauth2/tests/test_authorize.py +++ b/authentik/providers/oauth2/tests/test_authorize.py @@ -3,8 +3,8 @@ from django.test import RequestFactory from django.urls import reverse from django.utils.encoding import force_str -from authentik.core.models import Application, User -from authentik.crypto.models import CertificateKeyPair +from authentik.core.models import Application +from authentik.core.tests.utils import create_test_admin_user, create_test_cert, create_test_flow from authentik.flows.challenge import ChallengeTypes from authentik.flows.models import Flow from authentik.lib.generators import generate_id, generate_key @@ -43,7 +43,7 @@ class TestAuthorize(OAuthTestCase): OAuth2Provider.objects.create( name="test", client_id="test", - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), redirect_uris="http://local.invalid", ) with self.assertRaises(AuthorizeError): @@ -63,7 +63,7 @@ class TestAuthorize(OAuthTestCase): OAuth2Provider.objects.create( name="test", client_id="test", - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), redirect_uris="http://local.invalid", ) with self.assertRaises(RedirectUriError): @@ -85,7 +85,7 @@ class TestAuthorize(OAuthTestCase): OAuth2Provider.objects.create( name="test", client_id="test", - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), ) with self.assertRaises(RedirectUriError): request = self.factory.get("/", data={"response_type": "code", "client_id": "test"}) @@ -105,7 +105,7 @@ class TestAuthorize(OAuthTestCase): OAuth2Provider.objects.create( name="test", client_id="test", - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), redirect_uris="http://local.invalid", ) request = self.factory.get( @@ -184,7 +184,7 @@ class TestAuthorize(OAuthTestCase): ) Application.objects.create(name="app", slug="app", provider=provider) state = generate_id() - user = User.objects.get(username="akadmin") + user = create_test_admin_user() self.client.force_login(user) # Step 1, initiate params and get redirect to flow self.client.get( @@ -218,11 +218,11 @@ class TestAuthorize(OAuthTestCase): client_secret=generate_key(), authorization_flow=flow, redirect_uris="http://localhost", - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), ) Application.objects.create(name="app", slug="app", provider=provider) state = generate_id() - user = User.objects.get(username="akadmin") + user = create_test_admin_user() self.client.force_login(user) # Step 1, initiate params and get redirect to flow self.client.get( diff --git a/authentik/providers/oauth2/tests/test_jwks.py b/authentik/providers/oauth2/tests/test_jwks.py index 9c928a083..8dc6e84d9 100644 --- a/authentik/providers/oauth2/tests/test_jwks.py +++ b/authentik/providers/oauth2/tests/test_jwks.py @@ -6,8 +6,7 @@ from django.urls.base import reverse from django.utils.encoding import force_str from authentik.core.models import Application -from authentik.crypto.models import CertificateKeyPair -from authentik.flows.models import Flow +from authentik.core.tests.utils import create_test_cert, create_test_flow from authentik.providers.oauth2.models import OAuth2Provider from authentik.providers.oauth2.tests.utils import OAuthTestCase @@ -24,9 +23,9 @@ class TestJWKS(OAuthTestCase): provider = OAuth2Provider.objects.create( name="test", client_id="test", - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), redirect_uris="http://local.invalid", - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), ) app = Application.objects.create(name="test", slug="test", provider=provider) response = self.client.get( @@ -40,7 +39,7 @@ class TestJWKS(OAuthTestCase): provider = OAuth2Provider.objects.create( name="test", client_id="test", - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), redirect_uris="http://local.invalid", ) app = Application.objects.create(name="test", slug="test", provider=provider) diff --git a/authentik/providers/oauth2/tests/test_token.py b/authentik/providers/oauth2/tests/test_token.py index 1ec7e4521..543b26dd0 100644 --- a/authentik/providers/oauth2/tests/test_token.py +++ b/authentik/providers/oauth2/tests/test_token.py @@ -5,10 +5,9 @@ from django.test import RequestFactory from django.urls import reverse from django.utils.encoding import force_str -from authentik.core.models import Application, User -from authentik.crypto.models import CertificateKeyPair +from authentik.core.models import Application +from authentik.core.tests.utils import create_test_admin_user, create_test_cert, create_test_flow from authentik.events.models import Event, EventAction -from authentik.flows.models import Flow from authentik.lib.generators import generate_id, generate_key from authentik.providers.oauth2.constants import ( GRANT_TYPE_AUTHORIZATION_CODE, @@ -34,12 +33,12 @@ class TestToken(OAuthTestCase): name="test", client_id=generate_id(), client_secret=generate_key(), - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), redirect_uris="http://testserver", - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), ) header = b64encode(f"{provider.client_id}:{provider.client_secret}".encode()).decode() - user = User.objects.get(username="akadmin") + user = create_test_admin_user() code = AuthorizationCode.objects.create(code="foobar", provider=provider, user=user) request = self.factory.post( "/", @@ -61,9 +60,9 @@ class TestToken(OAuthTestCase): name="test", client_id=generate_id(), client_secret=generate_key(), - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), redirect_uris="http://testserver", - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), ) header = b64encode(f"{provider.client_id}:{provider.client_secret}".encode()).decode() request = self.factory.post( @@ -84,12 +83,12 @@ class TestToken(OAuthTestCase): name="test", client_id=generate_id(), client_secret=generate_key(), - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), redirect_uris="http://local.invalid", - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), ) header = b64encode(f"{provider.client_id}:{provider.client_secret}".encode()).decode() - user = User.objects.get(username="akadmin") + user = create_test_admin_user() token: RefreshToken = RefreshToken.objects.create( provider=provider, user=user, @@ -113,15 +112,15 @@ class TestToken(OAuthTestCase): name="test", client_id=generate_id(), client_secret=generate_key(), - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), redirect_uris="http://local.invalid", - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), ) # Needs to be assigned to an application for iss to be set self.app.provider = provider self.app.save() header = b64encode(f"{provider.client_id}:{provider.client_secret}".encode()).decode() - user = User.objects.get(username="akadmin") + user = create_test_admin_user() code = AuthorizationCode.objects.create( code="foobar", provider=provider, user=user, is_open_id=True ) @@ -155,15 +154,15 @@ class TestToken(OAuthTestCase): name="test", client_id=generate_id(), client_secret=generate_key(), - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), redirect_uris="http://local.invalid", - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), ) # Needs to be assigned to an application for iss to be set self.app.provider = provider self.app.save() header = b64encode(f"{provider.client_id}:{provider.client_secret}".encode()).decode() - user = User.objects.get(username="akadmin") + user = create_test_admin_user() token: RefreshToken = RefreshToken.objects.create( provider=provider, user=user, @@ -204,12 +203,12 @@ class TestToken(OAuthTestCase): name="test", client_id=generate_id(), client_secret=generate_key(), - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), redirect_uris="http://local.invalid", - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), ) header = b64encode(f"{provider.client_id}:{provider.client_secret}".encode()).decode() - user = User.objects.get(username="akadmin") + user = create_test_admin_user() token: RefreshToken = RefreshToken.objects.create( provider=provider, user=user, @@ -249,15 +248,15 @@ class TestToken(OAuthTestCase): name="test", client_id=generate_id(), client_secret=generate_key(), - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), redirect_uris="http://testserver", - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), ) # Needs to be assigned to an application for iss to be set self.app.provider = provider self.app.save() header = b64encode(f"{provider.client_id}:{provider.client_secret}".encode()).decode() - user = User.objects.get(username="akadmin") + user = create_test_admin_user() token: RefreshToken = RefreshToken.objects.create( provider=provider, user=user, diff --git a/authentik/providers/oauth2/tests/test_userinfo.py b/authentik/providers/oauth2/tests/test_userinfo.py index 97cb33871..494aed946 100644 --- a/authentik/providers/oauth2/tests/test_userinfo.py +++ b/authentik/providers/oauth2/tests/test_userinfo.py @@ -5,10 +5,9 @@ from dataclasses import asdict from django.urls import reverse from django.utils.encoding import force_str -from authentik.core.models import Application, User -from authentik.crypto.models import CertificateKeyPair +from authentik.core.models import Application +from authentik.core.tests.utils import create_test_admin_user, create_test_cert, create_test_flow from authentik.events.models import Event, EventAction -from authentik.flows.models import Flow from authentik.lib.generators import generate_id, generate_key from authentik.managed.manager import ObjectManager from authentik.providers.oauth2.models import IDToken, OAuth2Provider, RefreshToken, ScopeMapping @@ -26,15 +25,15 @@ class TestUserinfo(OAuthTestCase): name="test", client_id=generate_id(), client_secret=generate_key(), - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), redirect_uris="", - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), ) self.provider.property_mappings.set(ScopeMapping.objects.all()) # Needs to be assigned to an application for iss to be set self.app.provider = self.provider self.app.save() - self.user = User.objects.get(username="akadmin") + self.user = create_test_admin_user() self.token: RefreshToken = RefreshToken.objects.create( provider=self.provider, user=self.user, @@ -57,12 +56,12 @@ class TestUserinfo(OAuthTestCase): self.assertJSONEqual( force_str(res.content), { - "name": "authentik Default Admin", - "given_name": "authentik Default Admin", + "name": self.user.name, + "given_name": self.user.name, "family_name": "", - "preferred_username": "akadmin", - "nickname": "akadmin", - "groups": ["authentik Admins"], + "preferred_username": self.user.name, + "nickname": self.user.name, + "groups": [group.name for group in self.user.ak_groups.all()], "sub": "bar", }, ) @@ -80,12 +79,12 @@ class TestUserinfo(OAuthTestCase): self.assertJSONEqual( force_str(res.content), { - "name": "authentik Default Admin", - "given_name": "authentik Default Admin", + "name": self.user.name, + "given_name": self.user.name, "family_name": "", - "preferred_username": "akadmin", - "nickname": "akadmin", - "groups": ["authentik Admins"], + "preferred_username": self.user.name, + "nickname": self.user.name, + "groups": [group.name for group in self.user.ak_groups.all()], "sub": "bar", }, ) diff --git a/authentik/providers/saml/tests/test_api.py b/authentik/providers/saml/tests/test_api.py index ad7b0dacd..ecbe5227c 100644 --- a/authentik/providers/saml/tests/test_api.py +++ b/authentik/providers/saml/tests/test_api.py @@ -4,8 +4,9 @@ from tempfile import TemporaryFile from django.urls import reverse from rest_framework.test import APITestCase -from authentik.core.models import Application, User -from authentik.flows.models import Flow, FlowDesignation +from authentik.core.models import Application +from authentik.core.tests.utils import create_test_admin_user, create_test_flow +from authentik.flows.models import FlowDesignation from authentik.providers.saml.models import SAMLProvider from authentik.providers.saml.tests.test_metadata import METADATA_SIMPLE @@ -15,7 +16,7 @@ class TestSAMLProviderAPI(APITestCase): def setUp(self) -> None: super().setUp() - self.user = User.objects.get(username="akadmin") + self.user = create_test_admin_user() self.client.force_login(self.user) def test_metadata(self): @@ -23,9 +24,7 @@ class TestSAMLProviderAPI(APITestCase): self.client.logout() provider = SAMLProvider.objects.create( name="test", - authorization_flow=Flow.objects.get( - slug="default-provider-authorization-implicit-consent" - ), + authorization_flow=create_test_flow(), ) Application.objects.create(name="test", provider=provider, slug="test") response = self.client.get( @@ -38,9 +37,7 @@ class TestSAMLProviderAPI(APITestCase): self.client.logout() provider = SAMLProvider.objects.create( name="test", - authorization_flow=Flow.objects.get( - slug="default-provider-authorization-implicit-consent" - ), + authorization_flow=create_test_flow(), ) Application.objects.create(name="test", provider=provider, slug="test") response = self.client.get( @@ -56,9 +53,7 @@ class TestSAMLProviderAPI(APITestCase): # Provider without application provider = SAMLProvider.objects.create( name="test", - authorization_flow=Flow.objects.get( - slug="default-provider-authorization-implicit-consent" - ), + authorization_flow=create_test_flow(), ) response = self.client.get( reverse("authentik_api:samlprovider-metadata", kwargs={"pk": provider.pk}), @@ -79,11 +74,7 @@ class TestSAMLProviderAPI(APITestCase): { "file": metadata, "name": "test", - "authorization_flow": Flow.objects.filter( - designation=FlowDesignation.AUTHORIZATION - ) - .first() - .slug, + "authorization_flow": create_test_flow(FlowDesignation.AUTHORIZATION).slug, }, format="multipart", ) @@ -100,11 +91,7 @@ class TestSAMLProviderAPI(APITestCase): { "file": metadata, "name": "test", - "authorization_flow": Flow.objects.filter( - designation=FlowDesignation.AUTHORIZATION - ) - .first() - .slug, + "authorization_flow": create_test_flow().slug, }, format="multipart", ) diff --git a/authentik/providers/saml/tests/test_auth_n_request.py b/authentik/providers/saml/tests/test_auth_n_request.py index a78373fd8..6820191fa 100644 --- a/authentik/providers/saml/tests/test_auth_n_request.py +++ b/authentik/providers/saml/tests/test_auth_n_request.py @@ -4,10 +4,9 @@ from base64 import b64encode from django.http.request import QueryDict from django.test import RequestFactory, TestCase -from authentik.core.models import User +from authentik.core.tests.utils import create_test_admin_user, create_test_cert, create_test_flow from authentik.crypto.models import CertificateKeyPair from authentik.events.models import Event, EventAction -from authentik.flows.models import Flow from authentik.lib.tests.utils import get_request from authentik.managed.manager import ObjectManager from authentik.providers.saml.models import SAMLPropertyMapping, SAMLProvider @@ -76,11 +75,9 @@ class TestAuthNRequest(TestCase): def setUp(self): ObjectManager().run() - cert = CertificateKeyPair.objects.first() + cert = create_test_cert() self.provider: SAMLProvider = SAMLProvider.objects.create( - authorization_flow=Flow.objects.get( - slug="default-provider-authorization-implicit-consent" - ), + authorization_flow=create_test_flow(), acs_url="http://testserver/source/saml/provider/acs/", signing_kp=cert, verification_kp=cert, @@ -90,7 +87,7 @@ class TestAuthNRequest(TestCase): self.source = SAMLSource.objects.create( slug="provider", issuer="authentik", - pre_authentication_flow=Flow.objects.get(slug="default-source-pre-authentication"), + pre_authentication_flow=create_test_flow(), signing_kp=cert, ) self.factory = RequestFactory() @@ -186,9 +183,7 @@ class TestAuthNRequest(TestCase): ) provider = SAMLProvider( name="samltool", - authorization_flow=Flow.objects.get( - slug="default-provider-authorization-implicit-consent" - ), + authorization_flow=create_test_flow(), acs_url="https://10.120.20.200/saml-sp/SAML2/POST", audience="https://10.120.20.200/saml-sp/SAML2/POST", issuer="https://10.120.20.200/saml-sp/SAML2/POST", @@ -206,16 +201,14 @@ class TestAuthNRequest(TestCase): """Test post request with static request""" provider = SAMLProvider( name="aws", - authorization_flow=Flow.objects.get( - slug="default-provider-authorization-implicit-consent" - ), + authorization_flow=create_test_flow(), acs_url=( "https://eu-central-1.signin.aws.amazon.com/platform/" "saml/acs/2d737f96-55fb-4035-953e-5e24134eb778" ), audience="https://10.120.20.200/saml-sp/SAML2/POST", issuer="https://10.120.20.200/saml-sp/SAML2/POST", - signing_kp=CertificateKeyPair.objects.first(), + signing_kp=create_test_cert(), ) parsed_request = AuthNRequestParser(provider).parse(POST_REQUEST) self.assertEqual(parsed_request.id, "aws_LDxLGeubpc5lx12gxCgS6uPbix1yd5re") @@ -223,7 +216,8 @@ class TestAuthNRequest(TestCase): def test_request_attributes(self): """Test full SAML Request/Response flow, fully signed""" - http_request = get_request("/", user=User.objects.get(username="akadmin")) + user = create_test_admin_user() + http_request = get_request("/", user=user) # First create an AuthNRequest request_proc = RequestProcessor(self.source, http_request, "test_state") @@ -235,11 +229,12 @@ class TestAuthNRequest(TestCase): ) # Now create a response and convert it to string (provider) response_proc = AssertionProcessor(self.provider, http_request, parsed_request) - self.assertIn("akadmin", response_proc.build_response()) + self.assertIn(user.username, response_proc.build_response()) def test_request_attributes_invalid(self): """Test full SAML Request/Response flow, fully signed""" - http_request = get_request("/", user=User.objects.get(username="akadmin")) + user = create_test_admin_user() + http_request = get_request("/", user=user) # First create an AuthNRequest request_proc = RequestProcessor(self.source, http_request, "test_state") @@ -255,7 +250,7 @@ class TestAuthNRequest(TestCase): ) # Now create a response and convert it to string (provider) response_proc = AssertionProcessor(self.provider, http_request, parsed_request) - self.assertIn("akadmin", response_proc.build_response()) + self.assertIn(user.username, response_proc.build_response()) events = Event.objects.filter( action=EventAction.CONFIGURATION_ERROR, diff --git a/authentik/providers/saml/tests/test_metadata.py b/authentik/providers/saml/tests/test_metadata.py index e07931643..165004372 100644 --- a/authentik/providers/saml/tests/test_metadata.py +++ b/authentik/providers/saml/tests/test_metadata.py @@ -3,7 +3,7 @@ from django.test import TestCase -from authentik.flows.models import Flow +from authentik.core.tests.utils import create_test_cert, create_test_flow from authentik.providers.saml.models import SAMLBindings, SAMLPropertyMapping from authentik.providers.saml.processors.metadata_parser import ServiceProviderMetadataParser @@ -65,7 +65,7 @@ class TestServiceProviderMetadataParser(TestCase): """Test ServiceProviderMetadataParser parsing and creation of SAML Provider""" def setUp(self) -> None: - self.flow = Flow.objects.first() + self.flow = create_test_flow() def test_simple(self): """Test simple metadata without Singing""" @@ -81,6 +81,7 @@ class TestServiceProviderMetadataParser(TestCase): def test_with_signing_cert(self): """Test Metadata with signing cert""" + create_test_cert() metadata = ServiceProviderMetadataParser().parse(METADATA_CERT) provider = metadata.to_provider("test", self.flow) self.assertEqual(provider.acs_url, "http://localhost:8080/apps/user_saml/saml/acs") diff --git a/authentik/providers/saml/tests/test_schema.py b/authentik/providers/saml/tests/test_schema.py index 800df49d9..9fbe7f869 100644 --- a/authentik/providers/saml/tests/test_schema.py +++ b/authentik/providers/saml/tests/test_schema.py @@ -4,8 +4,7 @@ from base64 import b64encode from django.test import RequestFactory, TestCase from lxml import etree # nosec -from authentik.crypto.models import CertificateKeyPair -from authentik.flows.models import Flow +from authentik.core.tests.utils import create_test_cert, create_test_flow from authentik.lib.tests.utils import get_request from authentik.managed.manager import ObjectManager from authentik.providers.saml.models import SAMLPropertyMapping, SAMLProvider @@ -20,11 +19,9 @@ class TestSchema(TestCase): def setUp(self): ObjectManager().run() - cert = CertificateKeyPair.objects.first() + cert = create_test_cert() self.provider: SAMLProvider = SAMLProvider.objects.create( - authorization_flow=Flow.objects.get( - slug="default-provider-authorization-implicit-consent" - ), + authorization_flow=create_test_flow(), acs_url="http://testserver/source/saml/provider/acs/", signing_kp=cert, verification_kp=cert, @@ -35,7 +32,7 @@ class TestSchema(TestCase): slug="provider", issuer="authentik", signing_kp=cert, - pre_authentication_flow=Flow.objects.get(slug="default-source-pre-authentication"), + pre_authentication_flow=create_test_flow(), ) self.factory = RequestFactory() diff --git a/authentik/sources/saml/tests/test_metadata.py b/authentik/sources/saml/tests/test_metadata.py index 672c20262..0ad74df89 100644 --- a/authentik/sources/saml/tests/test_metadata.py +++ b/authentik/sources/saml/tests/test_metadata.py @@ -3,8 +3,7 @@ from defusedxml import ElementTree from django.test import RequestFactory, TestCase from lxml import etree # nosec -from authentik.crypto.models import CertificateKeyPair -from authentik.flows.models import Flow +from authentik.core.tests.utils import create_test_cert, create_test_flow from authentik.sources.saml.models import SAMLSource from authentik.sources.saml.processors.metadata import MetadataProcessor @@ -20,8 +19,8 @@ class TestMetadataProcessor(TestCase): source = SAMLSource.objects.create( slug="provider", issuer="authentik", - signing_kp=CertificateKeyPair.objects.first(), - pre_authentication_flow=Flow.objects.get(slug="default-source-pre-authentication"), + signing_kp=create_test_cert(), + pre_authentication_flow=create_test_flow(), ) request = self.factory.get("/") xml = MetadataProcessor(source, request).build_entity_descriptor() @@ -35,8 +34,8 @@ class TestMetadataProcessor(TestCase): source = SAMLSource.objects.create( slug="provider", issuer="authentik", - signing_kp=CertificateKeyPair.objects.first(), - pre_authentication_flow=Flow.objects.get(slug="default-source-pre-authentication"), + signing_kp=create_test_cert(), + pre_authentication_flow=create_test_flow(), ) request = self.factory.get("/") xml = MetadataProcessor(source, request).build_entity_descriptor() @@ -48,7 +47,7 @@ class TestMetadataProcessor(TestCase): source = SAMLSource.objects.create( slug="provider", issuer="authentik", - pre_authentication_flow=Flow.objects.get(slug="default-source-pre-authentication"), + pre_authentication_flow=create_test_flow(), ) request = self.factory.get("/") xml = MetadataProcessor(source, request).build_entity_descriptor() diff --git a/authentik/stages/authenticator_validate/tests.py b/authentik/stages/authenticator_validate/tests.py index 7a5dbca7a..29643df0a 100644 --- a/authentik/stages/authenticator_validate/tests.py +++ b/authentik/stages/authenticator_validate/tests.py @@ -9,7 +9,7 @@ from rest_framework.exceptions import ValidationError from rest_framework.test import APITestCase from webauthn.helpers import bytes_to_base64url -from authentik.core.models import User +from authentik.core.tests.utils import create_test_admin_user from authentik.flows.challenge import ChallengeTypes from authentik.flows.models import Flow, FlowStageBinding, NotConfiguredAction from authentik.lib.generators import generate_id, generate_key @@ -31,7 +31,7 @@ class AuthenticatorValidateStageTests(APITestCase): """Test validator stage""" def setUp(self) -> None: - self.user = User.objects.get(username="akadmin") + self.user = create_test_admin_user() self.request_factory = RequestFactory() def test_not_configured_action(self): @@ -53,7 +53,7 @@ class AuthenticatorValidateStageTests(APITestCase): response = self.client.post( reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}), - {"uid_field": "akadmin"}, + {"uid_field": self.user.username}, ) self.assertEqual(response.status_code, 302) response = self.client.get( diff --git a/authentik/stages/email/tests/test_api.py b/authentik/stages/email/tests/test_api.py index f3899850d..56c809870 100644 --- a/authentik/stages/email/tests/test_api.py +++ b/authentik/stages/email/tests/test_api.py @@ -3,7 +3,7 @@ from django.urls import reverse from rest_framework.serializers import ValidationError from rest_framework.test import APITestCase -from authentik.core.models import User +from authentik.core.tests.utils import create_test_admin_user from authentik.stages.email.api import EmailStageSerializer from authentik.stages.email.models import EmailTemplates @@ -13,8 +13,8 @@ class TestEmailStageAPI(APITestCase): def setUp(self): super().setUp() - self.akadmin = User.objects.get(username="akadmin") - self.client.force_login(self.akadmin) + self.user = create_test_admin_user() + self.client.force_login(self.user) def test_templates(self): """Test template list""" diff --git a/authentik/stages/invitation/tests.py b/authentik/stages/invitation/tests.py index 456bdc867..fc279f37b 100644 --- a/authentik/stages/invitation/tests.py +++ b/authentik/stages/invitation/tests.py @@ -8,6 +8,7 @@ from guardian.shortcuts import get_anonymous_user from rest_framework.test import APITestCase from authentik.core.models import User +from authentik.core.tests.utils import create_test_admin_user from authentik.flows.challenge import ChallengeTypes from authentik.flows.markers import StageMarker from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding @@ -167,7 +168,7 @@ class TestInvitationsAPI(APITestCase): def setUp(self) -> None: super().setUp() - self.user = User.objects.get(username="akadmin") + self.user = create_test_admin_user() self.client.force_login(self.user) def test_invite_create(self): diff --git a/authentik/stages/prompt/tests.py b/authentik/stages/prompt/tests.py index b109cc4ce..95643d539 100644 --- a/authentik/stages/prompt/tests.py +++ b/authentik/stages/prompt/tests.py @@ -7,6 +7,7 @@ from rest_framework.exceptions import ErrorDetail from rest_framework.test import APITestCase from authentik.core.models import User +from authentik.core.tests.utils import create_test_admin_user from authentik.flows.challenge import ChallengeTypes from authentik.flows.markers import StageMarker from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding @@ -202,8 +203,9 @@ class TestPromptStage(APITestCase): def test_invalid_username(self): """Test challenge_response validation""" + user = create_test_admin_user() plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()]) - self.prompt_data["username_prompt"] = "akadmin" + self.prompt_data["username_prompt"] = user.username challenge_response = PromptChallengeResponse( None, stage=self.stage, plan=plan, data=self.prompt_data ) diff --git a/authentik/stages/user_write/tests.py b/authentik/stages/user_write/tests.py index 53cab1dcf..17e33fad9 100644 --- a/authentik/stages/user_write/tests.py +++ b/authentik/stages/user_write/tests.py @@ -9,6 +9,7 @@ from rest_framework.test import APITestCase from authentik.core.models import USER_ATTRIBUTE_SOURCES, Group, Source, User, UserSourceConnection from authentik.core.sources.stage import PLAN_CONTEXT_SOURCES_CONNECTION +from authentik.core.tests.utils import create_test_admin_user from authentik.flows.challenge import ChallengeTypes from authentik.flows.markers import StageMarker from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding @@ -182,10 +183,11 @@ class TestUserWriteStage(APITestCase): ) def test_duplicate_data(self): """Test with duplicate data, should trigger error""" + user = create_test_admin_user() plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()]) session = self.client.session plan.context[PLAN_CONTEXT_PROMPT] = { - "username": "akadmin", + "username": user.username, "attribute_some-custom-attribute": "test", "some_ignored_attribute": "bar", } diff --git a/authentik/tenants/tests.py b/authentik/tenants/tests.py index bc2d58b07..63d948832 100644 --- a/authentik/tenants/tests.py +++ b/authentik/tenants/tests.py @@ -4,6 +4,7 @@ from django.test.client import RequestFactory from django.urls import reverse from django.utils.encoding import force_str +from authentik.core.tests.utils import create_test_tenant from authentik.events.models import Event, EventAction from authentik.lib.config import CONFIG from authentik.lib.utils.time import timedelta_from_string @@ -15,16 +16,15 @@ class TestTenants(TestCase): def test_current_tenant(self): """Test Current tenant API""" + tenant = create_test_tenant() self.assertJSONEqual( force_str(self.client.get(reverse("authentik_api:tenant-current")).content), { "branding_logo": "/static/dist/assets/icons/icon_left_brand.svg", "branding_favicon": "/static/dist/assets/icons/icon.png", "branding_title": "authentik", - "matched_domain": "authentik-default", + "matched_domain": tenant.domain, "ui_footer_links": CONFIG.y("footer_links"), - "flow_authentication": "default-authentication-flow", - "flow_invalidation": "default-invalidation-flow", }, ) diff --git a/tests/e2e/test_provider_oauth2_grafana.py b/tests/e2e/test_provider_oauth2_grafana.py index 75ea5d5ee..d73cc4f06 100644 --- a/tests/e2e/test_provider_oauth2_grafana.py +++ b/tests/e2e/test_provider_oauth2_grafana.py @@ -10,7 +10,7 @@ from selenium.webdriver.support import expected_conditions as ec from structlog.stdlib import get_logger from authentik.core.models import Application -from authentik.crypto.models import CertificateKeyPair +from authentik.core.tests.utils import create_test_cert from authentik.flows.models import Flow from authentik.lib.generators import generate_id, generate_key from authentik.policies.expression.models import ExpressionPolicy @@ -85,7 +85,7 @@ class TestProviderOAuth2OAuth(SeleniumTestCase): client_type=ClientTypes.CONFIDENTIAL, client_id=self.client_id, client_secret=self.client_secret, - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), redirect_uris="http://localhost:3000/", authorization_flow=authorization_flow, ) @@ -128,7 +128,7 @@ class TestProviderOAuth2OAuth(SeleniumTestCase): client_type=ClientTypes.CONFIDENTIAL, client_id=self.client_id, client_secret=self.client_secret, - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), redirect_uris="http://localhost:3000/login/generic_oauth", authorization_flow=authorization_flow, ) @@ -185,7 +185,7 @@ class TestProviderOAuth2OAuth(SeleniumTestCase): client_type=ClientTypes.CONFIDENTIAL, client_id=self.client_id, client_secret=self.client_secret, - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), redirect_uris="http://localhost:3000/login/generic_oauth", authorization_flow=authorization_flow, ) @@ -251,7 +251,7 @@ class TestProviderOAuth2OAuth(SeleniumTestCase): client_type=ClientTypes.CONFIDENTIAL, client_id=self.client_id, client_secret=self.client_secret, - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), redirect_uris="http://localhost:3000/login/generic_oauth", ) provider.property_mappings.set( @@ -324,7 +324,7 @@ class TestProviderOAuth2OAuth(SeleniumTestCase): client_type=ClientTypes.CONFIDENTIAL, client_id=self.client_id, client_secret=self.client_secret, - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), redirect_uris="http://localhost:3000/login/generic_oauth", ) provider.property_mappings.set( diff --git a/tests/e2e/test_provider_oauth2_oidc.py b/tests/e2e/test_provider_oauth2_oidc.py index 71b1c5da3..d29aed6ac 100644 --- a/tests/e2e/test_provider_oauth2_oidc.py +++ b/tests/e2e/test_provider_oauth2_oidc.py @@ -12,7 +12,7 @@ from selenium.webdriver.support import expected_conditions as ec from structlog.stdlib import get_logger from authentik.core.models import Application -from authentik.crypto.models import CertificateKeyPair +from authentik.core.tests.utils import create_test_cert from authentik.flows.models import Flow from authentik.lib.generators import generate_id, generate_key from authentik.policies.expression.models import ExpressionPolicy @@ -84,7 +84,7 @@ class TestProviderOAuth2OIDC(SeleniumTestCase): client_type=ClientTypes.CONFIDENTIAL, client_id=self.client_id, client_secret=self.client_secret, - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), redirect_uris="http://localhost:9009/", authorization_flow=authorization_flow, ) @@ -127,7 +127,7 @@ class TestProviderOAuth2OIDC(SeleniumTestCase): client_type=ClientTypes.CONFIDENTIAL, client_id=self.client_id, client_secret=self.client_secret, - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), redirect_uris="http://localhost:9009/auth/callback", authorization_flow=authorization_flow, ) @@ -178,7 +178,7 @@ class TestProviderOAuth2OIDC(SeleniumTestCase): client_type=ClientTypes.CONFIDENTIAL, client_id=self.client_id, client_secret=self.client_secret, - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), redirect_uris="http://localhost:9009/auth/callback", ) provider.property_mappings.set( @@ -242,7 +242,7 @@ class TestProviderOAuth2OIDC(SeleniumTestCase): client_type=ClientTypes.CONFIDENTIAL, client_id=self.client_id, client_secret=self.client_secret, - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), redirect_uris="http://localhost:9009/auth/callback", ) provider.property_mappings.set( diff --git a/tests/e2e/test_provider_oauth2_oidc_implicit.py b/tests/e2e/test_provider_oauth2_oidc_implicit.py index 739623bdc..b31d60b4d 100644 --- a/tests/e2e/test_provider_oauth2_oidc_implicit.py +++ b/tests/e2e/test_provider_oauth2_oidc_implicit.py @@ -12,7 +12,7 @@ from selenium.webdriver.support import expected_conditions as ec from structlog.stdlib import get_logger from authentik.core.models import Application -from authentik.crypto.models import CertificateKeyPair +from authentik.core.tests.utils import create_test_cert from authentik.flows.models import Flow from authentik.lib.generators import generate_id, generate_key from authentik.policies.expression.models import ExpressionPolicy @@ -84,7 +84,7 @@ class TestProviderOAuth2OIDCImplicit(SeleniumTestCase): client_type=ClientTypes.CONFIDENTIAL, client_id=self.client_id, client_secret=self.client_secret, - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), redirect_uris="http://localhost:9009/", authorization_flow=authorization_flow, ) @@ -127,7 +127,7 @@ class TestProviderOAuth2OIDCImplicit(SeleniumTestCase): client_type=ClientTypes.CONFIDENTIAL, client_id=self.client_id, client_secret=self.client_secret, - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), redirect_uris="http://localhost:9009/implicit/", authorization_flow=authorization_flow, ) @@ -175,7 +175,7 @@ class TestProviderOAuth2OIDCImplicit(SeleniumTestCase): client_type=ClientTypes.CONFIDENTIAL, client_id=self.client_id, client_secret=self.client_secret, - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), redirect_uris="http://localhost:9009/implicit/", ) provider.property_mappings.set( @@ -236,7 +236,7 @@ class TestProviderOAuth2OIDCImplicit(SeleniumTestCase): client_type=ClientTypes.CONFIDENTIAL, client_id=self.client_id, client_secret=self.client_secret, - rsa_key=CertificateKeyPair.objects.first(), + rsa_key=create_test_cert(), redirect_uris="http://localhost:9009/implicit/", ) provider.property_mappings.set( diff --git a/tests/e2e/test_provider_proxy.py b/tests/e2e/test_provider_proxy.py index 5cc4b8af8..75c37c78f 100644 --- a/tests/e2e/test_provider_proxy.py +++ b/tests/e2e/test_provider_proxy.py @@ -45,7 +45,6 @@ class TestProviderProxy(SeleniumTestCase): image=self.get_container_image("goauthentik.io/dev-proxy"), detach=True, network_mode="host", - auto_remove=True, environment={ "AUTHENTIK_HOST": self.live_server_url, "AUTHENTIK_TOKEN": outpost.token.key, diff --git a/tests/e2e/test_provider_saml.py b/tests/e2e/test_provider_saml.py index 0b056a172..fa37d045f 100644 --- a/tests/e2e/test_provider_saml.py +++ b/tests/e2e/test_provider_saml.py @@ -12,7 +12,7 @@ from selenium.webdriver.support import expected_conditions as ec from structlog.stdlib import get_logger from authentik.core.models import Application -from authentik.crypto.models import CertificateKeyPair +from authentik.core.tests.utils import create_test_cert from authentik.flows.models import Flow from authentik.policies.expression.models import ExpressionPolicy from authentik.policies.models import PolicyBinding @@ -81,7 +81,7 @@ class TestProviderSAML(SeleniumTestCase): issuer="authentik-e2e", sp_binding=SAMLBindings.POST, authorization_flow=authorization_flow, - signing_kp=CertificateKeyPair.objects.first(), + signing_kp=create_test_cert(), ) provider.property_mappings.set(SAMLPropertyMapping.objects.all()) provider.save() @@ -144,7 +144,7 @@ class TestProviderSAML(SeleniumTestCase): issuer="authentik-e2e", sp_binding=SAMLBindings.POST, authorization_flow=authorization_flow, - signing_kp=CertificateKeyPair.objects.first(), + signing_kp=create_test_cert(), ) provider.property_mappings.set(SAMLPropertyMapping.objects.all()) provider.save() @@ -222,7 +222,7 @@ class TestProviderSAML(SeleniumTestCase): issuer="authentik-e2e", sp_binding=SAMLBindings.POST, authorization_flow=authorization_flow, - signing_kp=CertificateKeyPair.objects.first(), + signing_kp=create_test_cert(), ) provider.property_mappings.set(SAMLPropertyMapping.objects.all()) provider.save() @@ -294,7 +294,7 @@ class TestProviderSAML(SeleniumTestCase): issuer="authentik-e2e", sp_binding=SAMLBindings.POST, authorization_flow=authorization_flow, - signing_kp=CertificateKeyPair.objects.first(), + signing_kp=create_test_cert(), ) provider.property_mappings.set(SAMLPropertyMapping.objects.all()) provider.save() diff --git a/tests/e2e/utils.py b/tests/e2e/utils.py index 05dc66ac2..441ece25f 100644 --- a/tests/e2e/utils.py +++ b/tests/e2e/utils.py @@ -6,8 +6,8 @@ from os import environ, makedirs from time import sleep, time from typing import Any, Callable, Optional +from channels.testing import ChannelsLiveServerTestCase from django.apps import apps -from django.contrib.staticfiles.testing import StaticLiveServerTestCase from django.db import connection from django.db.migrations.loader import MigrationLoader from django.db.migrations.operations.special import RunPython @@ -48,7 +48,7 @@ def get_docker_tag() -> str: return f"gh-{branch_name}" -class SeleniumTestCase(StaticLiveServerTestCase): +class SeleniumTestCase(ChannelsLiveServerTestCase): """StaticLiveServerTestCase which automatically creates a Webdriver instance""" container: Optional[Container] = None diff --git a/tests/integration/test_outpost_kubernetes.py b/tests/integration/test_outpost_kubernetes.py index 6ef8ea2c8..b6d7795f2 100644 --- a/tests/integration/test_outpost_kubernetes.py +++ b/tests/integration/test_outpost_kubernetes.py @@ -1,7 +1,7 @@ """outpost tests""" from django.test import TestCase -from authentik.flows.models import Flow +from authentik.core.tests.utils import create_test_flow from authentik.lib.config import CONFIG from authentik.outposts.controllers.k8s.deployment import DeploymentReconciler from authentik.outposts.controllers.k8s.triggers import NeedsUpdate @@ -22,7 +22,7 @@ class OutpostKubernetesTests(TestCase): name="test", internal_host="http://localhost", external_host="http://localhost", - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), ) self.service_connection = KubernetesServiceConnection.objects.first() self.outpost: Outpost = Outpost.objects.create( diff --git a/tests/integration/test_proxy_kubernetes.py b/tests/integration/test_proxy_kubernetes.py index ba498fdad..390eba149 100644 --- a/tests/integration/test_proxy_kubernetes.py +++ b/tests/integration/test_proxy_kubernetes.py @@ -5,7 +5,7 @@ import yaml from django.test import TestCase from structlog.stdlib import get_logger -from authentik.flows.models import Flow +from authentik.core.tests.utils import create_test_flow from authentik.outposts.controllers.kubernetes import KubernetesController from authentik.outposts.models import KubernetesServiceConnection, Outpost, OutpostType from authentik.outposts.tasks import outpost_local_connection @@ -38,7 +38,7 @@ class TestProxyKubernetes(TestCase): name="test", internal_host="http://localhost", external_host="http://localhost", - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), ) service_connection = KubernetesServiceConnection.objects.first() outpost: Outpost = Outpost.objects.create( @@ -59,14 +59,14 @@ class TestProxyKubernetes(TestCase): name="test", internal_host="http://localhost", external_host="https://localhost", - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), ) provider2: ProxyProvider = ProxyProvider.objects.create( name="test2", internal_host="http://otherhost", external_host="https://otherhost", mode=ProxyMode.FORWARD_SINGLE, - authorization_flow=Flow.objects.first(), + authorization_flow=create_test_flow(), ) service_connection = KubernetesServiceConnection.objects.first()