From 4d12a98c5dcc46bca3663e153c4577d4e9146e1c Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Mon, 28 Nov 2022 12:10:53 +0100 Subject: [PATCH 1/4] root: rework and expand security policy Signed-off-by: Jens Langhammer --- CODE_OF_CONDUCT.md | 32 +++++++++--------- CONTRIBUTING.md | 57 +++++++++++++++++--------------- README.md | 8 ++--- SECURITY.md | 38 +++++++++++++++++---- website/docs/security/policy.mdx | 5 +++ website/sidebars.js | 10 ++++++ 6 files changed, 97 insertions(+), 53 deletions(-) create mode 100644 website/docs/security/policy.mdx diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 9341f9f58..83738fbc2 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -17,24 +17,24 @@ diverse, inclusive, and healthy community. Examples of behavior that contributes to a positive environment for our community include: -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, - and learning from the experience -* Focusing on what is best not just for us as individuals, but for the - overall community +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the + overall community Examples of unacceptable behavior include: -* The use of sexualized language or imagery, and sexual attention or - advances of any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email - address, without their explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting +- The use of sexualized language or imagery, and sexual attention or + advances of any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email + address, without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting ## Enforcement Responsibilities @@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban. ### 4. Permanent Ban **Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an +standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. **Consequence**: A permanent ban from any sort of public interaction within diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ce156ab6b..1f5c5f215 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,19 +11,22 @@ The following is a set of guidelines for contributing to authentik and its compo [I don't want to read this whole thing, I just have a question!!!](#i-dont-want-to-read-this-whole-thing-i-just-have-a-question) [What should I know before I get started?](#what-should-i-know-before-i-get-started) - * [The components](#the-components) - * [authentik's structure](#authentiks-structure) + +- [The components](#the-components) +- [authentik's structure](#authentiks-structure) [How Can I Contribute?](#how-can-i-contribute) - * [Reporting Bugs](#reporting-bugs) - * [Suggesting Enhancements](#suggesting-enhancements) - * [Your First Code Contribution](#your-first-code-contribution) - * [Pull Requests](#pull-requests) + +- [Reporting Bugs](#reporting-bugs) +- [Suggesting Enhancements](#suggesting-enhancements) +- [Your First Code Contribution](#your-first-code-contribution) +- [Pull Requests](#pull-requests) [Styleguides](#styleguides) - * [Git Commit Messages](#git-commit-messages) - * [Python Styleguide](#python-styleguide) - * [Documentation Styleguide](#documentation-styleguide) + +- [Git Commit Messages](#git-commit-messages) +- [Python Styleguide](#python-styleguide) +- [Documentation Styleguide](#documentation-styleguide) ## Code of Conduct @@ -39,11 +42,11 @@ Either [create a question on GitHub](https://github.com/goauthentik/authentik/is authentik consists of a few larger components: -- *authentik* the actual application server, is described below. -- *outpost-proxy* is a Go application based on a forked version of oauth2_proxy, which does identity-aware reverse proxying. -- *outpost-ldap* is a Go LDAP server that uses the *authentik* application server as its backend -- *web* is the web frontend, both for administrating and using authentik. It is written in TypeScript using lit-html and the PatternFly CSS Library. -- *website* is the Website/documentation, which uses docusaurus. +- _authentik_ the actual application server, is described below. +- _outpost-proxy_ is a Go application based on a forked version of oauth2_proxy, which does identity-aware reverse proxying. +- _outpost-ldap_ is a Go LDAP server that uses the _authentik_ application server as its backend +- _web_ is the web frontend, both for administrating and using authentik. It is written in TypeScript using lit-html and the PatternFly CSS Library. +- _website_ is the Website/documentation, which uses docusaurus. ### authentik's structure @@ -137,10 +140,10 @@ This is documented in the [developer docs](https://goauthentik.io/developer-docs The process described here has several goals: -- Maintain authentik's quality -- Fix problems that are important to users -- Engage the community in working toward the best possible authentik -- Enable a sustainable system for authentik's maintainers to review contributions +- Maintain authentik's quality +- Fix problems that are important to users +- Engage the community in working toward the best possible authentik +- Enable a sustainable system for authentik's maintainers to review contributions Please follow these steps to have your contribution considered by the maintainers: @@ -154,10 +157,10 @@ While the prerequisites above must be satisfied prior to having your pull reques ### Git Commit Messages -* Use the format of `: ` - - See [here](#authentik-packages) for `package` - - Example: `providers/saml2: fix parsing of requests` -* Reference issues and pull requests liberally after the first line +- Use the format of `: ` + - See [here](#authentik-packages) for `package` + - Example: `providers/saml2: fix parsing of requests` +- Reference issues and pull requests liberally after the first line ### Python Styleguide @@ -165,11 +168,11 @@ All Python code is linted with [black](https://black.readthedocs.io/en/stable/), authentik runs on Python 3.9 at the time of writing this. -* Use native type-annotations wherever possible. -* Add meaningful docstrings when possible. -* Ensure any database migrations work properly from the last stable version (this is checked via CI) -* If your code changes central functions, make sure nothing else is broken. +- Use native type-annotations wherever possible. +- Add meaningful docstrings when possible. +- Ensure any database migrations work properly from the last stable version (this is checked via CI) +- If your code changes central functions, make sure nothing else is broken. ### Documentation Styleguide -* Use [MDX](https://mdxjs.com/) whenever appropriate. +- Use [MDX](https://mdxjs.com/) whenever appropriate. diff --git a/README.md b/README.md index d0fcef18b..784dbc04b 100644 --- a/README.md +++ b/README.md @@ -25,10 +25,10 @@ For bigger setups, there is a Helm Chart [here](https://github.com/goauthentik/h ## Screenshots -Light | Dark ---- | --- -![](https://goauthentik.io/img/screen_apps_light.jpg) | ![](https://goauthentik.io/img/screen_apps_dark.jpg) -![](https://goauthentik.io/img/screen_admin_light.jpg) | ![](https://goauthentik.io/img/screen_admin_dark.jpg) +| Light | Dark | +| ------------------------------------------------------ | ----------------------------------------------------- | +| ![](https://goauthentik.io/img/screen_apps_light.jpg) | ![](https://goauthentik.io/img/screen_apps_dark.jpg) | +| ![](https://goauthentik.io/img/screen_admin_light.jpg) | ![](https://goauthentik.io/img/screen_admin_dark.jpg) | ## Development diff --git a/SECURITY.md b/SECURITY.md index b319e1ae1..642fcdbdc 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,17 +1,43 @@ -# Security Policy +Authentik takes security very seriously. We follow the rules of [responsible disclosure](https://en.wikipedia.org/wiki/Responsible_disclosure), and we urge our community to do so as well, instead of reporting vulnerabilities publicly. This allows us to patch the issue quickly, announce it's existence and release the fixed version. ## Supported Versions (.x being the latest patch release for each version) -| Version | Supported | -| ---------- | ------------------ | -| 2022.10.x | :white_check_mark: | -| 2022.11.x | :white_check_mark: | +| Version | Supported | +| --------- | ------------------ | +| 2022.10.x | :white_check_mark: | +| 2022.11.x | :white_check_mark: | ## Reporting a Vulnerability -To report a vulnerability, send an email to [security@goauthentik.io](mailto:security@goauthentik.io) +To report a vulnerability, send an email to [security@goauthentik.io](mailto:security@goauthentik.io). Be sure to include relevant information like which version you've found the issue in, instructions on how to reproduce the issue, and anything else that might make it easier for us to find the bug. + +## Criticality levels + +### High + +- Authorization bypass +- Circumvention of policies + +### Moderate + +- Denial-of-Service attacks + +### Low + +- Unvalidated redirects +- Issues requiring uncommon setups + +## Disclosure process + +1. Issue is reported via Email as listed above. +2. The authentik Security team will try to reproduce the issue and ask for more information if required. +3. A criticality level is assigned. +4. A fix is created, and if possible tested by the issue reporter. +5. The fix is backported to other supported versions, and if possible a workaround for other versions is created. +6. An announcement is sent out with a fixed release date and criticality level of the issue. The announcement will be sent at least 24 hours before the release of the fix +7. The fixed version is released for the supported versions. ## Getting security notifications diff --git a/website/docs/security/policy.mdx b/website/docs/security/policy.mdx new file mode 100644 index 000000000..d4e100575 --- /dev/null +++ b/website/docs/security/policy.mdx @@ -0,0 +1,5 @@ +# Security Policy + +import SecurityPolicy from "../../../SECURITY.md"; + + diff --git a/website/sidebars.js b/website/sidebars.js index 29dfdda6c..2c96538d8 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -282,5 +282,15 @@ module.exports = { "troubleshooting/missing_admin_group", ], }, + { + type: "category", + label: "Security", + link: { + type: "generated-index", + title: "Security", + slug: "security", + }, + items: ["security/policy"], + }, ], }; From 17ee076f3d1f60ba22cb4b21ba24a78b6f961595 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Tue, 29 Nov 2022 00:05:39 +0100 Subject: [PATCH 2/4] root: include security policy in website container Signed-off-by: Jens Langhammer --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 816475a76..3daf391c7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,6 +3,7 @@ FROM --platform=${BUILDPLATFORM} docker.io/node:18 as website-builder COPY ./website /work/website/ COPY ./blueprints /work/blueprints/ +COPY ./SECURITY.md /work/ ENV NODE_ENV=production WORKDIR /work/website From e1a6dede54eaeda6887ebf11d78251f1db3cb15c Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 1 Dec 2022 10:41:26 +0200 Subject: [PATCH 3/4] *: backport CVE-2022-46145 fix Signed-off-by: Jens Langhammer --- authentik/flows/api/flows.py | 1 + authentik/flows/exceptions.py | 10 +++-- .../migrations/0024_flow_authentication.py | 27 ++++++++++++ authentik/flows/models.py | 15 +++++++ authentik/flows/planner.py | 28 +++++++++++- authentik/flows/tests/test_planner.py | 29 +++++++++++- .../default/0-flow-password-change.yaml | 1 + .../10-flow-default-authentication-flow.yaml | 1 + .../10-flow-default-invalidation-flow.yaml | 1 + ...ow-default-authenticator-static-setup.yaml | 1 + ...flow-default-authenticator-totp-setup.yaml | 1 + ...-default-authenticator-webauthn-setup.yaml | 1 + ...ovider-authorization-explicit-consent.yaml | 1 + ...ovider-authorization-implicit-consent.yaml | 1 + ...20-flow-default-source-authentication.yaml | 1 + .../20-flow-default-source-enrollment.yaml | 1 + ...low-default-source-pre-authentication.yaml | 1 + .../30-flow-default-user-settings-flow.yaml | 1 + .../example/flows-enrollment-2-stage.yaml | 1 + .../flows-enrollment-email-verification.yaml | 1 + blueprints/example/flows-login-2fa.yaml | 1 + .../flows-login-conditional-captcha.yaml | 1 + .../flows-recovery-email-verification.yaml | 1 + blueprints/example/flows-unenrollment.yaml | 1 + schema.yml | 22 ++++++++++ web/src/admin/flows/FlowForm.ts | 44 +++++++++++++++++++ website/docs/security/CVE-2022-46145.md | 19 ++++++++ website/sidebars.js | 2 +- 28 files changed, 207 insertions(+), 8 deletions(-) create mode 100644 authentik/flows/migrations/0024_flow_authentication.py create mode 100644 website/docs/security/CVE-2022-46145.md diff --git a/authentik/flows/api/flows.py b/authentik/flows/api/flows.py index 9838dd114..0566bddf2 100644 --- a/authentik/flows/api/flows.py +++ b/authentik/flows/api/flows.py @@ -71,6 +71,7 @@ class FlowSerializer(ModelSerializer): "export_url", "layout", "denied_action", + "authentication", ] extra_kwargs = { "background": {"read_only": True}, diff --git a/authentik/flows/exceptions.py b/authentik/flows/exceptions.py index 6ea03429e..cf38d9a50 100644 --- a/authentik/flows/exceptions.py +++ b/authentik/flows/exceptions.py @@ -1,4 +1,6 @@ """flow exceptions""" +from typing import Optional + from django.utils.translation import gettext_lazy as _ from authentik.lib.sentry import SentryIgnoredException @@ -6,15 +8,15 @@ from authentik.policies.types import PolicyResult class FlowNonApplicableException(SentryIgnoredException): - """Flow does not apply to current user (denied by policy).""" + """Flow does not apply to current user (denied by policy, or otherwise).""" - policy_result: PolicyResult + policy_result: Optional[PolicyResult] = None @property def messages(self) -> str: """Get messages from policy result, fallback to generic reason""" - if len(self.policy_result.messages) < 1: - return _("Flow does not apply to current user (denied by policy).") + if not self.policy_result or len(self.policy_result.messages) < 1: + return _("Flow does not apply to current user.") return "\n".join(self.policy_result.messages) diff --git a/authentik/flows/migrations/0024_flow_authentication.py b/authentik/flows/migrations/0024_flow_authentication.py new file mode 100644 index 000000000..cbfc01971 --- /dev/null +++ b/authentik/flows/migrations/0024_flow_authentication.py @@ -0,0 +1,27 @@ +# Generated by Django 4.1.3 on 2022-11-30 09:04 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("authentik_flows", "0023_flow_denied_action"), + ] + + operations = [ + migrations.AddField( + model_name="flow", + name="authentication", + field=models.TextField( + choices=[ + ("none", "None"), + ("require_authenticated", "Require Authenticated"), + ("require_unauthenticated", "Require Unauthenticated"), + ("require_superuser", "Require Superuser"), + ], + default="none", + help_text="Required level of authentication and authorization to access a flow.", + ), + ), + ] diff --git a/authentik/flows/models.py b/authentik/flows/models.py index 6c7edc37b..a837b7dae 100644 --- a/authentik/flows/models.py +++ b/authentik/flows/models.py @@ -23,6 +23,15 @@ if TYPE_CHECKING: LOGGER = get_logger() +class FlowAuthenticationRequirement(models.TextChoices): + """Required level of authentication and authorization to access a flow""" + + NONE = "none" + REQUIRE_AUTHENTICATED = "require_authenticated" + REQUIRE_UNAUTHENTICATED = "require_unauthenticated" + REQUIRE_SUPERUSER = "require_superuser" + + class NotConfiguredAction(models.TextChoices): """Decides how the FlowExecutor should proceed when a stage isn't configured""" @@ -152,6 +161,12 @@ class Flow(SerializerModel, PolicyBindingModel): help_text=_("Configure what should happen when a flow denies access to a user."), ) + authentication = models.TextField( + choices=FlowAuthenticationRequirement.choices, + default=FlowAuthenticationRequirement.NONE, + help_text=_("Required level of authentication and authorization to access a flow."), + ) + @property def background_url(self) -> str: """Get the URL to the background image. If the name is /static or starts with http diff --git a/authentik/flows/planner.py b/authentik/flows/planner.py index 547803dd2..367d7574b 100644 --- a/authentik/flows/planner.py +++ b/authentik/flows/planner.py @@ -13,7 +13,14 @@ from authentik.events.models import cleanse_dict from authentik.flows.apps import HIST_FLOWS_PLAN_TIME from authentik.flows.exceptions import EmptyFlowException, FlowNonApplicableException from authentik.flows.markers import ReevaluateMarker, StageMarker -from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding, Stage, in_memory_stage +from authentik.flows.models import ( + Flow, + FlowAuthenticationRequirement, + FlowDesignation, + FlowStageBinding, + Stage, + in_memory_stage, +) from authentik.lib.config import CONFIG from authentik.policies.engine import PolicyEngine @@ -117,11 +124,30 @@ class FlowPlanner: self.flow = flow self._logger = get_logger().bind(flow_slug=flow.slug) + def _check_authentication(self, request: HttpRequest): + """Check the flow's authentication level is matched by `request`""" + if ( + self.flow.authentication == FlowAuthenticationRequirement.REQUIRE_AUTHENTICATED + and not request.user.is_authenticated + ): + raise FlowNonApplicableException() + if ( + self.flow.authentication == FlowAuthenticationRequirement.REQUIRE_UNAUTHENTICATED + and request.user.is_authenticated + ): + raise FlowNonApplicableException() + if ( + self.flow.authentication == FlowAuthenticationRequirement.REQUIRE_SUPERUSER + and not request.user.is_superuser + ): + raise FlowNonApplicableException() + def plan( self, request: HttpRequest, default_context: Optional[dict[str, Any]] = None ) -> FlowPlan: """Check each of the flows' policies, check policies for each stage with PolicyBinding and return ordered list""" + self._check_authentication(request) with Hub.current.start_span( op="authentik.flow.planner.plan", description=self.flow.slug ) as span: diff --git a/authentik/flows/tests/test_planner.py b/authentik/flows/tests/test_planner.py index e7da06e0a..790f5bba4 100644 --- a/authentik/flows/tests/test_planner.py +++ b/authentik/flows/tests/test_planner.py @@ -1,6 +1,7 @@ """flow planner tests""" from unittest.mock import MagicMock, Mock, PropertyMock, patch +from django.contrib.auth.models import AnonymousUser from django.contrib.sessions.middleware import SessionMiddleware from django.core.cache import cache from django.test import RequestFactory, TestCase @@ -8,10 +9,10 @@ from django.urls import reverse from guardian.shortcuts import get_anonymous_user from authentik.core.models import User -from authentik.core.tests.utils import create_test_flow +from authentik.core.tests.utils import create_test_admin_user, create_test_flow from authentik.flows.exceptions import EmptyFlowException, FlowNonApplicableException from authentik.flows.markers import ReevaluateMarker, StageMarker -from authentik.flows.models import FlowDesignation, FlowStageBinding +from authentik.flows.models import FlowAuthenticationRequirement, FlowDesignation, FlowStageBinding from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlanner, cache_key from authentik.lib.tests.utils import dummy_get_response from authentik.policies.dummy.models import DummyPolicy @@ -43,6 +44,30 @@ class TestFlowPlanner(TestCase): planner = FlowPlanner(flow) planner.plan(request) + def test_authentication(self): + """Test flow authentication""" + flow = create_test_flow() + flow.authentication = FlowAuthenticationRequirement.NONE + request = self.request_factory.get( + reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}), + ) + request.user = AnonymousUser() + planner = FlowPlanner(flow) + planner.allow_empty_flows = True + planner.plan(request) + + with self.assertRaises(FlowNonApplicableException): + flow.authentication = FlowAuthenticationRequirement.REQUIRE_AUTHENTICATED + FlowPlanner(flow).plan(request) + with self.assertRaises(FlowNonApplicableException): + flow.authentication = FlowAuthenticationRequirement.REQUIRE_SUPERUSER + FlowPlanner(flow).plan(request) + + request.user = create_test_admin_user() + planner = FlowPlanner(flow) + planner.allow_empty_flows = True + planner.plan(request) + @patch( "authentik.policies.engine.PolicyEngine.result", POLICY_RETURN_FALSE, diff --git a/blueprints/default/0-flow-password-change.yaml b/blueprints/default/0-flow-password-change.yaml index fd87049f8..60a4d72e7 100644 --- a/blueprints/default/0-flow-password-change.yaml +++ b/blueprints/default/0-flow-password-change.yaml @@ -6,6 +6,7 @@ entries: designation: stage_configuration name: Change Password title: Change password + authentication: require_authenticated identifiers: slug: default-password-change model: authentik_flows.flow diff --git a/blueprints/default/10-flow-default-authentication-flow.yaml b/blueprints/default/10-flow-default-authentication-flow.yaml index 9afbf6605..37192356b 100644 --- a/blueprints/default/10-flow-default-authentication-flow.yaml +++ b/blueprints/default/10-flow-default-authentication-flow.yaml @@ -11,6 +11,7 @@ entries: designation: authentication name: Welcome to authentik! title: Welcome to authentik! + authentication: require_unauthenticated identifiers: slug: default-authentication-flow model: authentik_flows.flow diff --git a/blueprints/default/10-flow-default-invalidation-flow.yaml b/blueprints/default/10-flow-default-invalidation-flow.yaml index 80f8e729c..a77b62852 100644 --- a/blueprints/default/10-flow-default-invalidation-flow.yaml +++ b/blueprints/default/10-flow-default-invalidation-flow.yaml @@ -6,6 +6,7 @@ entries: designation: invalidation name: Logout title: Default Invalidation Flow + authentication: require_authenticated identifiers: slug: default-invalidation-flow model: authentik_flows.flow diff --git a/blueprints/default/20-flow-default-authenticator-static-setup.yaml b/blueprints/default/20-flow-default-authenticator-static-setup.yaml index 7f3173e24..190ca9098 100644 --- a/blueprints/default/20-flow-default-authenticator-static-setup.yaml +++ b/blueprints/default/20-flow-default-authenticator-static-setup.yaml @@ -6,6 +6,7 @@ entries: designation: stage_configuration name: default-authenticator-static-setup title: Setup Static OTP Tokens + authentication: require_authenticated identifiers: slug: default-authenticator-static-setup model: authentik_flows.flow diff --git a/blueprints/default/20-flow-default-authenticator-totp-setup.yaml b/blueprints/default/20-flow-default-authenticator-totp-setup.yaml index d701dd0ea..b97f565e3 100644 --- a/blueprints/default/20-flow-default-authenticator-totp-setup.yaml +++ b/blueprints/default/20-flow-default-authenticator-totp-setup.yaml @@ -6,6 +6,7 @@ entries: designation: stage_configuration name: default-authenticator-totp-setup title: Setup Two-Factor authentication + authentication: require_authenticated identifiers: slug: default-authenticator-totp-setup model: authentik_flows.flow diff --git a/blueprints/default/20-flow-default-authenticator-webauthn-setup.yaml b/blueprints/default/20-flow-default-authenticator-webauthn-setup.yaml index 26b5a64c7..da0abf7be 100644 --- a/blueprints/default/20-flow-default-authenticator-webauthn-setup.yaml +++ b/blueprints/default/20-flow-default-authenticator-webauthn-setup.yaml @@ -6,6 +6,7 @@ entries: designation: stage_configuration name: default-authenticator-webauthn-setup title: Setup WebAuthn + authentication: require_authenticated identifiers: slug: default-authenticator-webauthn-setup model: authentik_flows.flow diff --git a/blueprints/default/20-flow-default-provider-authorization-explicit-consent.yaml b/blueprints/default/20-flow-default-provider-authorization-explicit-consent.yaml index 84dd76d25..452102ab8 100644 --- a/blueprints/default/20-flow-default-provider-authorization-explicit-consent.yaml +++ b/blueprints/default/20-flow-default-provider-authorization-explicit-consent.yaml @@ -6,6 +6,7 @@ entries: designation: authorization name: Authorize Application title: Redirecting to %(app)s + authentication: require_authenticated identifiers: slug: default-provider-authorization-explicit-consent model: authentik_flows.flow diff --git a/blueprints/default/20-flow-default-provider-authorization-implicit-consent.yaml b/blueprints/default/20-flow-default-provider-authorization-implicit-consent.yaml index b609afdd9..0cec0acfc 100644 --- a/blueprints/default/20-flow-default-provider-authorization-implicit-consent.yaml +++ b/blueprints/default/20-flow-default-provider-authorization-implicit-consent.yaml @@ -6,6 +6,7 @@ entries: designation: authorization name: Authorize Application title: Redirecting to %(app)s + authentication: require_authenticated identifiers: slug: default-provider-authorization-implicit-consent model: authentik_flows.flow diff --git a/blueprints/default/20-flow-default-source-authentication.yaml b/blueprints/default/20-flow-default-source-authentication.yaml index 7b630343b..9ece1a1ec 100644 --- a/blueprints/default/20-flow-default-source-authentication.yaml +++ b/blueprints/default/20-flow-default-source-authentication.yaml @@ -6,6 +6,7 @@ entries: designation: authentication name: Welcome to authentik! title: Welcome to authentik! + authentication: require_unauthenticated identifiers: slug: default-source-authentication model: authentik_flows.flow diff --git a/blueprints/default/20-flow-default-source-enrollment.yaml b/blueprints/default/20-flow-default-source-enrollment.yaml index 52e55b807..e354104db 100644 --- a/blueprints/default/20-flow-default-source-enrollment.yaml +++ b/blueprints/default/20-flow-default-source-enrollment.yaml @@ -6,6 +6,7 @@ entries: designation: enrollment name: Welcome to authentik! Please select a username. title: Welcome to authentik! Please select a username. + authentication: none identifiers: slug: default-source-enrollment model: authentik_flows.flow diff --git a/blueprints/default/20-flow-default-source-pre-authentication.yaml b/blueprints/default/20-flow-default-source-pre-authentication.yaml index c98843de0..0d6040d49 100644 --- a/blueprints/default/20-flow-default-source-pre-authentication.yaml +++ b/blueprints/default/20-flow-default-source-pre-authentication.yaml @@ -6,6 +6,7 @@ entries: designation: stage_configuration name: Pre-Authentication title: Pre-authentication + authentication: none identifiers: slug: default-source-pre-authentication model: authentik_flows.flow diff --git a/blueprints/default/30-flow-default-user-settings-flow.yaml b/blueprints/default/30-flow-default-user-settings-flow.yaml index 8254d4865..34a593be7 100644 --- a/blueprints/default/30-flow-default-user-settings-flow.yaml +++ b/blueprints/default/30-flow-default-user-settings-flow.yaml @@ -6,6 +6,7 @@ entries: designation: stage_configuration name: User settings title: Update your info + authentication: require_authenticated identifiers: slug: default-user-settings-flow model: authentik_flows.flow diff --git a/blueprints/example/flows-enrollment-2-stage.yaml b/blueprints/example/flows-enrollment-2-stage.yaml index 97fb39ef0..670befc99 100644 --- a/blueprints/example/flows-enrollment-2-stage.yaml +++ b/blueprints/example/flows-enrollment-2-stage.yaml @@ -12,6 +12,7 @@ entries: name: Default enrollment Flow title: Welcome to authentik! designation: enrollment + authentication: require_unauthenticated - identifiers: field_key: username label: Username diff --git a/blueprints/example/flows-enrollment-email-verification.yaml b/blueprints/example/flows-enrollment-email-verification.yaml index ac051202b..3528906a1 100644 --- a/blueprints/example/flows-enrollment-email-verification.yaml +++ b/blueprints/example/flows-enrollment-email-verification.yaml @@ -12,6 +12,7 @@ entries: name: Default enrollment Flow title: Welcome to authentik! designation: enrollment + authentication: require_unauthenticated - identifiers: field_key: username label: Username diff --git a/blueprints/example/flows-login-2fa.yaml b/blueprints/example/flows-login-2fa.yaml index 903daa5aa..fa316caa9 100644 --- a/blueprints/example/flows-login-2fa.yaml +++ b/blueprints/example/flows-login-2fa.yaml @@ -12,6 +12,7 @@ entries: name: Default Authentication Flow title: Welcome to authentik! designation: authentication + authentication: require_unauthenticated - identifiers: name: test-not-app-password id: test-not-app-password diff --git a/blueprints/example/flows-login-conditional-captcha.yaml b/blueprints/example/flows-login-conditional-captcha.yaml index 2d727acaf..f5eb6ca1b 100644 --- a/blueprints/example/flows-login-conditional-captcha.yaml +++ b/blueprints/example/flows-login-conditional-captcha.yaml @@ -12,6 +12,7 @@ entries: name: Default Authentication Flow title: Welcome to authentik! designation: authentication + authentication: require_unauthenticated - identifiers: name: default-authentication-login id: default-authentication-login diff --git a/blueprints/example/flows-recovery-email-verification.yaml b/blueprints/example/flows-recovery-email-verification.yaml index 9217fa762..8b1994cc8 100644 --- a/blueprints/example/flows-recovery-email-verification.yaml +++ b/blueprints/example/flows-recovery-email-verification.yaml @@ -12,6 +12,7 @@ entries: name: Default recovery flow title: Reset your password designation: recovery + authentication: require_unauthenticated - identifiers: field_key: password label: Password diff --git a/blueprints/example/flows-unenrollment.yaml b/blueprints/example/flows-unenrollment.yaml index 898405cd6..5d29dd2b9 100644 --- a/blueprints/example/flows-unenrollment.yaml +++ b/blueprints/example/flows-unenrollment.yaml @@ -12,6 +12,7 @@ entries: name: Default unenrollment flow title: Delete your account designation: unenrollment + authentication: require_authenticated - identifiers: name: default-unenrollment-user-delete id: default-unenrollment-user-delete diff --git a/schema.yml b/schema.yml index 5537db567..2a02e8407 100644 --- a/schema.yml +++ b/schema.yml @@ -25269,6 +25269,13 @@ components: - last_used - user - user_agent + AuthenticationEnum: + enum: + - none + - require_authenticated + - require_unauthenticated + - require_superuser + type: string AuthenticatorAttachmentEnum: enum: - platform @@ -27578,6 +27585,11 @@ components: - $ref: '#/components/schemas/DeniedActionEnum' description: Configure what should happen when a flow denies access to a user. + authentication: + allOf: + - $ref: '#/components/schemas/AuthenticationEnum' + description: Required level of authentication and authorization to access + a flow. required: - background - cache_count @@ -27774,6 +27786,11 @@ components: - $ref: '#/components/schemas/DeniedActionEnum' description: Configure what should happen when a flow denies access to a user. + authentication: + allOf: + - $ref: '#/components/schemas/AuthenticationEnum' + description: Required level of authentication and authorization to access + a flow. required: - designation - name @@ -33651,6 +33668,11 @@ components: - $ref: '#/components/schemas/DeniedActionEnum' description: Configure what should happen when a flow denies access to a user. + authentication: + allOf: + - $ref: '#/components/schemas/AuthenticationEnum' + description: Required level of authentication and authorization to access + a flow. PatchedFlowStageBindingRequest: type: object description: FlowStageBinding Serializer diff --git a/web/src/admin/flows/FlowForm.ts b/web/src/admin/flows/FlowForm.ts index e205eb541..3db763b8f 100644 --- a/web/src/admin/flows/FlowForm.ts +++ b/web/src/admin/flows/FlowForm.ts @@ -1,4 +1,5 @@ import { DesignationToLabel, LayoutToLabel } from "@goauthentik/admin/flows/utils"; +import { AuthenticationEnum } from "@goauthentik/api/dist/models/AuthenticationEnum"; import { DEFAULT_CONFIG, config } from "@goauthentik/common/api/config"; import { first } from "@goauthentik/common/utils"; import "@goauthentik/elements/forms/HorizontalFormElement"; @@ -141,6 +142,37 @@ export class FlowForm extends ModelForm { `; } + renderAuthentication(): TemplateResult { + return html` + + + + + `; + } + renderLayout(): TemplateResult { return html` + + +

