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