flows: update migrations to use update_or_create
This commit is contained in:
parent
b8654c06bf
commit
ec823aebed
|
@ -20,42 +20,38 @@ def create_default_authentication_flow(
|
|||
)
|
||||
db_alias = schema_editor.connection.alias
|
||||
|
||||
if (
|
||||
Flow.objects.using(db_alias)
|
||||
.filter(designation=FlowDesignation.AUTHENTICATION)
|
||||
.exists()
|
||||
):
|
||||
# Only create default flow when none exist
|
||||
return
|
||||
identification_stage, _ = IdentificationStage.objects.using(
|
||||
db_alias
|
||||
).update_or_create(
|
||||
name="default-authentication-identification",
|
||||
defaults={
|
||||
"user_fields": [UserFields.E_MAIL, UserFields.USERNAME],
|
||||
"template": Templates.DEFAULT_LOGIN,
|
||||
},
|
||||
)
|
||||
|
||||
if not IdentificationStage.objects.using(db_alias).exists():
|
||||
IdentificationStage.objects.using(db_alias).create(
|
||||
name="identification",
|
||||
user_fields=[UserFields.E_MAIL, UserFields.USERNAME],
|
||||
template=Templates.DEFAULT_LOGIN,
|
||||
)
|
||||
password_stage, _ = PasswordStage.objects.using(db_alias).update_or_create(
|
||||
name="default-authentication-password",
|
||||
defaults={"backends": ["django.contrib.auth.backends.ModelBackend"]},
|
||||
)
|
||||
|
||||
if not PasswordStage.objects.using(db_alias).exists():
|
||||
PasswordStage.objects.using(db_alias).create(
|
||||
name="password", backends=["django.contrib.auth.backends.ModelBackend"],
|
||||
)
|
||||
login_stage, _ = UserLoginStage.objects.using(db_alias).update_or_create(
|
||||
name="default-authentication-login"
|
||||
)
|
||||
|
||||
if not UserLoginStage.objects.using(db_alias).exists():
|
||||
UserLoginStage.objects.using(db_alias).create(name="authentication")
|
||||
|
||||
flow = Flow.objects.using(db_alias).create(
|
||||
name="Welcome to passbook!",
|
||||
flow, _ = Flow.objects.using(db_alias).update_or_create(
|
||||
slug="default-authentication-flow",
|
||||
designation=FlowDesignation.AUTHENTICATION,
|
||||
defaults={"name": "Welcome to passbook!",},
|
||||
)
|
||||
FlowStageBinding.objects.using(db_alias).create(
|
||||
flow=flow, stage=IdentificationStage.objects.using(db_alias).first(), order=0,
|
||||
FlowStageBinding.objects.using(db_alias).update_or_create(
|
||||
flow=flow, stage=identification_stage, defaults={"order": 0,},
|
||||
)
|
||||
FlowStageBinding.objects.using(db_alias).create(
|
||||
flow=flow, stage=PasswordStage.objects.using(db_alias).first(), order=1,
|
||||
FlowStageBinding.objects.using(db_alias).update_or_create(
|
||||
flow=flow, stage=password_stage, defaults={"order": 1,},
|
||||
)
|
||||
FlowStageBinding.objects.using(db_alias).create(
|
||||
flow=flow, stage=UserLoginStage.objects.using(db_alias).first(), order=2,
|
||||
FlowStageBinding.objects.using(db_alias).update_or_create(
|
||||
flow=flow, stage=login_stage, defaults={"order": 2,},
|
||||
)
|
||||
|
||||
|
||||
|
@ -67,24 +63,19 @@ def create_default_invalidation_flow(
|
|||
UserLogoutStage = apps.get_model("passbook_stages_user_logout", "UserLogoutStage")
|
||||
db_alias = schema_editor.connection.alias
|
||||
|
||||
if (
|
||||
Flow.objects.using(db_alias)
|
||||
.filter(designation=FlowDesignation.INVALIDATION)
|
||||
.exists()
|
||||
):
|
||||
# Only create default flow when none exist
|
||||
return
|
||||
UserLogoutStage.objects.using(db_alias).update_or_create(
|
||||
name="default-invalidation-logout"
|
||||
)
|
||||
|
||||
if not UserLogoutStage.objects.using(db_alias).exists():
|
||||
UserLogoutStage.objects.using(db_alias).create(name="logout")
|
||||
|
||||
flow = Flow.objects.using(db_alias).create(
|
||||
name="default-invalidation-flow",
|
||||
flow, _ = Flow.objects.using(db_alias).update_or_create(
|
||||
slug="default-invalidation-flow",
|
||||
designation=FlowDesignation.INVALIDATION,
|
||||
defaults={"name": "Logout",},
|
||||
)
|
||||
FlowStageBinding.objects.using(db_alias).create(
|
||||
flow=flow, stage=UserLogoutStage.objects.using(db_alias).first(), order=0,
|
||||
FlowStageBinding.objects.using(db_alias).update_or_create(
|
||||
flow=flow,
|
||||
stage=UserLogoutStage.objects.using(db_alias).first(),
|
||||
defaults={"order": 0,},
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -34,60 +34,63 @@ def create_default_source_enrollment_flow(
|
|||
db_alias = schema_editor.connection.alias
|
||||
|
||||
# Create a policy that only allows this flow when doing an SSO Request
|
||||
flow_policy = ExpressionPolicy.objects.using(db_alias).create(
|
||||
name="default-source-enrollment-if-sso", expression=FLOW_POLICY_EXPRESSION
|
||||
flow_policy, _ = ExpressionPolicy.objects.using(db_alias).update_or_create(
|
||||
name="default-source-enrollment-if-sso",
|
||||
defaults={"expression": FLOW_POLICY_EXPRESSION},
|
||||
)
|
||||
|
||||
# This creates a Flow used by sources to enroll users
|
||||
# It makes sure that a username is set, and if not, prompts the user for a Username
|
||||
flow = Flow.objects.using(db_alias).create(
|
||||
name="default-source-enrollment",
|
||||
flow, _ = Flow.objects.using(db_alias).update_or_create(
|
||||
slug="default-source-enrollment",
|
||||
designation=FlowDesignation.ENROLLMENT,
|
||||
defaults={"name": "Welcome to passbook!",},
|
||||
)
|
||||
PolicyBinding.objects.using(db_alias).create(
|
||||
policy=flow_policy, target=flow, order=0
|
||||
PolicyBinding.objects.using(db_alias).update_or_create(
|
||||
policy=flow_policy, target=flow, defaults={"order": 0}
|
||||
)
|
||||
|
||||
# PromptStage to ask user for their username
|
||||
prompt_stage = PromptStage.objects.using(db_alias).create(
|
||||
prompt_stage, _ = PromptStage.objects.using(db_alias).update_or_create(
|
||||
name="default-source-enrollment-username-prompt",
|
||||
)
|
||||
prompt_stage.fields.add(
|
||||
Prompt.objects.using(db_alias).create(
|
||||
field_key="username",
|
||||
label="Username",
|
||||
type=FieldTypes.TEXT,
|
||||
required=True,
|
||||
placeholder="Username",
|
||||
)
|
||||
prompt, _ = Prompt.objects.using(db_alias).update_or_create(
|
||||
field_key="username",
|
||||
defaults={
|
||||
"label": "Username",
|
||||
"type": FieldTypes.TEXT,
|
||||
"required": True,
|
||||
"placeholder": "Username",
|
||||
},
|
||||
)
|
||||
prompt_stage.fields.add(prompt)
|
||||
|
||||
# Policy to only trigger prompt when no username is given
|
||||
prompt_policy = ExpressionPolicy.objects.using(db_alias).create(
|
||||
prompt_policy, _ = ExpressionPolicy.objects.using(db_alias).update_or_create(
|
||||
name="default-source-enrollment-if-username",
|
||||
expression=PROMPT_POLICY_EXPRESSION,
|
||||
defaults={"expression": PROMPT_POLICY_EXPRESSION},
|
||||
)
|
||||
|
||||
# UserWrite stage to create the user, and login stage to log user in
|
||||
user_write = UserWriteStage.objects.using(db_alias).create(
|
||||
user_write, _ = UserWriteStage.objects.using(db_alias).update_or_create(
|
||||
name="default-source-enrollment-write"
|
||||
)
|
||||
user_login = UserLoginStage.objects.using(db_alias).create(
|
||||
user_login, _ = UserLoginStage.objects.using(db_alias).update_or_create(
|
||||
name="default-source-enrollment-login"
|
||||
)
|
||||
|
||||
binding = FlowStageBinding.objects.using(db_alias).create(
|
||||
flow=flow, stage=prompt_stage, order=0
|
||||
binding, _ = FlowStageBinding.objects.using(db_alias).update_or_create(
|
||||
flow=flow, stage=prompt_stage, defaults={"order": 0}
|
||||
)
|
||||
PolicyBinding.objects.using(db_alias).create(
|
||||
policy=prompt_policy, target=binding, order=0
|
||||
PolicyBinding.objects.using(db_alias).update_or_create(
|
||||
policy=prompt_policy, target=binding, defaults={"order": 0}
|
||||
)
|
||||
|
||||
FlowStageBinding.objects.using(db_alias).create(
|
||||
flow=flow, stage=user_write, order=1
|
||||
FlowStageBinding.objects.using(db_alias).update_or_create(
|
||||
flow=flow, stage=user_write, defaults={"order": 1}
|
||||
)
|
||||
FlowStageBinding.objects.using(db_alias).create(
|
||||
flow=flow, stage=user_login, order=2
|
||||
FlowStageBinding.objects.using(db_alias).update_or_create(
|
||||
flow=flow, stage=user_login, defaults={"order": 2}
|
||||
)
|
||||
|
||||
|
||||
|
@ -107,25 +110,26 @@ def create_default_source_authentication_flow(
|
|||
db_alias = schema_editor.connection.alias
|
||||
|
||||
# Create a policy that only allows this flow when doing an SSO Request
|
||||
flow_policy = ExpressionPolicy.objects.using(db_alias).create(
|
||||
name="default-source-authentication-if-sso", expression=FLOW_POLICY_EXPRESSION
|
||||
flow_policy, _ = ExpressionPolicy.objects.using(db_alias).update_or_create(
|
||||
name="default-source-authentication-if-sso",
|
||||
defaults={"expression": FLOW_POLICY_EXPRESSION,},
|
||||
)
|
||||
|
||||
# This creates a Flow used by sources to authenticate users
|
||||
flow = Flow.objects.using(db_alias).create(
|
||||
name="default-source-authentication",
|
||||
flow, _ = Flow.objects.using(db_alias).update_or_create(
|
||||
slug="default-source-authentication",
|
||||
designation=FlowDesignation.AUTHENTICATION,
|
||||
defaults={"name": "Welcome to passbook!",},
|
||||
)
|
||||
PolicyBinding.objects.using(db_alias).create(
|
||||
policy=flow_policy, target=flow, order=0
|
||||
PolicyBinding.objects.using(db_alias).update_or_create(
|
||||
policy=flow_policy, target=flow, defaults={"order": 0}
|
||||
)
|
||||
|
||||
user_login = UserLoginStage.objects.using(db_alias).create(
|
||||
user_login, _ = UserLoginStage.objects.using(db_alias).update_or_create(
|
||||
name="default-source-authentication-login"
|
||||
)
|
||||
FlowStageBinding.objects.using(db_alias).create(
|
||||
flow=flow, stage=user_login, order=0
|
||||
FlowStageBinding.objects.using(db_alias).update_or_create(
|
||||
flow=flow, stage=user_login, defaults={"order": 0}
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ from django.db.backends.base.schema import BaseDatabaseSchemaEditor
|
|||
from passbook.flows.models import FlowDesignation
|
||||
|
||||
|
||||
def create_default_provider_authz_flow(
|
||||
def create_default_provider_authorization_flow(
|
||||
apps: Apps, schema_editor: BaseDatabaseSchemaEditor
|
||||
):
|
||||
Flow = apps.get_model("passbook_flows", "Flow")
|
||||
|
@ -18,22 +18,24 @@ def create_default_provider_authz_flow(
|
|||
db_alias = schema_editor.connection.alias
|
||||
|
||||
# Empty flow for providers where consent is implicitly given
|
||||
Flow.objects.using(db_alias).create(
|
||||
name="Authorize Application",
|
||||
Flow.objects.using(db_alias).update_or_create(
|
||||
slug="default-provider-authorization-implicit-consent",
|
||||
designation=FlowDesignation.AUTHORIZATION,
|
||||
defaults={"name": "Authorize Application"},
|
||||
)
|
||||
|
||||
# Flow with consent form to obtain explicit user consent
|
||||
flow = Flow.objects.using(db_alias).create(
|
||||
name="Authorize Application",
|
||||
flow, _ = Flow.objects.using(db_alias).update_or_create(
|
||||
slug="default-provider-authorization-explicit-consent",
|
||||
designation=FlowDesignation.AUTHORIZATION,
|
||||
defaults={"name": "Authorize Application"},
|
||||
)
|
||||
stage = ConsentStage.objects.using(db_alias).create(
|
||||
stage, _ = ConsentStage.objects.using(db_alias).update_or_create(
|
||||
name="default-provider-authorization-consent"
|
||||
)
|
||||
FlowStageBinding.objects.using(db_alias).create(flow=flow, stage=stage, order=0)
|
||||
FlowStageBinding.objects.using(db_alias).update_or_create(
|
||||
flow=flow, stage=stage, defaults={"order": 0}
|
||||
)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
@ -43,4 +45,4 @@ class Migration(migrations.Migration):
|
|||
("passbook_stages_consent", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [migrations.RunPython(create_default_provider_authz_flow)]
|
||||
operations = [migrations.RunPython(create_default_provider_authorization_flow)]
|
||||
|
|
|
@ -153,7 +153,7 @@ class Processor:
|
|||
self, request: HttpRequest, flow: Flow, **kwargs
|
||||
) -> HttpResponse:
|
||||
kwargs[PLAN_CONTEXT_SSO] = True
|
||||
request.session[SESSION_KEY_PLAN] = FlowPlanner(flow).plan(request, kwargs,)
|
||||
request.session[SESSION_KEY_PLAN] = FlowPlanner(flow).plan(request, kwargs)
|
||||
return redirect_with_qs(
|
||||
"passbook_flows:flow-executor-shell", request.GET, flow_slug=flow.slug,
|
||||
)
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.core.validators import validate_email
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from structlog import get_logger
|
||||
|
||||
from passbook.flows.models import Flow, FlowDesignation
|
||||
from passbook.lib.utils.ui import human_list
|
||||
from passbook.stages.identification.models import IdentificationStage, UserFields
|
||||
|
||||
|
@ -14,6 +15,15 @@ LOGGER = get_logger()
|
|||
class IdentificationStageForm(forms.ModelForm):
|
||||
"""Form to create/edit IdentificationStage instances"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields["enrollment_flow"].queryset = Flow.objects.filter(
|
||||
designation=FlowDesignation.ENROLLMENT
|
||||
)
|
||||
self.fields["recovery_flow"].queryset = Flow.objects.filter(
|
||||
designation=FlowDesignation.RECOVERY
|
||||
)
|
||||
|
||||
class Meta:
|
||||
|
||||
model = IdentificationStage
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
"""Prompt forms"""
|
||||
from django import forms
|
||||
from django.contrib.admin.widgets import FilteredSelectMultiple
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from guardian.shortcuts import get_anonymous_user
|
||||
|
||||
from passbook.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
|
||||
|
@ -16,6 +18,7 @@ class PromptStageForm(forms.ModelForm):
|
|||
fields = ["name", "fields"]
|
||||
widgets = {
|
||||
"name": forms.TextInput(),
|
||||
"fields": FilteredSelectMultiple(_("prompts"), False),
|
||||
}
|
||||
|
||||
|
||||
|
|
Reference in a new issue