+ ${t`Required authentication level for this flow.`} +

+
Date: Thu, 1 Dec 2022 10:41:29 +0200 Subject: [PATCH 4/4] release: 2022.11.2 --- .bumpversion.cfg | 2 +- authentik/__init__.py | 2 +- docker-compose.yml | 4 ++-- internal/constants/constants.go | 2 +- pyproject.toml | 2 +- schema.yml | 2 +- web/src/common/constants.ts | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index b3f57b7fa..d72fd44a8 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 2022.11.1 +current_version = 2022.11.2 tag = True commit = True parse = (?P\d+)\.(?P\d+)\.(?P\d+) diff --git a/authentik/__init__.py b/authentik/__init__.py index 00ddfc92c..8e03ee834 100644 --- a/authentik/__init__.py +++ b/authentik/__init__.py @@ -2,7 +2,7 @@ from os import environ from typing import Optional -__version__ = "2022.11.1" +__version__ = "2022.11.2" ENV_GIT_HASH_KEY = "GIT_BUILD_HASH" diff --git a/docker-compose.yml b/docker-compose.yml index 74a30e38a..cd8c4d211 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,7 +32,7 @@ services: volumes: - redis:/data server: - image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.11.1} + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.11.2} restart: unless-stopped command: server environment: @@ -52,7 +52,7 @@ services: - "0.0.0.0:${AUTHENTIK_PORT_HTTP:-9000}:9000" - "0.0.0.0:${AUTHENTIK_PORT_HTTPS:-9443}:9443" worker: - image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.11.1} + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.11.2} restart: unless-stopped command: worker environment: diff --git a/internal/constants/constants.go b/internal/constants/constants.go index e2eeb176e..6e602dffd 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -29,4 +29,4 @@ func UserAgent() string { return fmt.Sprintf("authentik@%s", FullVersion()) } -const VERSION = "2022.11.1" +const VERSION = "2022.11.2" diff --git a/pyproject.toml b/pyproject.toml index e2e93600e..89758bb68 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -100,7 +100,7 @@ addopts = "-p no:celery --junitxml=unittest.xml" [tool.poetry] name = "authentik" -version = "2022.11.1" +version = "2022.11.2" description = "" authors = ["authentik Team "] diff --git a/schema.yml b/schema.yml index 2a02e8407..e06ebbbd4 100644 --- a/schema.yml +++ b/schema.yml @@ -1,7 +1,7 @@ openapi: 3.0.3 info: title: authentik - version: 2022.11.1 + version: 2022.11.2 description: Making authentication simple. contact: email: hello@goauthentik.io diff --git a/web/src/common/constants.ts b/web/src/common/constants.ts index 7713cdd34..a1477f8ef 100644 --- a/web/src/common/constants.ts +++ b/web/src/common/constants.ts @@ -3,7 +3,7 @@ export const SUCCESS_CLASS = "pf-m-success"; export const ERROR_CLASS = "pf-m-danger"; export const PROGRESS_CLASS = "pf-m-in-progress"; export const CURRENT_CLASS = "pf-m-current"; -export const VERSION = "2022.11.1"; +export const VERSION = "2022.11.2"; export const TITLE_DEFAULT = "authentik"; export const ROUTE_SEPARATOR = ";";