docs: add example flows

closes #36
This commit is contained in:
Jens Langhammer 2020-09-08 23:18:42 +02:00
parent 3b6341bf41
commit 8db60b3e83
9 changed files with 844 additions and 38 deletions

View File

@ -0,0 +1,180 @@
{
"version": 1,
"entries": [
{
"identifiers": {
"pk": "773c6673-e4a2-423f-8d32-95b7b4a41cf3",
"slug": "default-enrollment-flow"
},
"model": "passbook_flows.flow",
"attrs": {
"name": "Default enrollment Flow",
"title": "Welcome to passbook!",
"designation": "enrollment"
}
},
{
"identifiers": {
"pk": "cb954fd4-65a5-4ad9-b1ee-180ee9559cf4"
},
"model": "passbook_stages_prompt.prompt",
"attrs": {
"field_key": "username",
"label": "Username",
"type": "text",
"required": true,
"placeholder": "Username",
"order": 0
}
},
{
"identifiers": {
"pk": "7db91ee8-4290-4e08-8d39-63f132402515"
},
"model": "passbook_stages_prompt.prompt",
"attrs": {
"field_key": "password",
"label": "Password",
"type": "password",
"required": true,
"placeholder": "Password",
"order": 0
}
},
{
"identifiers": {
"pk": "d30b5eb4-7787-4072-b1ba-65b46e928920"
},
"model": "passbook_stages_prompt.prompt",
"attrs": {
"field_key": "password_repeat",
"label": "Password (repeat)",
"type": "password",
"required": true,
"placeholder": "Password (repeat)",
"order": 1
}
},
{
"identifiers": {
"pk": "f78d977a-efa6-4cc2-9a0f-2621a9fd94d2"
},
"model": "passbook_stages_prompt.prompt",
"attrs": {
"field_key": "name",
"label": "Name",
"type": "text",
"required": true,
"placeholder": "Name",
"order": 0
}
},
{
"identifiers": {
"pk": "1ff91927-e33d-4615-95b0-c258e5f0df62"
},
"model": "passbook_stages_prompt.prompt",
"attrs": {
"field_key": "email",
"label": "Email",
"type": "email",
"required": true,
"placeholder": "Email",
"order": 1
}
},
{
"identifiers": {
"pk": "6c342b94-790d-425a-ae31-6196b6570722",
"name": "default-enrollment-prompt-second"
},
"model": "passbook_stages_prompt.promptstage",
"attrs": {
"fields": [
"f78d977a-efa6-4cc2-9a0f-2621a9fd94d2",
"1ff91927-e33d-4615-95b0-c258e5f0df62"
]
}
},
{
"identifiers": {
"pk": "20375f30-7fa7-4562-8f6e-0f61889f2963",
"name": "default-enrollment-prompt-first"
},
"model": "passbook_stages_prompt.promptstage",
"attrs": {
"fields": [
"cb954fd4-65a5-4ad9-b1ee-180ee9559cf4",
"7db91ee8-4290-4e08-8d39-63f132402515",
"d30b5eb4-7787-4072-b1ba-65b46e928920"
]
}
},
{
"identifiers": {
"pk": "77090897-eb3f-40db-81e6-b4074b1998c4",
"name": "default-enrollment-user-login"
},
"model": "passbook_stages_user_login.userloginstage",
"attrs": {
"session_duration": 0
}
},
{
"identifiers": {
"pk": "a4090add-f483-4ac6-8917-10b493ef843e",
"name": "default-enrollment-user-write"
},
"model": "passbook_stages_user_write.userwritestage",
"attrs": {}
},
{
"identifiers": {
"pk": "34e1e7d5-8eed-4549-bc7a-305069ff7df0",
"target": "773c6673-e4a2-423f-8d32-95b7b4a41cf3",
"stage": "20375f30-7fa7-4562-8f6e-0f61889f2963",
"order": 0
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
},
{
"identifiers": {
"pk": "e40467a6-3052-488c-a1b5-1ad7a80fe7b3",
"target": "773c6673-e4a2-423f-8d32-95b7b4a41cf3",
"stage": "6c342b94-790d-425a-ae31-6196b6570722",
"order": 1
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
},
{
"identifiers": {
"pk": "76bc594e-2715-49ab-bd40-994abd9a7b70",
"target": "773c6673-e4a2-423f-8d32-95b7b4a41cf3",
"stage": "a4090add-f483-4ac6-8917-10b493ef843e",
"order": 2
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
},
{
"identifiers": {
"pk": "2f324f6d-7646-4108-a6e2-e7f90985477f",
"target": "773c6673-e4a2-423f-8d32-95b7b4a41cf3",
"stage": "77090897-eb3f-40db-81e6-b4074b1998c4",
"order": 3
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
}
]
}

View File

@ -0,0 +1,234 @@
{
"version": 1,
"entries": [
{
"identifiers": {
"pk": "773c6673-e4a2-423f-8d32-95b7b4a41cf3",
"slug": "default-enrollment-flow"
},
"model": "passbook_flows.flow",
"attrs": {
"name": "Default enrollment Flow",
"title": "Welcome to passbook!",
"designation": "enrollment"
}
},
{
"identifiers": {
"pk": "cb954fd4-65a5-4ad9-b1ee-180ee9559cf4"
},
"model": "passbook_stages_prompt.prompt",
"attrs": {
"field_key": "username",
"label": "Username",
"type": "text",
"required": true,
"placeholder": "Username",
"order": 0
}
},
{
"identifiers": {
"pk": "7db91ee8-4290-4e08-8d39-63f132402515"
},
"model": "passbook_stages_prompt.prompt",
"attrs": {
"field_key": "password",
"label": "Password",
"type": "password",
"required": true,
"placeholder": "Password",
"order": 0
}
},
{
"identifiers": {
"pk": "d30b5eb4-7787-4072-b1ba-65b46e928920"
},
"model": "passbook_stages_prompt.prompt",
"attrs": {
"field_key": "password_repeat",
"label": "Password (repeat)",
"type": "password",
"required": true,
"placeholder": "Password (repeat)",
"order": 1
}
},
{
"identifiers": {
"pk": "f78d977a-efa6-4cc2-9a0f-2621a9fd94d2"
},
"model": "passbook_stages_prompt.prompt",
"attrs": {
"field_key": "name",
"label": "Name",
"type": "text",
"required": true,
"placeholder": "Name",
"order": 0
}
},
{
"identifiers": {
"pk": "1ff91927-e33d-4615-95b0-c258e5f0df62"
},
"model": "passbook_stages_prompt.prompt",
"attrs": {
"field_key": "email",
"label": "Email",
"type": "email",
"required": true,
"placeholder": "Email",
"order": 1
}
},
{
"identifiers": {
"pk": "096e6282-6b30-4695-bd03-3b143eab5580",
"name": "default-enrollment-email-verficiation"
},
"model": "passbook_stages_email.emailstage",
"attrs": {
"host": "localhost",
"port": 25,
"username": "",
"use_tls": false,
"use_ssl": false,
"timeout": 10,
"from_address": "system@passbook.local",
"token_expiry": 30,
"subject": "passbook",
"template": "stages/email/for_email/account_confirmation.html"
}
},
{
"identifiers": {
"pk": "6c342b94-790d-425a-ae31-6196b6570722",
"name": "default-enrollment-prompt-second"
},
"model": "passbook_stages_prompt.promptstage",
"attrs": {
"fields": [
"f78d977a-efa6-4cc2-9a0f-2621a9fd94d2",
"1ff91927-e33d-4615-95b0-c258e5f0df62"
]
}
},
{
"identifiers": {
"pk": "20375f30-7fa7-4562-8f6e-0f61889f2963",
"name": "default-enrollment-prompt-first"
},
"model": "passbook_stages_prompt.promptstage",
"attrs": {
"fields": [
"cb954fd4-65a5-4ad9-b1ee-180ee9559cf4",
"7db91ee8-4290-4e08-8d39-63f132402515",
"d30b5eb4-7787-4072-b1ba-65b46e928920"
]
}
},
{
"identifiers": {
"pk": "77090897-eb3f-40db-81e6-b4074b1998c4",
"name": "default-enrollment-user-login"
},
"model": "passbook_stages_user_login.userloginstage",
"attrs": {
"session_duration": 0
}
},
{
"identifiers": {
"pk": "a4090add-f483-4ac6-8917-10b493ef843e",
"name": "default-enrollment-user-write"
},
"model": "passbook_stages_user_write.userwritestage",
"attrs": {}
},
{
"identifiers": {
"pk": "34e1e7d5-8eed-4549-bc7a-305069ff7df0",
"target": "773c6673-e4a2-423f-8d32-95b7b4a41cf3",
"stage": "7145399a-0015-4201-9560-2d5c6d27efeb",
"order": 0
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
},
{
"identifiers": {
"pk": "e40467a6-3052-488c-a1b5-1ad7a80fe7b3",
"target": "773c6673-e4a2-423f-8d32-95b7b4a41cf3",
"stage": "130ab95a-5146-4ca9-a7b7-3518f629cc3e",
"order": 1
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
},
{
"identifiers": {
"pk": "76bc594e-2715-49ab-bd40-994abd9a7b70",
"target": "773c6673-e4a2-423f-8d32-95b7b4a41cf3",
"stage": "a4090add-f483-4ac6-8917-10b493ef843e",
"order": 2
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
},
{
"identifiers": {
"pk": "1db34a14-8985-4184-b5c9-254cd585d94f",
"target": "773c6673-e4a2-423f-8d32-95b7b4a41cf3",
"stage": "096e6282-6b30-4695-bd03-3b143eab5580",
"order": 3
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
},
{
"identifiers": {
"pk": "2f324f6d-7646-4108-a6e2-e7f90985477f",
"target": "773c6673-e4a2-423f-8d32-95b7b4a41cf3",
"stage": "77090897-eb3f-40db-81e6-b4074b1998c4",
"order": 4
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
},
{
"identifiers": {
"pk": "9922212c-47a2-475a-9905-abeb5e621652"
},
"model": "passbook_policies_expression.expressionpolicy",
"attrs": {
"name": "policy-enrollment-password-equals",
"expression": "# Verifies that the passwords are equal\r\nreturn request.context['password'] == request.context['password_repeat']"
}
},
{
"identifiers": {
"pk": "4f3b5a0a-8f91-438b-959c-c908415cacd9",
"policy": "9922212c-47a2-475a-9905-abeb5e621652",
"target": "20375f30-7fa7-4562-8f6e-0f61889f2963",
"order": 0
},
"model": "passbook_policies.policybinding",
"attrs": {
"enabled": true,
"timeout": 30
}
}
]
}

View File

@ -0,0 +1,49 @@
# Example Flows
!!! info
You can apply theses flows multiple times to stay updated, however this will discard all changes you've made.
## Enrollment (2 Stage)
Flow: right-click [here](enrollment-2-stage.json) and save the file.
Sign-up flow for new users, which prompts them for their username, email, password and name. No verification is done. Users are also immediately logged on after this flow.
## Enrollment with email verification
Flow: right-click [here](enrollment-email-verification.json) and save the file.
Same flow as above, with an extra email verification stage.
You'll probably have to adjust the Email stage and set your connection details.
## Two-factor Login
Flow: right-click [here](login-2fa.json) and save the file.
Login flow which follows the default pattern (username/email, then password), but also checks for the user's OTP token, if they have one configured
## Login with conditional Captcha
Flow: right-click [here](login-conditional-captcha.json) and save the file.
Login flow which conditionally shows the users a captcha, based on the reputation of their IP and Username.
By default, the captcha test keys are used. You can get a proper key [here](https://www.google.com/recaptcha/intro/v3.html)
## Recovery with email verification
Flow: right-click [here](recovery-email-verification.json) and save the file.
Recovery flow, the user is sent an email after they've identified themselves. After they click on the link in the email, they are prompted for a new password and immediately logged on.
## User deletion
Flow: right-click [here](unenrollment.json) and save the file.
Flow for users to delete their account,
!!! warning
This is done without any warning.

View File

@ -0,0 +1,139 @@
{
"version": 1,
"entries": [
{
"identifiers": {
"slug": "default-authentication-flow",
"pk": "563ece21-e9a4-47e5-a264-23ffd923e393"
},
"model": "passbook_flows.flow",
"attrs": {
"name": "Default Authentication Flow",
"title": "Welcome to passbook!",
"designation": "authentication"
}
},
{
"identifiers": {
"name": "default-authentication-login",
"pk": "69d41125-3987-499b-8d74-ef27b54b88c8"
},
"model": "passbook_stages_user_login.userloginstage",
"attrs": {
"session_duration": 0
}
},
{
"identifiers": {
"name": "default-authentication-flow-captcha",
"pk": "a368cafc-1494-45e9-b75b-b5e7ac2bd3e4"
},
"model": "passbook_stages_captcha.captchastage",
"attrs": {
"public_key": "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI",
"private_key": "6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe"
}
},
{
"identifiers": {
"name": "default-authentication-identification",
"pk": "5f594f27-0def-488d-9855-fe604eb13de5"
},
"model": "passbook_stages_identification.identificationstage",
"attrs": {
"user_fields": [
"email",
"username"
],
"template": "stages/identification/login.html",
"enrollment_flow": null,
"recovery_flow": null
}
},
{
"identifiers": {
"name": "default-authentication-password",
"pk": "d8affa62-500c-4c5c-a01f-5835e1ffdf40"
},
"model": "passbook_stages_password.passwordstage",
"attrs": {
"backends": [
"django.contrib.auth.backends.ModelBackend"
]
}
},
{
"identifiers": {
"pk": "a3056482-b692-4e3a-93f1-7351c6a351c7",
"target": "563ece21-e9a4-47e5-a264-23ffd923e393",
"stage": "5f594f27-0def-488d-9855-fe604eb13de5",
"order": 0
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
},
{
"identifiers": {
"pk": "4e8538cf-3e18-4a68-82ae-6df6725fa2e6",
"target": "563ece21-e9a4-47e5-a264-23ffd923e393",
"stage": "d8affa62-500c-4c5c-a01f-5835e1ffdf40",
"order": 1
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
},
{
"identifiers": {
"pk": "3bcd6af0-48a6-4e18-87f3-d251a1a58226",
"target": "563ece21-e9a4-47e5-a264-23ffd923e393",
"stage": "a368cafc-1494-45e9-b75b-b5e7ac2bd3e4",
"order": 2
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
},
{
"identifiers": {
"pk": "f3fede3a-a9b5-4232-9ec7-be7ff4194b27",
"target": "563ece21-e9a4-47e5-a264-23ffd923e393",
"stage": "69d41125-3987-499b-8d74-ef27b54b88c8",
"order": 3
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
},
{
"identifiers": {
"pk": "688c9890-47ad-4327-a9e5-380e88d34be5"
},
"model": "passbook_policies_reputation.reputationpolicy",
"attrs": {
"name": "default-authentication-flow-conditional-captcha",
"check_ip": true,
"check_username": true,
"threshold": -5
}
},
{
"identifiers": {
"pk": "02e4d220-3448-44db-822e-c5255cf7c250",
"policy": "688c9890-47ad-4327-a9e5-380e88d34be5",
"target": "998bdd3a-52b9-4298-8878-3c3fc993b68c",
"order": 0
},
"model": "passbook_policies.policybinding",
"attrs": {
"enabled": true,
"timeout": 30
}
}
]
}

View File

@ -1,36 +0,0 @@
# Login Flow
This document describes how a simple authentication flow can be created.
This flow is created automatically when passbook is installed.
1. Create an **Identification** stage
> Here you can select whichever fields the user can identify themselves with
> Select the Template **Default Login**, as this template shows the (optional) Flows
> Here you can also link optional enrollment and recovery flows.
2. Create a **Password** stage
> Select the Backend you want the password to be checked against. Select "passbook-internal Userdatabase".
3. Create a **User Login** stage
> This stage doesn't have any options.
4. Create a flow
> Create a flow with the delegation of **Authentication**
> Assign a name and a slug. The slug is used in the URL when the flow is executed.
5. Bind the stages to the flow
> Bind the **Identification** Stage with an order of 0
> Bind the **Password** Stage with an order of 1
> Bind the **User Login** Stage with an order of 2
![](login.png)
!!! notice
This flow can used by any user, authenticated and un-authenticated. This means any authenticated user that visits this flow can login again.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

View File

@ -0,0 +1,204 @@
{
"version": 1,
"entries": [
{
"identifiers": {
"pk": "a5993183-89c0-43d2-a7f4-ddffb17baba7",
"slug": "default-recovery-flow"
},
"model": "passbook_flows.flow",
"attrs": {
"name": "Default recovery flow",
"title": "Reset your password",
"designation": "recovery"
}
},
{
"identifiers": {
"pk": "1ff91927-e33d-4615-95b0-c258e5f0df62"
},
"model": "passbook_stages_prompt.prompt",
"attrs": {
"field_key": "email",
"label": "Email",
"type": "email",
"required": true,
"placeholder": "Email",
"order": 1
}
},
{
"identifiers": {
"pk": "7db91ee8-4290-4e08-8d39-63f132402515"
},
"model": "passbook_stages_prompt.prompt",
"attrs": {
"field_key": "password",
"label": "Password",
"type": "password",
"required": true,
"placeholder": "Password",
"order": 0
}
},
{
"identifiers": {
"pk": "d30b5eb4-7787-4072-b1ba-65b46e928920"
},
"model": "passbook_stages_prompt.prompt",
"attrs": {
"field_key": "password_repeat",
"label": "Password (repeat)",
"type": "password",
"required": true,
"placeholder": "Password (repeat)",
"order": 1
}
},
{
"identifiers": {
"pk": "d33ceb78-eb0d-44e7-828b-541414214eb3",
"name": "default-recovery-prompt-email"
},
"model": "passbook_stages_prompt.promptstage",
"attrs": {
"fields": [
"1ff91927-e33d-4615-95b0-c258e5f0df62"
]
}
},
{
"identifiers": {
"pk": "3909fd60-b013-4668-8806-12e9507dab97",
"name": "default-recovery-user-write"
},
"model": "passbook_stages_user_write.userwritestage",
"attrs": {}
},
{
"identifiers": {
"pk": "66f948dc-3f74-42b2-b26b-b8b9df109efb",
"name": "default-recovery-email"
},
"model": "passbook_stages_email.emailstage",
"attrs": {
"host": "localhost",
"port": 25,
"username": "",
"use_tls": false,
"use_ssl": false,
"timeout": 10,
"from_address": "system@passbook.local",
"token_expiry": 30,
"subject": "passbook",
"template": "stages/email/for_email/password_reset.html"
}
},
{
"identifiers": {
"pk": "975d5502-1e22-4d10-b560-fbc5bd70ff4d",
"name": "default-password-change-prompt"
},
"model": "passbook_stages_prompt.promptstage",
"attrs": {
"fields": [
"7db91ee8-4290-4e08-8d39-63f132402515",
"d30b5eb4-7787-4072-b1ba-65b46e928920"
]
}
},
{
"identifiers": {
"pk": "fcdd4206-0d35-4ad2-a59f-5a72422936bb",
"name": "default-recovery-user-login"
},
"model": "passbook_stages_user_login.userloginstage",
"attrs": {
"session_duration": 0
}
},
{
"identifiers": {
"pk": "7af7558e-2196-4b9f-a08e-d38420b7cfbb",
"target": "a5993183-89c0-43d2-a7f4-ddffb17baba7",
"stage": "2390c8be-203a-40f9-acf1-6665fb4be23c",
"order": 0
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
},
{
"identifiers": {
"pk": "29446fd6-dd93-4e92-9830-2d81debad5ae",
"target": "a5993183-89c0-43d2-a7f4-ddffb17baba7",
"stage": "66f948dc-3f74-42b2-b26b-b8b9df109efb",
"order": 1
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
},
{
"identifiers": {
"pk": "1219d06e-2c06-4c5b-a162-78e3959c6cf0",
"target": "a5993183-89c0-43d2-a7f4-ddffb17baba7",
"stage": "f0b2ab09-759c-47b0-9d2a-3470e7912b71",
"order": 2
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
},
{
"identifiers": {
"pk": "66de86ba-0707-46a0-8475-ff2e260d6935",
"target": "a5993183-89c0-43d2-a7f4-ddffb17baba7",
"stage": "3909fd60-b013-4668-8806-12e9507dab97",
"order": 3
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
},
{
"identifiers": {
"pk": "9cec2334-d4a2-4895-a2b2-bc5ae4e9639a",
"target": "a5993183-89c0-43d2-a7f4-ddffb17baba7",
"stage": "fcdd4206-0d35-4ad2-a59f-5a72422936bb",
"order": 4
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
},
{
"identifiers": {
"pk": "cd042fc6-cc92-4b98-b7e6-f4729df798d8"
},
"model": "passbook_policies_expression.expressionpolicy",
"attrs": {
"name": "default-password-change-password-equal",
"expression": "# Check that both passwords are equal.\nreturn request.context['password'] == request.context['password_repeat']"
}
},
{
"identifiers": {
"pk": "ed3fc35e-4b6b-499e-b82b-bb2a90ac70b7",
"policy": "cd042fc6-cc92-4b98-b7e6-f4729df798d8",
"target": "975d5502-1e22-4d10-b560-fbc5bd70ff4d",
"order": 0
},
"model": "passbook_policies.policybinding",
"attrs": {
"enabled": true,
"timeout": 30
}
}
]
}

View File

@ -0,0 +1,37 @@
{
"version": 1,
"entries": [
{
"identifiers": {
"pk": "59a576ce-2f23-4a63-b63a-d18dc7e550f5",
"slug": "default-unenrollment-flow"
},
"model": "passbook_flows.flow",
"attrs": {
"name": "Default unenrollment flow",
"title": "Delete your account",
"designation": "unenrollment"
}
},
{
"identifiers": {
"pk": "c62ac2a4-2735-4a0f-abd0-8523d68c1209",
"name": "default-unenrollment-user-delete"
},
"model": "passbook_stages_user_delete.userdeletestage",
"attrs": {}
},
{
"identifiers": {
"pk": "eb9aff2b-b95d-40b3-ad08-233aa77bbcf3",
"target": "59a576ce-2f23-4a63-b63a-d18dc7e550f5",
"stage": "c62ac2a4-2735-4a0f-abd0-8523d68c1209",
"order": 0
},
"model": "passbook_flows.flowstagebinding",
"attrs": {
"re_evaluate_policies": false
}
}
]
}

View File

@ -10,8 +10,7 @@ nav:
- Kubernetes: installation/kubernetes.md - Kubernetes: installation/kubernetes.md
- Flows: - Flows:
Overview: flow/flows.md Overview: flow/flows.md
Examples: Examples: flow/examples/examples.md
- Login: flow/examples/login.md
- Stages: - Stages:
- Captcha Stage: flow/stages/captcha/index.md - Captcha Stage: flow/stages/captcha/index.md
- Dummy Stage: flow/stages/dummy/index.md - Dummy Stage: flow/stages/dummy/index.md