stages/password: add constants for password backends

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-06-12 12:14:55 +02:00
parent 6661af032d
commit 10d949f7a9
14 changed files with 35 additions and 27 deletions

View File

@ -33,6 +33,7 @@ from authentik.flows.planner import (
from authentik.flows.views import NEXT_ARG_NAME, SESSION_KEY_GET, SESSION_KEY_PLAN
from authentik.lib.utils.urls import redirect_with_qs
from authentik.policies.utils import delete_none_keys
from authentik.stages.password import BACKEND_DJANGO
from authentik.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
from authentik.stages.prompt.stage import PLAN_CONTEXT_PROMPT
@ -198,7 +199,7 @@ class SourceFlowManager:
kwargs.update(
{
# Since we authenticate the user by their token, they have no backend set
PLAN_CONTEXT_AUTHENTICATION_BACKEND: "django.contrib.auth.backends.ModelBackend",
PLAN_CONTEXT_AUTHENTICATION_BACKEND: BACKEND_DJANGO,
PLAN_CONTEXT_SSO: True,
PLAN_CONTEXT_SOURCE: self.source,
PLAN_CONTEXT_REDIRECT: final_redirect,

View File

@ -6,6 +6,7 @@ from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from authentik.flows.models import FlowDesignation
from authentik.stages.identification.models import UserFields
from authentik.stages.password import BACKEND_DJANGO, BACKEND_LDAP
def create_default_authentication_flow(
@ -31,7 +32,7 @@ def create_default_authentication_flow(
password_stage, _ = PasswordStage.objects.using(db_alias).update_or_create(
name="default-authentication-password",
defaults={"backends": ["django.contrib.auth.backends.ModelBackend"]},
defaults={"backends": [BACKEND_DJANGO, BACKEND_LDAP]},
)
login_stage, _ = UserLoginStage.objects.using(db_alias).update_or_create(

View File

@ -15,9 +15,6 @@ PREFILL_POLICY_EXPRESSION = """# This policy sets the user for the currently run
# by injecting "pending_user"
akadmin = ak_user_by(username="akadmin")
context["pending_user"] = akadmin
# We're also setting the backend for the user, so we can
# directly login without having to identify again
context["user_backend"] = "django.contrib.auth.backends.ModelBackend"
return True"""

View File

@ -7,6 +7,7 @@ from django.utils.translation import gettext as _
from django.views import View
from authentik.core.models import Token, TokenIntents
from authentik.stages.password import BACKEND_DJANGO
class UseTokenView(View):
@ -18,7 +19,7 @@ class UseTokenView(View):
if not tokens.exists():
raise Http404
token = tokens.first()
login(request, token.user, backend="django.contrib.auth.backends.ModelBackend")
login(request, token.user, backend=BACKEND_DJANGO)
token.delete()
messages.warning(request, _("Used recovery-link to authenticate."))
return redirect("authentik_core:if-admin")

View File

@ -39,7 +39,7 @@ from authentik.sources.saml.processors.constants import (
from authentik.sources.saml.processors.request import SESSION_REQUEST_ID
from authentik.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
from authentik.stages.prompt.stage import PLAN_CONTEXT_PROMPT
from authentik.stages.user_login.stage import DEFAULT_BACKEND
from authentik.stages.user_login.stage import BACKEND_DJANGO
LOGGER = get_logger()
if TYPE_CHECKING:
@ -141,7 +141,7 @@ class ResponseProcessor:
self._source.authentication_flow,
**{
PLAN_CONTEXT_PENDING_USER: user,
PLAN_CONTEXT_AUTHENTICATION_BACKEND: DEFAULT_BACKEND,
PLAN_CONTEXT_AUTHENTICATION_BACKEND: BACKEND_DJANGO,
},
)
@ -204,7 +204,7 @@ class ResponseProcessor:
self._source.authentication_flow,
**{
PLAN_CONTEXT_PENDING_USER: matching_users.first(),
PLAN_CONTEXT_AUTHENTICATION_BACKEND: DEFAULT_BACKEND,
PLAN_CONTEXT_AUTHENTICATION_BACKEND: BACKEND_DJANGO,
PLAN_CONTEXT_REDIRECT: final_redirect,
},
)

View File

@ -9,6 +9,7 @@ from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding
from authentik.providers.oauth2.generators import generate_client_secret
from authentik.sources.oauth.models import OAuthSource
from authentik.stages.identification.models import IdentificationStage, UserFields
from authentik.stages.password import BACKEND_DJANGO
from authentik.stages.password.models import PasswordStage
@ -70,7 +71,7 @@ class TestIdentificationStage(TestCase):
def test_valid_with_password(self):
"""Test with valid email and password in single step"""
pw_stage = PasswordStage.objects.create(
name="password", backends=["django.contrib.auth.backends.ModelBackend"]
name="password", backends=[BACKEND_DJANGO]
)
self.stage.password_stage = pw_stage
self.stage.save()
@ -92,7 +93,7 @@ class TestIdentificationStage(TestCase):
def test_invalid_with_password(self):
"""Test with valid email and invalid password in single step"""
pw_stage = PasswordStage.objects.create(
name="password", backends=["django.contrib.auth.backends.ModelBackend"]
name="password", backends=[BACKEND_DJANGO]
)
self.stage.password_stage = pw_stage
self.stage.save()

View File

@ -17,6 +17,7 @@ from authentik.flows.tests.test_views import TO_STAGE_RESPONSE_MOCK
from authentik.flows.views import SESSION_KEY_PLAN
from authentik.stages.invitation.models import Invitation, InvitationStage
from authentik.stages.invitation.stage import INVITATION_TOKEN_KEY, PLAN_CONTEXT_PROMPT
from authentik.stages.password import BACKEND_DJANGO
from authentik.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
@ -46,9 +47,7 @@ class TestUserLoginStage(TestCase):
flow_pk=self.flow.pk.hex, stages=[self.stage], markers=[StageMarker()]
)
plan.context[PLAN_CONTEXT_PENDING_USER] = self.user
plan.context[
PLAN_CONTEXT_AUTHENTICATION_BACKEND
] = "django.contrib.auth.backends.ModelBackend"
plan.context[PLAN_CONTEXT_AUTHENTICATION_BACKEND] = BACKEND_DJANGO
session = self.client.session
session[SESSION_KEY_PLAN] = plan
session.save()
@ -79,9 +78,7 @@ class TestUserLoginStage(TestCase):
flow_pk=self.flow.pk.hex, stages=[self.stage], markers=[StageMarker()]
)
plan.context[PLAN_CONTEXT_PENDING_USER] = self.user
plan.context[
PLAN_CONTEXT_AUTHENTICATION_BACKEND
] = "django.contrib.auth.backends.ModelBackend"
plan.context[PLAN_CONTEXT_AUTHENTICATION_BACKEND] = BACKEND_DJANGO
session = self.client.session
session[SESSION_KEY_PLAN] = plan
session.save()

View File

@ -0,0 +1,3 @@
"""Backend paths"""
BACKEND_DJANGO = "django.contrib.auth.backends.ModelBackend"
BACKEND_LDAP = "authentik.sources.ldap.auth.LDAPBackend"

View File

@ -9,17 +9,18 @@ from rest_framework.serializers import BaseSerializer
from authentik.core.types import UserSettingSerializer
from authentik.flows.models import ConfigurableStage, Stage
from authentik.stages.password import BACKEND_DJANGO, BACKEND_LDAP
def get_authentication_backends():
"""Return all available authentication backends as tuple set"""
return [
(
"django.contrib.auth.backends.ModelBackend",
BACKEND_DJANGO,
_("authentik-internal Userdatabase"),
),
(
"authentik.sources.ldap.auth.LDAPBackend",
BACKEND_LDAP,
_("authentik LDAP"),
),
]

View File

@ -14,6 +14,7 @@ from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
from authentik.flows.tests.test_views import TO_STAGE_RESPONSE_MOCK
from authentik.flows.views import SESSION_KEY_PLAN
from authentik.providers.oauth2.generators import generate_client_secret
from authentik.stages.password import BACKEND_DJANGO
from authentik.stages.password.models import PasswordStage
MOCK_BACKEND_AUTHENTICATE = MagicMock(side_effect=PermissionDenied("test"))
@ -36,7 +37,7 @@ class TestPasswordStage(TestCase):
designation=FlowDesignation.AUTHENTICATION,
)
self.stage = PasswordStage.objects.create(
name="password", backends=["django.contrib.auth.backends.ModelBackend"]
name="password", backends=[BACKEND_DJANGO]
)
FlowStageBinding.objects.create(target=self.flow, stage=self.stage, order=2)

View File

@ -8,10 +8,10 @@ from structlog.stdlib import get_logger
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
from authentik.flows.stage import StageView
from authentik.lib.utils.time import timedelta_from_string
from authentik.stages.password import BACKEND_DJANGO
from authentik.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
LOGGER = get_logger()
DEFAULT_BACKEND = "django.contrib.auth.backends.ModelBackend"
USER_LOGIN_AUTHENTICATED = "user_login_authenticated"
@ -26,7 +26,7 @@ class UserLoginStageView(StageView):
LOGGER.debug(message)
return self.executor.stage_invalid()
backend = self.executor.plan.context.get(
PLAN_CONTEXT_AUTHENTICATION_BACKEND, DEFAULT_BACKEND
PLAN_CONTEXT_AUTHENTICATION_BACKEND, BACKEND_DJANGO
)
login(
self.request,

View File

@ -9,6 +9,7 @@ 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.views import SESSION_KEY_PLAN
from authentik.stages.password import BACKEND_DJANGO
from authentik.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND
from authentik.stages.user_logout.models import UserLogoutStage
@ -35,9 +36,7 @@ class TestUserLogoutStage(TestCase):
flow_pk=self.flow.pk.hex, stages=[self.stage], markers=[StageMarker()]
)
plan.context[PLAN_CONTEXT_PENDING_USER] = self.user
plan.context[
PLAN_CONTEXT_AUTHENTICATION_BACKEND
] = "django.contrib.auth.backends.ModelBackend"
plan.context[PLAN_CONTEXT_AUTHENTICATION_BACKEND] = BACKEND_DJANGO
session = self.client.session
session[SESSION_KEY_PLAN] = plan
session.save()

View File

@ -51,7 +51,10 @@
},
"model": "authentik_stages_password.passwordstage",
"attrs": {
"backends": ["django.contrib.auth.backends.ModelBackend"]
"backends": [
"django.contrib.auth.backends.ModelBackend",
"authentik.sources.ldap.auth.LDAPBackend"
]
}
},
{

View File

@ -54,7 +54,10 @@
},
"model": "authentik_stages_password.passwordstage",
"attrs": {
"backends": ["django.contrib.auth.backends.ModelBackend"]
"backends": [
"django.contrib.auth.backends.ModelBackend",
"authentik.sources.ldap.auth.LDAPBackend"
]
}
},
{