From 24e8915e0a40098dd8efe2b3b420a37f2f7d31ec Mon Sep 17 00:00:00 2001 From: Jens L Date: Wed, 4 Jan 2023 22:04:16 +0100 Subject: [PATCH 1/6] providers/proxy: add tests for proxy basic auth (#4357) * add tests for proxy basic auth Signed-off-by: Jens Langhammer * stop bandit from complaining Signed-off-by: Jens Langhammer * add API tests Signed-off-by: Jens Langhammer * more tests Signed-off-by: Jens Langhammer Signed-off-by: Jens Langhammer --- authentik/providers/proxy/api.py | 19 ++++- authentik/providers/proxy/tests.py | 122 +++++++++++++++++++++++++++++ tests/e2e/test_provider_ldap.py | 1 - tests/e2e/test_provider_proxy.py | 74 +++++++++++++++++ 4 files changed, 212 insertions(+), 4 deletions(-) create mode 100644 authentik/providers/proxy/tests.py diff --git a/authentik/providers/proxy/api.py b/authentik/providers/proxy/api.py index 2561b4377..0054000f5 100644 --- a/authentik/providers/proxy/api.py +++ b/authentik/providers/proxy/api.py @@ -1,6 +1,7 @@ """ProxyProvider API Views""" from typing import Any, Optional +from django.utils.translation import gettext_lazy as _ from drf_spectacular.utils import extend_schema_field from rest_framework.exceptions import ValidationError from rest_framework.fields import CharField, ListField, ReadOnlyField, SerializerMethodField @@ -39,22 +40,34 @@ class ProxyProviderSerializer(ProviderSerializer): redirect_uris = CharField(read_only=True) outpost_set = ListField(child=CharField(), read_only=True, source="outpost_set.all") + def validate_basic_auth_enabled(self, value: bool) -> bool: + """Ensure user and password attributes are set""" + if value: + if ( + self.initial_data.get("basic_auth_password_attribute", "") == "" + or self.initial_data.get("basic_auth_user_attribute", "") == "" + ): + raise ValidationError( + _("User and password attributes must be set when basic auth is enabled.") + ) + return value + def validate(self, attrs) -> dict[Any, str]: """Check that internal_host is set when mode is Proxy""" if ( attrs.get("mode", ProxyMode.PROXY) == ProxyMode.PROXY and attrs.get("internal_host", "") == "" ): - raise ValidationError("Internal host cannot be empty when forward auth is disabled.") + raise ValidationError(_("Internal host cannot be empty when forward auth is disabled.")) return attrs - def create(self, validated_data): + def create(self, validated_data: dict): instance: ProxyProvider = super().create(validated_data) instance.set_oauth_defaults() instance.save() return instance - def update(self, instance: ProxyProvider, validated_data): + def update(self, instance: ProxyProvider, validated_data: dict): instance = super().update(instance, validated_data) instance.set_oauth_defaults() instance.save() diff --git a/authentik/providers/proxy/tests.py b/authentik/providers/proxy/tests.py new file mode 100644 index 000000000..76409df89 --- /dev/null +++ b/authentik/providers/proxy/tests.py @@ -0,0 +1,122 @@ +"""proxy provider tests""" +from django.urls import reverse +from rest_framework.test import APITestCase + +from authentik.core.tests.utils import create_test_admin_user, create_test_flow +from authentik.lib.generators import generate_id +from authentik.providers.oauth2.models import ClientTypes +from authentik.providers.proxy.models import ProxyMode, ProxyProvider + + +class ProxyProviderTests(APITestCase): + """proxy provider tests""" + + def setUp(self) -> None: + self.user = create_test_admin_user() + self.client.force_login(self.user) + + def test_basic_auth(self): + """Test basic_auth_enabled""" + response = self.client.post( + reverse("authentik_api:proxyprovider-list"), + { + "name": generate_id(), + "mode": ProxyMode.PROXY, + "authorization_flow": create_test_flow().pk.hex, + "external_host": "http://localhost", + "internal_host": "http://localhost", + "basic_auth_enabled": True, + "basic_auth_user_attribute": generate_id(), + "basic_auth_password_attribute": generate_id(), + }, + ) + self.assertEqual(response.status_code, 201) + + def test_basic_auth_invalid(self): + """Test basic_auth_enabled""" + response = self.client.post( + reverse("authentik_api:proxyprovider-list"), + { + "name": generate_id(), + "mode": ProxyMode.PROXY, + "authorization_flow": create_test_flow().pk.hex, + "external_host": "http://localhost", + "internal_host": "http://localhost", + "basic_auth_enabled": True, + }, + ) + self.assertEqual(response.status_code, 400) + self.assertJSONEqual( + response.content.decode(), + { + "basic_auth_enabled": [ + "User and password attributes must be set when basic auth is enabled." + ] + }, + ) + + def test_validate(self): + """Test validate""" + response = self.client.post( + reverse("authentik_api:proxyprovider-list"), + { + "name": generate_id(), + "mode": ProxyMode.PROXY, + "authorization_flow": create_test_flow().pk.hex, + "external_host": "http://localhost", + }, + ) + self.assertEqual(response.status_code, 400) + self.assertJSONEqual( + response.content.decode(), + {"non_field_errors": ["Internal host cannot be empty when forward auth is disabled."]}, + ) + + def test_create_defaults(self): + """Test create""" + name = generate_id() + response = self.client.post( + reverse("authentik_api:proxyprovider-list"), + { + "name": name, + "mode": ProxyMode.PROXY, + "authorization_flow": create_test_flow().pk.hex, + "external_host": "http://localhost", + "internal_host": "http://localhost", + }, + ) + self.assertEqual(response.status_code, 201) + provider: ProxyProvider = ProxyProvider.objects.get(name=name) + self.assertEqual(provider.client_type, ClientTypes.CONFIDENTIAL) + + def test_update_defaults(self): + """Test create""" + name = generate_id() + response = self.client.post( + reverse("authentik_api:proxyprovider-list"), + { + "name": name, + "mode": ProxyMode.PROXY, + "authorization_flow": create_test_flow().pk.hex, + "external_host": "http://localhost", + "internal_host": "http://localhost", + }, + ) + self.assertEqual(response.status_code, 201) + provider: ProxyProvider = ProxyProvider.objects.get(name=name) + self.assertEqual(provider.client_type, ClientTypes.CONFIDENTIAL) + provider.client_type = ClientTypes.PUBLIC + provider.save() + response = self.client.put( + reverse("authentik_api:proxyprovider-detail", kwargs={"pk": provider.pk}), + { + "name": name, + "mode": ProxyMode.PROXY, + "authorization_flow": create_test_flow().pk.hex, + "external_host": "http://localhost", + "internal_host": "http://localhost", + }, + ) + self.assertEqual(response.status_code, 200) + provider: ProxyProvider = ProxyProvider.objects.get(name=name) + self.assertEqual(provider.client_type, ClientTypes.CONFIDENTIAL) diff --git a/tests/e2e/test_provider_ldap.py b/tests/e2e/test_provider_ldap.py index dae09b742..cc4dce79a 100644 --- a/tests/e2e/test_provider_ldap.py +++ b/tests/e2e/test_provider_ldap.py @@ -47,7 +47,6 @@ class TestProviderLDAP(SeleniumTestCase): def _prepare(self) -> User: """prepare user, provider, app and container""" - # set additionalHeaders to test later self.user.attributes["extraAttribute"] = "bar" self.user.save() diff --git a/tests/e2e/test_provider_proxy.py b/tests/e2e/test_provider_proxy.py index 5ce1683b7..7ea0bf359 100644 --- a/tests/e2e/test_provider_proxy.py +++ b/tests/e2e/test_provider_proxy.py @@ -1,4 +1,5 @@ """Proxy and Outpost e2e tests""" +from base64 import b64encode from dataclasses import asdict from sys import platform from time import sleep @@ -14,6 +15,7 @@ from authentik import __version__ from authentik.blueprints.tests import apply_blueprint, reconcile_app from authentik.core.models import Application from authentik.flows.models import Flow +from authentik.lib.generators import generate_id from authentik.outposts.models import DockerServiceConnection, Outpost, OutpostConfig, OutpostType from authentik.outposts.tasks import outpost_local_connection from authentik.providers.proxy.models import ProxyProvider @@ -119,6 +121,78 @@ class TestProviderProxy(SeleniumTestCase): full_body_text = self.driver.find_element(By.CSS_SELECTOR, ".pf-c-title.pf-m-3xl").text self.assertIn("You've logged out of proxy.", full_body_text) + @retry() + @apply_blueprint( + "default/10-flow-default-authentication-flow.yaml", + "default/10-flow-default-invalidation-flow.yaml", + ) + @apply_blueprint( + "default/20-flow-default-provider-authorization-explicit-consent.yaml", + "default/20-flow-default-provider-authorization-implicit-consent.yaml", + ) + @apply_blueprint( + "system/providers-oauth2.yaml", + "system/providers-proxy.yaml", + ) + @reconcile_app("authentik_crypto") + def test_proxy_basic_auth(self): + """Test simple outpost setup with single provider""" + cred = generate_id() + attr = "basic-password" # nosec + self.user.attributes["basic-username"] = cred + self.user.attributes[attr] = cred + self.user.save() + + proxy: ProxyProvider = ProxyProvider.objects.create( + name="proxy_provider", + authorization_flow=Flow.objects.get( + slug="default-provider-authorization-implicit-consent" + ), + internal_host="http://localhost", + external_host="http://localhost:9000", + basic_auth_enabled=True, + basic_auth_user_attribute="basic-username", + basic_auth_password_attribute=attr, + ) + # Ensure OAuth2 Params are set + proxy.set_oauth_defaults() + proxy.save() + # we need to create an application to actually access the proxy + Application.objects.create(name="proxy", slug="proxy", provider=proxy) + outpost: Outpost = Outpost.objects.create( + name="proxy_outpost", + type=OutpostType.PROXY, + ) + outpost.providers.add(proxy) + outpost.build_user_permissions(outpost.user) + + self.proxy_container = self.start_proxy(outpost) + + # Wait until outpost healthcheck succeeds + healthcheck_retries = 0 + while healthcheck_retries < 50: + if len(outpost.state) > 0: + state = outpost.state[0] + if state.last_seen: + break + healthcheck_retries += 1 + sleep(0.5) + sleep(5) + + self.driver.get("http://localhost:9000") + self.login() + sleep(1) + + full_body_text = self.driver.find_element(By.CSS_SELECTOR, "pre").text + self.assertIn(f"X-Authentik-Username: {self.user.username}", full_body_text) + auth_header = b64encode(f"{cred}:{cred}".encode()).decode() + self.assertIn(f"Authorization: Basic {auth_header}", full_body_text) + + self.driver.get("http://localhost:9000/outpost.goauthentik.io/sign_out") + sleep(2) + full_body_text = self.driver.find_element(By.CSS_SELECTOR, ".pf-c-title.pf-m-3xl").text + self.assertIn("You've logged out of proxy.", full_body_text) + @skipUnless(platform.startswith("linux"), "requires local docker") class TestProviderProxyConnect(ChannelsLiveServerTestCase): From 730139e43cfa34abf948690e4de9fc5ccdcea69b Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 4 Jan 2023 22:26:55 +0100 Subject: [PATCH 2/6] *: improve general tests Signed-off-by: Jens Langhammer --- authentik/__init__.py | 4 +--- authentik/api/v3/config.py | 2 +- authentik/blueprints/tests/test_models.py | 2 +- authentik/blueprints/tests/test_oci.py | 12 ++++++------ authentik/core/tests/test_models.py | 2 +- authentik/lib/tests/test_serializer_model.py | 2 +- authentik/stages/user_write/tests.py | 4 ++++ 7 files changed, 15 insertions(+), 13 deletions(-) diff --git a/authentik/__init__.py b/authentik/__init__.py index a9e445136..7838c3acf 100644 --- a/authentik/__init__.py +++ b/authentik/__init__.py @@ -9,9 +9,7 @@ ENV_GIT_HASH_KEY = "GIT_BUILD_HASH" def get_build_hash(fallback: Optional[str] = None) -> str: """Get build hash""" build_hash = environ.get(ENV_GIT_HASH_KEY, fallback if fallback else "") - if build_hash == "" and fallback: - return fallback - return build_hash + return fallback if build_hash == "" and fallback else build_hash def get_full_version() -> str: diff --git a/authentik/api/v3/config.py b/authentik/api/v3/config.py index 952a6b637..e7f815b43 100644 --- a/authentik/api/v3/config.py +++ b/authentik/api/v3/config.py @@ -68,7 +68,7 @@ class ConfigView(APIView): caps.append(Capabilities.CAN_GEO_IP) if CONFIG.y_bool("impersonation"): caps.append(Capabilities.CAN_IMPERSONATE) - if settings.DEBUG: + if settings.DEBUG: # pragma: no cover caps.append(Capabilities.CAN_DEBUG) return caps diff --git a/authentik/blueprints/tests/test_models.py b/authentik/blueprints/tests/test_models.py index a27aa5493..718caa502 100644 --- a/authentik/blueprints/tests/test_models.py +++ b/authentik/blueprints/tests/test_models.py @@ -16,7 +16,7 @@ def serializer_tester_factory(test_model: Type[SerializerModel]) -> Callable: """Test serializer""" def tester(self: TestModels): - if test_model._meta.abstract: + if test_model._meta.abstract: # pragma: no cover return model_class = test_model() self.assertTrue(isinstance(model_class, SerializerModel)) diff --git a/authentik/blueprints/tests/test_oci.py b/authentik/blueprints/tests/test_oci.py index 80397b644..2eec45ea2 100644 --- a/authentik/blueprints/tests/test_oci.py +++ b/authentik/blueprints/tests/test_oci.py @@ -26,8 +26,8 @@ class TestBlueprintOCI(TransactionTestCase): self.assertEqual( BlueprintInstance( - path="https://ghcr.io/goauthentik/blueprints/test:latest" - ).retrieve_oci(), + path="oci://ghcr.io/goauthentik/blueprints/test:latest" + ).retrieve(), "foo", ) @@ -40,7 +40,7 @@ class TestBlueprintOCI(TransactionTestCase): with self.assertRaises(BlueprintRetrievalFailed): BlueprintInstance( - path="https://ghcr.io/goauthentik/blueprints/test:latest" + path="oci://ghcr.io/goauthentik/blueprints/test:latest" ).retrieve_oci() def test_manifests_error_response(self): @@ -53,7 +53,7 @@ class TestBlueprintOCI(TransactionTestCase): with self.assertRaises(BlueprintRetrievalFailed): BlueprintInstance( - path="https://ghcr.io/goauthentik/blueprints/test:latest" + path="oci://ghcr.io/goauthentik/blueprints/test:latest" ).retrieve_oci() def test_no_matching_blob(self): @@ -72,7 +72,7 @@ class TestBlueprintOCI(TransactionTestCase): ) with self.assertRaises(BlueprintRetrievalFailed): BlueprintInstance( - path="https://ghcr.io/goauthentik/blueprints/test:latest" + path="oci://ghcr.io/goauthentik/blueprints/test:latest" ).retrieve_oci() def test_blob_error(self): @@ -93,5 +93,5 @@ class TestBlueprintOCI(TransactionTestCase): with self.assertRaises(BlueprintRetrievalFailed): BlueprintInstance( - path="https://ghcr.io/goauthentik/blueprints/test:latest" + path="oci://ghcr.io/goauthentik/blueprints/test:latest" ).retrieve_oci() diff --git a/authentik/core/tests/test_models.py b/authentik/core/tests/test_models.py index 89cf30765..1cf2cff36 100644 --- a/authentik/core/tests/test_models.py +++ b/authentik/core/tests/test_models.py @@ -35,7 +35,7 @@ def source_tester_factory(test_model: type[Stage]) -> Callable: def tester(self: TestModels): model_class = None - if test_model._meta.abstract: + if test_model._meta.abstract: # pragma: no cover model_class = test_model.__bases__[0]() else: model_class = test_model() diff --git a/authentik/lib/tests/test_serializer_model.py b/authentik/lib/tests/test_serializer_model.py index 28b1db718..08907211e 100644 --- a/authentik/lib/tests/test_serializer_model.py +++ b/authentik/lib/tests/test_serializer_model.py @@ -19,7 +19,7 @@ def model_tester_factory(test_model: type[Stage]) -> Callable: def tester(self: TestModels): try: model_class = None - if test_model._meta.abstract: + if test_model._meta.abstract: # pragma: no cover return model_class = test_model() self.assertTrue(issubclass(model_class.serializer, BaseSerializer)) diff --git a/authentik/stages/user_write/tests.py b/authentik/stages/user_write/tests.py index 0bd101fd0..2c967300d 100644 --- a/authentik/stages/user_write/tests.py +++ b/authentik/stages/user_write/tests.py @@ -73,6 +73,9 @@ class TestUserWriteStage(FlowTestCase): "username": "test-user-new", "password": new_password, "attributes.some.custom-attribute": "test", + "attributes": { + "foo": "bar", + }, "some_ignored_attribute": "bar", } session = self.client.session @@ -89,6 +92,7 @@ class TestUserWriteStage(FlowTestCase): self.assertTrue(user_qs.exists()) self.assertTrue(user_qs.first().check_password(new_password)) self.assertEqual(user_qs.first().attributes["some"]["custom-attribute"], "test") + self.assertEqual(user_qs.first().attributes["foo"], "bar") self.assertNotIn("some_ignored_attribute", user_qs.first().attributes) @patch( From 805a4b766a06b04f2aaff12299acdef74ee8e615 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 4 Jan 2023 22:33:30 +0100 Subject: [PATCH 3/6] web/admin: migrate webauthn forms to radio Signed-off-by: Jens Langhammer --- .../AuthenticatorValidateStageForm.ts | 43 +++--- .../AuthenticateWebAuthnStageForm.ts | 126 ++++++++---------- 2 files changed, 78 insertions(+), 91 deletions(-) diff --git a/web/src/admin/stages/authenticator_validate/AuthenticatorValidateStageForm.ts b/web/src/admin/stages/authenticator_validate/AuthenticatorValidateStageForm.ts index 4c83705bb..393c410a5 100644 --- a/web/src/admin/stages/authenticator_validate/AuthenticatorValidateStageForm.ts +++ b/web/src/admin/stages/authenticator_validate/AuthenticatorValidateStageForm.ts @@ -1,5 +1,6 @@ import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import "@goauthentik/elements/forms/FormGroup"; +import "@goauthentik/elements/forms/Radio"; import "@goauthentik/elements/forms/HorizontalFormElement"; import { ModelForm } from "@goauthentik/elements/forms/ModelForm"; import "@goauthentik/elements/utils/TimeDeltaHelp"; @@ -188,29 +189,25 @@ export class AuthenticatorValidateStageForm extends ModelForm - + + ${this.showConfigurationStages ? html` diff --git a/web/src/admin/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts b/web/src/admin/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts index f24bf5e4a..b481bd4a7 100644 --- a/web/src/admin/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts +++ b/web/src/admin/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts @@ -1,6 +1,7 @@ import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import "@goauthentik/elements/forms/HorizontalFormElement"; import { ModelForm } from "@goauthentik/elements/forms/ModelForm"; +import "@goauthentik/elements/forms/Radio"; import "@goauthentik/elements/forms/SearchSelect"; import { t } from "@lingui/macro"; @@ -74,86 +75,75 @@ export class AuthenticateWebAuthnStageForm extends ModelForm - + + - + + - + + Date: Wed, 4 Jan 2023 22:38:34 +0100 Subject: [PATCH 4/6] web: fix radio label code in dark mode Signed-off-by: Jens Langhammer --- web/src/common/styles/authentik.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/src/common/styles/authentik.css b/web/src/common/styles/authentik.css index ca72f8430..6d183e930 100644 --- a/web/src/common/styles/authentik.css +++ b/web/src/common/styles/authentik.css @@ -123,7 +123,9 @@ html > form > input { --pf-global--Color--100: var(--ak-dark-foreground); --pf-c-page__main-section--m-light--BackgroundColor: var(--ak-dark-background-darker); --pf-global--link--Color: var(--ak-dark-foreground-link); - --pf-c-radio__label--Color: var(--ak-dark-foreground-link); + } + .pf-c-radio { + --pf-c-radio__label--Color: var(--ak-dark-foreground); } /* Global page background colour */ .pf-c-page { From be473470a499e1b848eaee5f84bf1b1dead4b2bd Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 4 Jan 2023 22:39:44 +0100 Subject: [PATCH 5/6] web/admin: fix lint Signed-off-by: Jens Langhammer --- .../authenticator_validate/AuthenticatorValidateStageForm.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/admin/stages/authenticator_validate/AuthenticatorValidateStageForm.ts b/web/src/admin/stages/authenticator_validate/AuthenticatorValidateStageForm.ts index 393c410a5..cdd823c25 100644 --- a/web/src/admin/stages/authenticator_validate/AuthenticatorValidateStageForm.ts +++ b/web/src/admin/stages/authenticator_validate/AuthenticatorValidateStageForm.ts @@ -1,8 +1,8 @@ import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import "@goauthentik/elements/forms/FormGroup"; -import "@goauthentik/elements/forms/Radio"; import "@goauthentik/elements/forms/HorizontalFormElement"; import { ModelForm } from "@goauthentik/elements/forms/ModelForm"; +import "@goauthentik/elements/forms/Radio"; import "@goauthentik/elements/utils/TimeDeltaHelp"; import { t } from "@lingui/macro"; From ac0783368804b1f3d0aeddb120d707c032ef7bcd Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 5 Jan 2023 10:01:30 +0100 Subject: [PATCH 6/6] release: 2022.12.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 0ac77375e..10510a57b 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 2022.12.1 +current_version = 2022.12.2 tag = True commit = True parse = (?P\d+)\.(?P\d+)\.(?P\d+) diff --git a/authentik/__init__.py b/authentik/__init__.py index 7838c3acf..eebeb414c 100644 --- a/authentik/__init__.py +++ b/authentik/__init__.py @@ -2,7 +2,7 @@ from os import environ from typing import Optional -__version__ = "2022.12.1" +__version__ = "2022.12.2" ENV_GIT_HASH_KEY = "GIT_BUILD_HASH" diff --git a/docker-compose.yml b/docker-compose.yml index 1787042f1..aaa8bccb2 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.12.1} + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.12.2} restart: unless-stopped command: server environment: @@ -50,7 +50,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.12.1} + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.12.2} restart: unless-stopped command: worker environment: diff --git a/internal/constants/constants.go b/internal/constants/constants.go index a468046da..40231016e 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.12.1" +const VERSION = "2022.12.2" diff --git a/pyproject.toml b/pyproject.toml index f52871cbc..8e3ce3a58 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -100,7 +100,7 @@ addopts = "-p no:celery --junitxml=unittest.xml" [tool.poetry] name = "authentik" -version = "2022.12.1" +version = "2022.12.2" description = "" authors = ["authentik Team "] diff --git a/schema.yml b/schema.yml index cfdfed2df..c3ba4d01c 100644 --- a/schema.yml +++ b/schema.yml @@ -1,7 +1,7 @@ openapi: 3.0.3 info: title: authentik - version: 2022.12.1 + version: 2022.12.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 538d73597..d9ba62fb1 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.12.1"; +export const VERSION = "2022.12.2"; export const TITLE_DEFAULT = "authentik"; export const ROUTE_SEPARATOR = ";";