flows: add test helpers to simplify and improve checking of stages, remove force_str
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
50e3d317b2
commit
90c31c2214
|
@ -1,6 +1,5 @@
|
|||
"""Test Applications API"""
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import Application
|
||||
|
@ -32,7 +31,7 @@ class TestApplicationsAPI(APITestCase):
|
|||
)
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(force_str(response.content), {"messages": [], "passing": True})
|
||||
self.assertJSONEqual(response.content.decode(), {"messages": [], "passing": True})
|
||||
response = self.client.get(
|
||||
reverse(
|
||||
"authentik_api:application-check-access",
|
||||
|
@ -40,14 +39,14 @@ class TestApplicationsAPI(APITestCase):
|
|||
)
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(force_str(response.content), {"messages": ["dummy"], "passing": False})
|
||||
self.assertJSONEqual(response.content.decode(), {"messages": ["dummy"], "passing": False})
|
||||
|
||||
def test_list(self):
|
||||
"""Test list operation without superuser_full_list"""
|
||||
self.client.force_login(self.user)
|
||||
response = self.client.get(reverse("authentik_api:application-list"))
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
response.content.decode(),
|
||||
{
|
||||
"pagination": {
|
||||
"next": 0,
|
||||
|
@ -83,7 +82,7 @@ class TestApplicationsAPI(APITestCase):
|
|||
reverse("authentik_api:application-list") + "?superuser_full_list=true"
|
||||
)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
response.content.decode(),
|
||||
{
|
||||
"pagination": {
|
||||
"next": 0,
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
from json import loads
|
||||
|
||||
from django.urls.base import reverse
|
||||
from django.utils.encoding import force_str
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import User
|
||||
|
@ -28,5 +27,5 @@ class TestAuthenticatedSessionsAPI(APITestCase):
|
|||
self.client.force_login(self.other_user)
|
||||
response = self.client.get(reverse("authentik_api:authenticatedsession-list"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
body = loads(force_str(response.content))
|
||||
body = loads(response.content.decode())
|
||||
self.assertEqual(body["pagination"]["count"], 1)
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
"""Test helpers"""
|
||||
from json import loads
|
||||
from typing import Any, Optional
|
||||
|
||||
from django.http.response import HttpResponse
|
||||
from django.urls.base import reverse
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.flows.models import Flow
|
||||
|
||||
|
||||
class FlowTestCase(APITestCase):
|
||||
"""Helpers for testing flows and stages."""
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
def assertStageResponse(
|
||||
self,
|
||||
response: HttpResponse,
|
||||
flow: Optional[Flow] = None,
|
||||
user: Optional[User] = None,
|
||||
**kwargs,
|
||||
) -> dict[str, Any]:
|
||||
"""Assert various attributes of a stage response"""
|
||||
raw_response = loads(response.content.decode())
|
||||
self.assertIsNotNone(raw_response["component"])
|
||||
self.assertIsNotNone(raw_response["type"])
|
||||
if flow:
|
||||
self.assertIn("flow_info", raw_response)
|
||||
self.assertEqual(raw_response["flow_info"]["background"], flow.background_url)
|
||||
self.assertEqual(
|
||||
raw_response["flow_info"]["cancel_url"], reverse("authentik_flows:cancel")
|
||||
)
|
||||
# We don't check the flow title since it will most likely go
|
||||
# through ChallengeStageView.format_title() so might not match 1:1
|
||||
# self.assertEqual(raw_response["flow_info"]["title"], flow.title)
|
||||
self.assertIsNotNone(raw_response["flow_info"]["title"])
|
||||
if user:
|
||||
self.assertEqual(raw_response["pending_user"], user.username)
|
||||
self.assertEqual(raw_response["pending_user_avatar"], user.avatar)
|
||||
for key, expected in kwargs.items():
|
||||
self.assertEqual(raw_response[key], expected)
|
||||
return raw_response
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
def assertStageRedirects(self, response: HttpResponse, to: str) -> dict[str, Any]:
|
||||
"""Wrapper around assertStageResponse that checks for a redirect"""
|
||||
return self.assertStageResponse(
|
||||
response, component="xak-flow-redirect", to=to, type=ChallengeTypes.REDIRECT.value
|
||||
)
|
|
@ -4,16 +4,14 @@ from unittest.mock import MagicMock, PropertyMock, patch
|
|||
from django.http import HttpRequest, HttpResponse
|
||||
from django.test.client import RequestFactory
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.flows.exceptions import FlowNonApplicableException
|
||||
from authentik.flows.markers import ReevaluateMarker, StageMarker
|
||||
from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding, InvalidResponseAction
|
||||
from authentik.flows.planner import FlowPlan, FlowPlanner
|
||||
from authentik.flows.stage import PLAN_CONTEXT_PENDING_USER_IDENTIFIER, StageView
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.flows.views.executor import NEXT_ARG_NAME, SESSION_KEY_PLAN, FlowExecutorView
|
||||
from authentik.lib.config import CONFIG
|
||||
from authentik.policies.dummy.models import DummyPolicy
|
||||
|
@ -37,7 +35,7 @@ def to_stage_response(request: HttpRequest, source: HttpResponse):
|
|||
TO_STAGE_RESPONSE_MOCK = MagicMock(side_effect=to_stage_response)
|
||||
|
||||
|
||||
class TestFlowExecutor(APITestCase):
|
||||
class TestFlowExecutor(FlowTestCase):
|
||||
"""Test executor"""
|
||||
|
||||
def setUp(self):
|
||||
|
@ -90,18 +88,11 @@ class TestFlowExecutor(APITestCase):
|
|||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "ak-stage-access-denied",
|
||||
"error_message": FlowNonApplicableException.__doc__,
|
||||
"flow_info": {
|
||||
"background": flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
},
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
flow=flow,
|
||||
error_message=FlowNonApplicableException.__doc__,
|
||||
component="ak-stage-access-denied",
|
||||
)
|
||||
|
||||
@patch(
|
||||
|
@ -283,14 +274,7 @@ class TestFlowExecutor(APITestCase):
|
|||
# We do this request without the patch, so the policy results in false
|
||||
response = self.client.post(exec_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
||||
def test_reevaluate_keep(self):
|
||||
"""Test planner with re-evaluate (everything is kept)"""
|
||||
|
@ -360,14 +344,7 @@ class TestFlowExecutor(APITestCase):
|
|||
# We do this request without the patch, so the policy results in false
|
||||
response = self.client.post(exec_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
||||
def test_reevaluate_remove_consecutive(self):
|
||||
"""Test planner with re-evaluate (consecutive stages are removed)"""
|
||||
|
@ -407,18 +384,7 @@ class TestFlowExecutor(APITestCase):
|
|||
# First request, run the planner
|
||||
response = self.client.get(exec_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"component": "ak-stage-dummy",
|
||||
"flow_info": {
|
||||
"background": flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
},
|
||||
)
|
||||
self.assertStageResponse(response, flow, component="ak-stage-dummy")
|
||||
|
||||
plan: FlowPlan = self.client.session[SESSION_KEY_PLAN]
|
||||
|
||||
|
@ -441,31 +407,13 @@ class TestFlowExecutor(APITestCase):
|
|||
# but it won't save it, hence we can't check the plan
|
||||
response = self.client.get(exec_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"component": "ak-stage-dummy",
|
||||
"flow_info": {
|
||||
"background": flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
},
|
||||
)
|
||||
self.assertStageResponse(response, flow, component="ak-stage-dummy")
|
||||
|
||||
# fourth request, this confirms the last stage (dummy4)
|
||||
# We do this request without the patch, so the policy results in false
|
||||
response = self.client.post(exec_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
||||
def test_stageview_user_identifier(self):
|
||||
"""Test PLAN_CONTEXT_PENDING_USER_IDENTIFIER"""
|
||||
|
@ -532,35 +480,16 @@ class TestFlowExecutor(APITestCase):
|
|||
# First request, run the planner
|
||||
response = self.client.get(exec_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"component": "ak-stage-identification",
|
||||
"flow_info": {
|
||||
"background": flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
"password_fields": False,
|
||||
"primary_action": "Log in",
|
||||
"sources": [],
|
||||
"show_source_labels": False,
|
||||
"user_fields": [UserFields.E_MAIL],
|
||||
},
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
flow,
|
||||
component="ak-stage-identification",
|
||||
password_fields=False,
|
||||
primary_action="Log in",
|
||||
sources=[],
|
||||
show_source_labels=False,
|
||||
user_fields=[UserFields.E_MAIL],
|
||||
)
|
||||
response = self.client.post(exec_url, {"uid_field": "invalid-string"}, follow=True)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "ak-stage-access-denied",
|
||||
"error_message": None,
|
||||
"flow_info": {
|
||||
"background": flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
},
|
||||
)
|
||||
self.assertStageResponse(response, flow, component="ak-stage-access-denied")
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
"""Password flow tests"""
|
||||
from django.urls.base import reverse
|
||||
from django.utils.encoding import force_str
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.policies.password.models import PasswordPolicy
|
||||
from authentik.stages.prompt.models import FieldTypes, Prompt, PromptStage
|
||||
|
||||
|
||||
class TestPasswordPolicyFlow(APITestCase):
|
||||
class TestPasswordPolicyFlow(FlowTestCase):
|
||||
"""Test Password Policy"""
|
||||
|
||||
def setUp(self) -> None:
|
||||
|
@ -53,29 +51,22 @@ class TestPasswordPolicyFlow(APITestCase):
|
|||
{"password": "akadmin"},
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "ak-stage-prompt",
|
||||
"fields": [
|
||||
{
|
||||
"field_key": "password",
|
||||
"label": "PASSWORD_LABEL",
|
||||
"order": 0,
|
||||
"placeholder": "PASSWORD_PLACEHOLDER",
|
||||
"required": True,
|
||||
"type": "password",
|
||||
"sub_text": "",
|
||||
}
|
||||
],
|
||||
"flow_info": {
|
||||
"background": self.flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
"response_errors": {
|
||||
"non_field_errors": [{"code": "invalid", "string": self.policy.error_message}]
|
||||
},
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
self.flow,
|
||||
component="ak-stage-prompt",
|
||||
fields=[
|
||||
{
|
||||
"field_key": "password",
|
||||
"label": "PASSWORD_LABEL",
|
||||
"order": 0,
|
||||
"placeholder": "PASSWORD_PLACEHOLDER",
|
||||
"required": True,
|
||||
"type": "password",
|
||||
"sub_text": "",
|
||||
}
|
||||
],
|
||||
response_errors={
|
||||
"non_field_errors": [{"code": "invalid", "string": self.policy.error_message}]
|
||||
},
|
||||
)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
"""Test authorize view"""
|
||||
from django.test import RequestFactory
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
|
||||
from authentik.core.models import Application
|
||||
from authentik.core.tests.utils import create_test_admin_user, create_test_cert, create_test_flow
|
||||
|
@ -201,7 +200,7 @@ class TestAuthorize(OAuthTestCase):
|
|||
)
|
||||
code: AuthorizationCode = AuthorizationCode.objects.filter(user=user).first()
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
response.content.decode(),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
|
@ -240,7 +239,7 @@ class TestAuthorize(OAuthTestCase):
|
|||
)
|
||||
token: RefreshToken = RefreshToken.objects.filter(user=user).first()
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
response.content.decode(),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
|
|
|
@ -3,7 +3,6 @@ import json
|
|||
|
||||
from django.test import RequestFactory
|
||||
from django.urls.base import reverse
|
||||
from django.utils.encoding import force_str
|
||||
|
||||
from authentik.core.models import Application
|
||||
from authentik.core.tests.utils import create_test_cert, create_test_flow
|
||||
|
@ -31,7 +30,7 @@ class TestJWKS(OAuthTestCase):
|
|||
response = self.client.get(
|
||||
reverse("authentik_providers_oauth2:jwks", kwargs={"application_slug": app.slug})
|
||||
)
|
||||
body = json.loads(force_str(response.content))
|
||||
body = json.loads(response.content.decode())
|
||||
self.assertEqual(len(body["keys"]), 1)
|
||||
|
||||
def test_hs256(self):
|
||||
|
@ -46,4 +45,4 @@ class TestJWKS(OAuthTestCase):
|
|||
response = self.client.get(
|
||||
reverse("authentik_providers_oauth2:jwks", kwargs={"application_slug": app.slug})
|
||||
)
|
||||
self.assertJSONEqual(force_str(response.content), {})
|
||||
self.assertJSONEqual(response.content.decode(), {})
|
||||
|
|
|
@ -3,7 +3,6 @@ from base64 import b64encode
|
|||
|
||||
from django.test import RequestFactory
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
|
||||
from authentik.core.models import Application
|
||||
from authentik.core.tests.utils import create_test_admin_user, create_test_cert, create_test_flow
|
||||
|
@ -135,7 +134,7 @@ class TestToken(OAuthTestCase):
|
|||
)
|
||||
new_token: RefreshToken = RefreshToken.objects.filter(user=user).first()
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
response.content.decode(),
|
||||
{
|
||||
"access_token": new_token.access_token,
|
||||
"refresh_token": new_token.refresh_token,
|
||||
|
@ -184,7 +183,7 @@ class TestToken(OAuthTestCase):
|
|||
self.assertEqual(response["Access-Control-Allow-Credentials"], "true")
|
||||
self.assertEqual(response["Access-Control-Allow-Origin"], "http://local.invalid")
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
response.content.decode(),
|
||||
{
|
||||
"access_token": new_token.access_token,
|
||||
"refresh_token": new_token.refresh_token,
|
||||
|
@ -230,7 +229,7 @@ class TestToken(OAuthTestCase):
|
|||
self.assertNotIn("Access-Control-Allow-Credentials", response)
|
||||
self.assertNotIn("Access-Control-Allow-Origin", response)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
response.content.decode(),
|
||||
{
|
||||
"access_token": new_token.access_token,
|
||||
"refresh_token": new_token.refresh_token,
|
||||
|
|
|
@ -3,7 +3,6 @@ import json
|
|||
from dataclasses import asdict
|
||||
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
|
||||
from authentik.core.models import Application
|
||||
from authentik.core.tests.utils import create_test_admin_user, create_test_cert, create_test_flow
|
||||
|
@ -54,7 +53,7 @@ class TestUserinfo(OAuthTestCase):
|
|||
HTTP_AUTHORIZATION=f"Bearer {self.token.access_token}",
|
||||
)
|
||||
self.assertJSONEqual(
|
||||
force_str(res.content),
|
||||
res.content.decode(),
|
||||
{
|
||||
"name": self.user.name,
|
||||
"given_name": self.user.name,
|
||||
|
@ -77,7 +76,7 @@ class TestUserinfo(OAuthTestCase):
|
|||
HTTP_AUTHORIZATION=f"Bearer {self.token.access_token}",
|
||||
)
|
||||
self.assertJSONEqual(
|
||||
force_str(res.content),
|
||||
res.content.decode(),
|
||||
{
|
||||
"name": self.user.name,
|
||||
"given_name": self.user.name,
|
||||
|
|
|
@ -3,15 +3,13 @@ from unittest.mock import MagicMock, patch
|
|||
|
||||
from django.test.client import RequestFactory
|
||||
from django.urls.base import reverse
|
||||
from django.utils.encoding import force_str
|
||||
from django_otp.plugins.otp_totp.models import TOTPDevice
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.test import APITestCase
|
||||
from webauthn.helpers import bytes_to_base64url
|
||||
|
||||
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.flows.tests import FlowTestCase
|
||||
from authentik.lib.generators import generate_id, generate_key
|
||||
from authentik.lib.tests.utils import get_request
|
||||
from authentik.stages.authenticator_duo.models import AuthenticatorDuoStage, DuoDevice
|
||||
|
@ -27,7 +25,7 @@ from authentik.stages.authenticator_webauthn.models import WebAuthnDevice
|
|||
from authentik.stages.identification.models import IdentificationStage, UserFields
|
||||
|
||||
|
||||
class AuthenticatorValidateStageTests(APITestCase):
|
||||
class AuthenticatorValidateStageTests(FlowTestCase):
|
||||
"""Test validator stage"""
|
||||
|
||||
def setUp(self) -> None:
|
||||
|
@ -61,22 +59,15 @@ class AuthenticatorValidateStageTests(APITestCase):
|
|||
follow=True,
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"component": "ak-stage-identification",
|
||||
"password_fields": False,
|
||||
"primary_action": "Log in",
|
||||
"flow_info": {
|
||||
"background": flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": flow.title,
|
||||
},
|
||||
"user_fields": ["username"],
|
||||
"sources": [],
|
||||
"show_source_labels": False,
|
||||
},
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
flow,
|
||||
component="ak-stage-identification",
|
||||
password_fields=False,
|
||||
primary_action="Log in",
|
||||
user_fields=["username"],
|
||||
sources=[],
|
||||
show_source_labels=False,
|
||||
)
|
||||
|
||||
def test_stage_validation(self):
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
"""captcha tests"""
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.flows.markers import StageMarker
|
||||
from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
|
||||
from authentik.flows.planner import FlowPlan
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.flows.views.executor import SESSION_KEY_PLAN
|
||||
from authentik.stages.captcha.models import CaptchaStage
|
||||
|
||||
|
@ -16,7 +14,7 @@ RECAPTCHA_PUBLIC_KEY = "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"
|
|||
RECAPTCHA_PRIVATE_KEY = "6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe"
|
||||
|
||||
|
||||
class TestCaptchaStage(APITestCase):
|
||||
class TestCaptchaStage(FlowTestCase):
|
||||
"""Captcha tests"""
|
||||
|
||||
def setUp(self):
|
||||
|
@ -46,11 +44,4 @@ class TestCaptchaStage(APITestCase):
|
|||
{"token": "PASSED"},
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
|
|
@ -2,20 +2,18 @@
|
|||
from time import sleep
|
||||
|
||||
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.tasks import clean_expired_models
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.flows.markers import StageMarker
|
||||
from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
|
||||
from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, FlowPlan
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.flows.views.executor import SESSION_KEY_PLAN
|
||||
from authentik.stages.consent.models import ConsentMode, ConsentStage, UserConsent
|
||||
|
||||
|
||||
class TestConsentStage(APITestCase):
|
||||
class TestConsentStage(FlowTestCase):
|
||||
"""Consent tests"""
|
||||
|
||||
def setUp(self):
|
||||
|
@ -46,15 +44,7 @@ class TestConsentStage(APITestCase):
|
|||
)
|
||||
# pylint: disable=no-member
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
# pylint: disable=no-member
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
self.assertFalse(UserConsent.objects.filter(user=self.user).exists())
|
||||
|
||||
def test_permanent(self):
|
||||
|
@ -82,14 +72,7 @@ class TestConsentStage(APITestCase):
|
|||
{},
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
self.assertTrue(
|
||||
UserConsent.objects.filter(user=self.user, application=self.application).exists()
|
||||
)
|
||||
|
@ -121,14 +104,7 @@ class TestConsentStage(APITestCase):
|
|||
{},
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
self.assertTrue(
|
||||
UserConsent.objects.filter(user=self.user, application=self.application).exists()
|
||||
)
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
"""deny tests"""
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.flows.markers import StageMarker
|
||||
from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
|
||||
from authentik.flows.planner import FlowPlan
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.flows.views.executor import SESSION_KEY_PLAN
|
||||
from authentik.stages.deny.models import DenyStage
|
||||
|
||||
|
||||
class TestUserDenyStage(APITestCase):
|
||||
class TestUserDenyStage(FlowTestCase):
|
||||
"""Deny tests"""
|
||||
|
||||
def setUp(self):
|
||||
|
@ -39,19 +37,7 @@ class TestUserDenyStage(APITestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "ak-stage-access-denied",
|
||||
"error_message": None,
|
||||
"flow_info": {
|
||||
"background": self.flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
},
|
||||
)
|
||||
self.assertStageResponse(response, self.flow, component="ak-stage-access-denied")
|
||||
|
||||
def test_valid_post(self):
|
||||
"""Test with a valid pending user and backend"""
|
||||
|
@ -65,16 +51,4 @@ class TestUserDenyStage(APITestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "ak-stage-access-denied",
|
||||
"error_message": None,
|
||||
"flow_info": {
|
||||
"background": self.flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
},
|
||||
)
|
||||
self.assertStageResponse(response, self.flow, component="ak-stage-access-denied")
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
"""dummy tests"""
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.stages.dummy.models import DummyStage
|
||||
|
||||
|
||||
class TestDummyStage(APITestCase):
|
||||
class TestDummyStage(FlowTestCase):
|
||||
"""Dummy tests"""
|
||||
|
||||
def setUp(self):
|
||||
|
@ -42,11 +40,4 @@ class TestDummyStage(APITestCase):
|
|||
url = reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
|
||||
response = self.client.post(url, {})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
|
|
@ -5,21 +5,19 @@ from django.core import mail
|
|||
from django.core.mail.backends.locmem import EmailBackend
|
||||
from django.core.mail.backends.smtp import EmailBackend as SMTPEmailBackend
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
from django.utils.http import urlencode
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import Token, User
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.flows.markers import StageMarker
|
||||
from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
|
||||
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.flows.views.executor import SESSION_KEY_PLAN
|
||||
from authentik.stages.email.models import EmailStage
|
||||
from authentik.stages.email.stage import QS_KEY_TOKEN
|
||||
|
||||
|
||||
class TestEmailStage(APITestCase):
|
||||
class TestEmailStage(FlowTestCase):
|
||||
"""Email tests"""
|
||||
|
||||
def setUp(self):
|
||||
|
@ -123,14 +121,7 @@ class TestEmailStage(APITestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
||||
session = self.client.session
|
||||
plan: FlowPlan = session[SESSION_KEY_PLAN]
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
"""identification tests"""
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.lib.generators import generate_key
|
||||
from authentik.sources.oauth.models import OAuthSource
|
||||
from authentik.stages.identification.models import IdentificationStage, UserFields
|
||||
|
@ -13,7 +12,7 @@ from authentik.stages.password import BACKEND_INBUILT
|
|||
from authentik.stages.password.models import PasswordStage
|
||||
|
||||
|
||||
class TestIdentificationStage(APITestCase):
|
||||
class TestIdentificationStage(FlowTestCase):
|
||||
"""Identification tests"""
|
||||
|
||||
def setUp(self):
|
||||
|
@ -56,14 +55,7 @@ class TestIdentificationStage(APITestCase):
|
|||
url = reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
|
||||
response = self.client.post(url, form_data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
||||
def test_valid_with_password(self):
|
||||
"""Test with valid email and password in single step"""
|
||||
|
@ -74,14 +66,7 @@ class TestIdentificationStage(APITestCase):
|
|||
url = reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
|
||||
response = self.client.post(url, form_data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
||||
def test_invalid_with_password(self):
|
||||
"""Test with valid email and invalid password in single step"""
|
||||
|
@ -95,37 +80,28 @@ class TestIdentificationStage(APITestCase):
|
|||
url = reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
|
||||
response = self.client.post(url, form_data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"component": "ak-stage-identification",
|
||||
"password_fields": True,
|
||||
"primary_action": "Log in",
|
||||
"response_errors": {
|
||||
"non_field_errors": [
|
||||
{"code": "invalid", "string": "Failed to " "authenticate."}
|
||||
]
|
||||
},
|
||||
"flow_info": {
|
||||
"background": self.flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"challenge": {
|
||||
"component": "xak-flow-redirect",
|
||||
"to": "/source/oauth/login/test/",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"name": "test",
|
||||
}
|
||||
],
|
||||
"show_source_labels": False,
|
||||
"user_fields": ["email"],
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
self.flow,
|
||||
component="ak-stage-identification",
|
||||
password_fields=True,
|
||||
primary_action="Log in",
|
||||
response_errors={
|
||||
"non_field_errors": [{"code": "invalid", "string": "Failed to " "authenticate."}]
|
||||
},
|
||||
sources=[
|
||||
{
|
||||
"challenge": {
|
||||
"component": "xak-flow-redirect",
|
||||
"to": "/source/oauth/login/test/",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"name": "test",
|
||||
}
|
||||
],
|
||||
show_source_labels=False,
|
||||
user_fields=["email"],
|
||||
)
|
||||
|
||||
def test_invalid_with_username(self):
|
||||
|
@ -147,37 +123,28 @@ class TestIdentificationStage(APITestCase):
|
|||
form_data,
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"component": "ak-stage-identification",
|
||||
"password_fields": False,
|
||||
"primary_action": "Log in",
|
||||
"response_errors": {
|
||||
"non_field_errors": [
|
||||
{"code": "invalid", "string": "Failed to " "authenticate."}
|
||||
]
|
||||
},
|
||||
"show_source_labels": False,
|
||||
"flow_info": {
|
||||
"background": self.flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"challenge": {
|
||||
"component": "xak-flow-redirect",
|
||||
"to": "/source/oauth/login/test/",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"name": "test",
|
||||
}
|
||||
],
|
||||
"user_fields": [],
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
self.flow,
|
||||
component="ak-stage-identification",
|
||||
password_fields=False,
|
||||
primary_action="Log in",
|
||||
response_errors={
|
||||
"non_field_errors": [{"code": "invalid", "string": "Failed to " "authenticate."}]
|
||||
},
|
||||
show_source_labels=False,
|
||||
sources=[
|
||||
{
|
||||
"challenge": {
|
||||
"component": "xak-flow-redirect",
|
||||
"to": "/source/oauth/login/test/",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"name": "test",
|
||||
}
|
||||
],
|
||||
user_fields=[],
|
||||
)
|
||||
|
||||
def test_invalid_with_invalid_email(self):
|
||||
|
@ -209,36 +176,29 @@ class TestIdentificationStage(APITestCase):
|
|||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"component": "ak-stage-identification",
|
||||
"user_fields": ["email"],
|
||||
"password_fields": False,
|
||||
"enroll_url": reverse(
|
||||
"authentik_core:if-flow",
|
||||
kwargs={"flow_slug": "unique-enrollment-string"},
|
||||
),
|
||||
"show_source_labels": False,
|
||||
"primary_action": "Log in",
|
||||
"flow_info": {
|
||||
"background": flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": self.flow.title,
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"name": "test",
|
||||
"challenge": {
|
||||
"component": "xak-flow-redirect",
|
||||
"to": "/source/oauth/login/test/",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
self.flow,
|
||||
component="ak-stage-identification",
|
||||
user_fields=["email"],
|
||||
password_fields=False,
|
||||
enroll_url=reverse(
|
||||
"authentik_core:if-flow",
|
||||
kwargs={"flow_slug": "unique-enrollment-string"},
|
||||
),
|
||||
show_source_labels=False,
|
||||
primary_action="Log in",
|
||||
sources=[
|
||||
{
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"name": "test",
|
||||
"challenge": {
|
||||
"component": "xak-flow-redirect",
|
||||
"to": "/source/oauth/login/test/",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
def test_recovery_flow(self):
|
||||
|
@ -259,34 +219,27 @@ class TestIdentificationStage(APITestCase):
|
|||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"component": "ak-stage-identification",
|
||||
"user_fields": ["email"],
|
||||
"password_fields": False,
|
||||
"recovery_url": reverse(
|
||||
"authentik_core:if-flow",
|
||||
kwargs={"flow_slug": "unique-recovery-string"},
|
||||
),
|
||||
"show_source_labels": False,
|
||||
"primary_action": "Log in",
|
||||
"flow_info": {
|
||||
"background": flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": self.flow.title,
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"challenge": {
|
||||
"component": "xak-flow-redirect",
|
||||
"to": "/source/oauth/login/test/",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"name": "test",
|
||||
}
|
||||
],
|
||||
},
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
self.flow,
|
||||
component="ak-stage-identification",
|
||||
user_fields=["email"],
|
||||
password_fields=False,
|
||||
recovery_url=reverse(
|
||||
"authentik_core:if-flow",
|
||||
kwargs={"flow_slug": "unique-recovery-string"},
|
||||
),
|
||||
show_source_labels=False,
|
||||
primary_action="Log in",
|
||||
sources=[
|
||||
{
|
||||
"challenge": {
|
||||
"component": "xak-flow-redirect",
|
||||
"to": "/source/oauth/login/test/",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"name": "test",
|
||||
}
|
||||
],
|
||||
)
|
||||
|
|
|
@ -2,17 +2,16 @@
|
|||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
from django.utils.http import urlencode
|
||||
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
|
||||
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.flows.tests.test_executor import TO_STAGE_RESPONSE_MOCK
|
||||
from authentik.flows.views.executor import SESSION_KEY_PLAN
|
||||
from authentik.stages.invitation.models import Invitation, InvitationStage
|
||||
|
@ -25,7 +24,7 @@ from authentik.stages.password import BACKEND_INBUILT
|
|||
from authentik.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
|
||||
|
||||
|
||||
class TestUserLoginStage(APITestCase):
|
||||
class TestUserLoginStage(FlowTestCase):
|
||||
"""Login tests"""
|
||||
|
||||
def setUp(self):
|
||||
|
@ -57,18 +56,10 @@ class TestUserLoginStage(APITestCase):
|
|||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "ak-stage-access-denied",
|
||||
"error_message": None,
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"flow_info": {
|
||||
"background": self.flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
},
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
flow=self.flow,
|
||||
component="ak-stage-access-denied",
|
||||
)
|
||||
|
||||
def test_without_invitation_continue(self):
|
||||
|
@ -87,14 +78,7 @@ class TestUserLoginStage(APITestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
||||
self.stage.continue_flow_without_invitation = False
|
||||
self.stage.save()
|
||||
|
@ -119,14 +103,7 @@ class TestUserLoginStage(APITestCase):
|
|||
self.assertEqual(plan.context[PLAN_CONTEXT_PROMPT], data)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
||||
def test_with_invitation_prompt_data(self):
|
||||
"""Test with invitation, check data in session"""
|
||||
|
@ -152,14 +129,7 @@ class TestUserLoginStage(APITestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
self.assertFalse(Invitation.objects.filter(pk=invite.pk))
|
||||
|
||||
|
||||
|
|
|
@ -3,14 +3,12 @@ from unittest.mock import MagicMock, patch
|
|||
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.flows.markers import StageMarker
|
||||
from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
|
||||
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.flows.tests.test_executor import TO_STAGE_RESPONSE_MOCK
|
||||
from authentik.flows.views.executor import SESSION_KEY_PLAN
|
||||
from authentik.lib.generators import generate_key
|
||||
|
@ -20,7 +18,7 @@ from authentik.stages.password.models import PasswordStage
|
|||
MOCK_BACKEND_AUTHENTICATE = MagicMock(side_effect=PermissionDenied("test"))
|
||||
|
||||
|
||||
class TestPasswordStage(APITestCase):
|
||||
class TestPasswordStage(FlowTestCase):
|
||||
"""Password tests"""
|
||||
|
||||
def setUp(self):
|
||||
|
@ -56,18 +54,11 @@ class TestPasswordStage(APITestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "ak-stage-access-denied",
|
||||
"error_message": None,
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"flow_info": {
|
||||
"background": self.flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
},
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
self.flow,
|
||||
component="ak-stage-access-denied",
|
||||
error_message="Unknown error",
|
||||
)
|
||||
|
||||
def test_recovery_flow_link(self):
|
||||
|
@ -83,7 +74,7 @@ class TestPasswordStage(APITestCase):
|
|||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertIn(flow.slug, force_str(response.content))
|
||||
self.assertIn(flow.slug, response.content.decode())
|
||||
|
||||
def test_valid_password(self):
|
||||
"""Test with a valid pending user and valid password"""
|
||||
|
@ -100,14 +91,7 @@ class TestPasswordStage(APITestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
||||
def test_invalid_password(self):
|
||||
"""Test with a valid pending user and invalid password"""
|
||||
|
@ -176,16 +160,9 @@ class TestPasswordStage(APITestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "ak-stage-access-denied",
|
||||
"error_message": None,
|
||||
"flow_info": {
|
||||
"background": self.flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
},
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
self.flow,
|
||||
component="ak-stage-access-denied",
|
||||
error_message="Unknown error",
|
||||
)
|
||||
|
|
|
@ -2,23 +2,21 @@
|
|||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
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
|
||||
from authentik.flows.planner import FlowPlan
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.flows.views.executor import SESSION_KEY_PLAN
|
||||
from authentik.policies.expression.models import ExpressionPolicy
|
||||
from authentik.stages.prompt.models import FieldTypes, Prompt, PromptStage
|
||||
from authentik.stages.prompt.stage import PLAN_CONTEXT_PROMPT, PromptChallengeResponse
|
||||
|
||||
|
||||
class TestPromptStage(APITestCase):
|
||||
class TestPromptStage(FlowTestCase):
|
||||
"""Prompt tests"""
|
||||
|
||||
def setUp(self):
|
||||
|
@ -123,9 +121,9 @@ class TestPromptStage(APITestCase):
|
|||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
for prompt in self.stage.fields.all():
|
||||
self.assertIn(prompt.field_key, force_str(response.content))
|
||||
self.assertIn(prompt.label, force_str(response.content))
|
||||
self.assertIn(prompt.placeholder, force_str(response.content))
|
||||
self.assertIn(prompt.field_key, response.content.decode())
|
||||
self.assertIn(prompt.label, response.content.decode())
|
||||
self.assertIn(prompt.placeholder, response.content.decode())
|
||||
|
||||
def test_valid_challenge_with_policy(self) -> PromptChallengeResponse:
|
||||
"""Test challenge_response validation"""
|
||||
|
@ -171,14 +169,7 @@ class TestPromptStage(APITestCase):
|
|||
challenge_response.validated_data,
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
||||
# Check that valid data has been saved
|
||||
session = self.client.session
|
||||
|
|
|
@ -2,20 +2,18 @@
|
|||
from unittest.mock import patch
|
||||
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.flows.markers import StageMarker
|
||||
from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
|
||||
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.flows.tests.test_executor import TO_STAGE_RESPONSE_MOCK
|
||||
from authentik.flows.views.executor import SESSION_KEY_PLAN
|
||||
from authentik.stages.user_delete.models import UserDeleteStage
|
||||
|
||||
|
||||
class TestUserDeleteStage(APITestCase):
|
||||
class TestUserDeleteStage(FlowTestCase):
|
||||
"""Delete tests"""
|
||||
|
||||
def setUp(self):
|
||||
|
@ -46,19 +44,7 @@ class TestUserDeleteStage(APITestCase):
|
|||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "ak-stage-access-denied",
|
||||
"error_message": None,
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"flow_info": {
|
||||
"background": self.flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
},
|
||||
)
|
||||
self.assertStageResponse(response, self.flow, component="ak-stage-access-denied")
|
||||
|
||||
def test_user_delete_get(self):
|
||||
"""Test Form render"""
|
||||
|
@ -72,14 +58,7 @@ class TestUserDeleteStage(APITestCase):
|
|||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
||||
self.assertFalse(User.objects.filter(username=self.username).exists())
|
||||
|
||||
|
@ -95,13 +74,6 @@ class TestUserDeleteStage(APITestCase):
|
|||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
||||
self.assertFalse(User.objects.filter(username=self.username).exists())
|
||||
|
|
|
@ -3,20 +3,18 @@ from time import sleep
|
|||
from unittest.mock import patch
|
||||
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.flows.markers import StageMarker
|
||||
from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
|
||||
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.flows.tests.test_executor import TO_STAGE_RESPONSE_MOCK
|
||||
from authentik.flows.views.executor import SESSION_KEY_PLAN
|
||||
from authentik.stages.user_login.models import UserLoginStage
|
||||
|
||||
|
||||
class TestUserLoginStage(APITestCase):
|
||||
class TestUserLoginStage(FlowTestCase):
|
||||
"""Login tests"""
|
||||
|
||||
def setUp(self):
|
||||
|
@ -44,14 +42,7 @@ class TestUserLoginStage(APITestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
||||
def test_valid_post(self):
|
||||
"""Test with a valid pending user and backend"""
|
||||
|
@ -66,14 +57,7 @@ class TestUserLoginStage(APITestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
||||
def test_expiry(self):
|
||||
"""Test with expiry"""
|
||||
|
@ -89,14 +73,7 @@ class TestUserLoginStage(APITestCase):
|
|||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
self.assertNotEqual(list(self.client.session.keys()), [])
|
||||
sleep(3)
|
||||
self.client.session.clear_expired()
|
||||
|
@ -118,18 +95,10 @@ class TestUserLoginStage(APITestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "ak-stage-access-denied",
|
||||
"error_message": None,
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"flow_info": {
|
||||
"background": self.flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
},
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
self.flow,
|
||||
component="ak-stage-access-denied",
|
||||
)
|
||||
|
||||
def test_inactive_account(self):
|
||||
|
@ -147,13 +116,6 @@ class TestUserLoginStage(APITestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
response = self.client.get(reverse("authentik_api:application-list"))
|
||||
self.assertEqual(response.status_code, 403)
|
||||
|
|
|
@ -1,20 +1,18 @@
|
|||
"""logout tests"""
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.flows.markers import StageMarker
|
||||
from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
|
||||
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.flows.views.executor import SESSION_KEY_PLAN
|
||||
from authentik.stages.password import BACKEND_INBUILT
|
||||
from authentik.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
|
||||
from authentik.stages.user_logout.models import UserLogoutStage
|
||||
|
||||
|
||||
class TestUserLogoutStage(APITestCase):
|
||||
class TestUserLogoutStage(FlowTestCase):
|
||||
"""Logout tests"""
|
||||
|
||||
def setUp(self):
|
||||
|
@ -44,15 +42,7 @@ class TestUserLogoutStage(APITestCase):
|
|||
|
||||
# pylint: disable=no-member
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
# pylint: disable=no-member
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
||||
def test_valid_post(self):
|
||||
"""Test with a valid pending user and backend"""
|
||||
|
@ -69,12 +59,4 @@ class TestUserLogoutStage(APITestCase):
|
|||
|
||||
# pylint: disable=no-member
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
# pylint: disable=no-member
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
|
|
@ -4,23 +4,21 @@ from random import SystemRandom
|
|||
from unittest.mock import patch
|
||||
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import force_str
|
||||
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
|
||||
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.flows.tests.test_executor import TO_STAGE_RESPONSE_MOCK
|
||||
from authentik.flows.views.executor import SESSION_KEY_PLAN
|
||||
from authentik.stages.prompt.stage import PLAN_CONTEXT_PROMPT
|
||||
from authentik.stages.user_write.models import UserWriteStage
|
||||
|
||||
|
||||
class TestUserWriteStage(APITestCase):
|
||||
class TestUserWriteStage(FlowTestCase):
|
||||
"""Write tests"""
|
||||
|
||||
def setUp(self):
|
||||
|
@ -60,14 +58,7 @@ class TestUserWriteStage(APITestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
user_qs = User.objects.filter(username=plan.context[PLAN_CONTEXT_PROMPT]["username"])
|
||||
self.assertTrue(user_qs.exists())
|
||||
self.assertTrue(user_qs.first().check_password(password))
|
||||
|
@ -98,14 +89,7 @@ class TestUserWriteStage(APITestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"to": reverse("authentik_core:root-redirect"),
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
user_qs = User.objects.filter(username=plan.context[PLAN_CONTEXT_PROMPT]["username"])
|
||||
self.assertTrue(user_qs.exists())
|
||||
self.assertTrue(user_qs.first().check_password(new_password))
|
||||
|
@ -128,18 +112,10 @@ class TestUserWriteStage(APITestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "ak-stage-access-denied",
|
||||
"error_message": None,
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"flow_info": {
|
||||
"background": self.flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
},
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
self.flow,
|
||||
component="ak-stage-access-denied",
|
||||
)
|
||||
|
||||
@patch(
|
||||
|
@ -163,18 +139,10 @@ class TestUserWriteStage(APITestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "ak-stage-access-denied",
|
||||
"error_message": None,
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"flow_info": {
|
||||
"background": self.flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
},
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
self.flow,
|
||||
component="ak-stage-access-denied",
|
||||
)
|
||||
|
||||
@patch(
|
||||
|
@ -199,16 +167,8 @@ class TestUserWriteStage(APITestCase):
|
|||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
force_str(response.content),
|
||||
{
|
||||
"component": "ak-stage-access-denied",
|
||||
"error_message": None,
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"flow_info": {
|
||||
"background": self.flow.background_url,
|
||||
"cancel_url": reverse("authentik_flows:cancel"),
|
||||
"title": "",
|
||||
},
|
||||
},
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
self.flow,
|
||||
component="ak-stage-access-denied",
|
||||
)
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
from django.test import TestCase
|
||||
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
|
||||
|
@ -18,7 +17,7 @@ class TestTenants(TestCase):
|
|||
"""Test Current tenant API"""
|
||||
tenant = create_test_tenant()
|
||||
self.assertJSONEqual(
|
||||
force_str(self.client.get(reverse("authentik_api:tenant-current")).content),
|
||||
self.client.get(reverse("authentik_api:tenant-current")).content.decode(),
|
||||
{
|
||||
"branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
|
||||
"branding_favicon": "/static/dist/assets/icons/icon.png",
|
||||
|
@ -33,11 +32,9 @@ class TestTenants(TestCase):
|
|||
Tenant.objects.all().delete()
|
||||
Tenant.objects.create(domain="bar.baz", branding_title="custom")
|
||||
self.assertJSONEqual(
|
||||
force_str(
|
||||
self.client.get(
|
||||
reverse("authentik_api:tenant-current"), HTTP_HOST="foo.bar.baz"
|
||||
).content
|
||||
),
|
||||
self.client.get(
|
||||
reverse("authentik_api:tenant-current"), HTTP_HOST="foo.bar.baz"
|
||||
).content.decode(),
|
||||
{
|
||||
"branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
|
||||
"branding_favicon": "/static/dist/assets/icons/icon.png",
|
||||
|
@ -51,7 +48,7 @@ class TestTenants(TestCase):
|
|||
"""Test fallback tenant"""
|
||||
Tenant.objects.all().delete()
|
||||
self.assertJSONEqual(
|
||||
force_str(self.client.get(reverse("authentik_api:tenant-current")).content),
|
||||
self.client.get(reverse("authentik_api:tenant-current")).content.decode(),
|
||||
{
|
||||
"branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
|
||||
"branding_favicon": "/static/dist/assets/icons/icon.png",
|
||||
|
|
|
@ -19036,9 +19036,15 @@ components:
|
|||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ErrorDetail'
|
||||
pending_user:
|
||||
type: string
|
||||
pending_user_avatar:
|
||||
type: string
|
||||
error_message:
|
||||
type: string
|
||||
required:
|
||||
- pending_user
|
||||
- pending_user_avatar
|
||||
- type
|
||||
App:
|
||||
type: object
|
||||
|
|
Reference in New Issue