From 602aed674b5bee14745858313e2f0c82c0326c06 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 28 Jul 2021 12:26:50 +0200 Subject: [PATCH 01/24] web/admin: fully remove response cloning due to errors Signed-off-by: Jens Langhammer --- web/src/api/Sentry.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/web/src/api/Sentry.ts b/web/src/api/Sentry.ts index 462114c0..84dc572a 100644 --- a/web/src/api/Sentry.ts +++ b/web/src/api/Sentry.ts @@ -33,15 +33,7 @@ export function configureSentry(canDoPpi: boolean = false): Promise { } } if (hint.originalException instanceof Response) { - const response = hint.originalException as Response; - // We only care about server errors - if (response.status < 500) { - return null; - } - // Need to clone the response, otherwise the .text() and .json() can't be re-used - const resCopy = response.clone(); - const body = await resCopy.json(); - event.message = `${response.status} ${response.url}: ${JSON.stringify(body)}` + return null; } if (event.exception) { me().then(user => { From affafc31cfefb7eaeea34d15903618de14c3d79f Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 28 Jul 2021 12:47:52 +0200 Subject: [PATCH 02/24] sources/ldap: improve ms-ad password complexity checking Signed-off-by: Jens Langhammer --- authentik/sources/ldap/password.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/authentik/sources/ldap/password.py b/authentik/sources/ldap/password.py index 24c064cf..6a5d4960 100644 --- a/authentik/sources/ldap/password.py +++ b/authentik/sources/ldap/password.py @@ -105,15 +105,17 @@ class LDAPPasswordChanger: if len(user_attributes["sAMAccountName"]) >= 3: if password.lower() in user_attributes["sAMAccountName"].lower(): return False - display_name_tokens = split( - RE_DISPLAYNAME_SEPARATORS, user_attributes["displayName"] - ) - for token in display_name_tokens: - # Ignore tokens under 3 chars - if len(token) < 3: - continue - if token.lower() in password.lower(): - return False + # No display name set, can't check any further + if len(user_attributes["displayName"]) < 1: + return True + for display_name in user_attributes["displayName"]: + display_name_tokens = split(RE_DISPLAYNAME_SEPARATORS, display_name) + for token in display_name_tokens: + # Ignore tokens under 3 chars + if len(token) < 3: + continue + if token.lower() in password.lower(): + return False return True def ad_password_complexity( From a3981dd3cdc9d81b5db52c4fd1ee3340d874df51 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 28 Jul 2021 16:08:06 +0200 Subject: [PATCH 03/24] providers/proxy: fix hosts for ingress not being compared correctly Signed-off-by: Jens Langhammer --- .../proxy/controllers/k8s/ingress.py | 6 +- tests/integration/test_proxy_kubernetes.py | 55 +++++++++++++++---- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/authentik/providers/proxy/controllers/k8s/ingress.py b/authentik/providers/proxy/controllers/k8s/ingress.py index 401db2e8..2cb2153b 100644 --- a/authentik/providers/proxy/controllers/k8s/ingress.py +++ b/authentik/providers/proxy/controllers/k8s/ingress.py @@ -60,12 +60,12 @@ class IngressReconciler(KubernetesObjectReconciler[NetworkingV1beta1Ingress]): expected_hosts.sort() expected_hosts_tls.sort() - have_hosts = [rule.host for rule in reference.spec.rules] + have_hosts = [rule.host for rule in current.spec.rules] have_hosts.sort() have_hosts_tls = [] - for tls_config in reference.spec.tls: - if tls_config: + for tls_config in current.spec.tls: + if tls_config and tls_config.hosts: have_hosts_tls += tls_config.hosts have_hosts_tls.sort() diff --git a/tests/integration/test_proxy_kubernetes.py b/tests/integration/test_proxy_kubernetes.py index 11b31969..ba498fda 100644 --- a/tests/integration/test_proxy_kubernetes.py +++ b/tests/integration/test_proxy_kubernetes.py @@ -1,20 +1,36 @@ """Test Controllers""" +from typing import Optional + import yaml from django.test import TestCase +from structlog.stdlib import get_logger from authentik.flows.models import Flow +from authentik.outposts.controllers.kubernetes import KubernetesController from authentik.outposts.models import KubernetesServiceConnection, Outpost, OutpostType from authentik.outposts.tasks import outpost_local_connection +from authentik.providers.proxy.controllers.k8s.ingress import IngressReconciler from authentik.providers.proxy.controllers.kubernetes import ProxyKubernetesController -from authentik.providers.proxy.models import ProxyProvider +from authentik.providers.proxy.models import ProxyMode, ProxyProvider + +LOGGER = get_logger() class TestProxyKubernetes(TestCase): """Test Controllers""" + controller: Optional[KubernetesController] + def setUp(self): # Ensure that local connection have been created outpost_local_connection() + self.controller = None + + def tearDown(self) -> None: + if self.controller: + for log in self.controller.down_with_logs(): + LOGGER.info(log) + return super().tearDown() def test_kubernetes_controller_static(self): """Test Kubernetes Controller""" @@ -33,18 +49,26 @@ class TestProxyKubernetes(TestCase): outpost.providers.add(provider) outpost.save() - controller = ProxyKubernetesController(outpost, service_connection) - manifest = controller.get_static_deployment() + self.controller = ProxyKubernetesController(outpost, service_connection) + manifest = self.controller.get_static_deployment() self.assertEqual(len(list(yaml.load_all(manifest, Loader=yaml.SafeLoader))), 4) - def test_kubernetes_controller_deploy(self): - """Test Kubernetes Controller""" + def test_kubernetes_controller_ingress(self): + """Test Kubernetes Controller's Ingress""" provider: ProxyProvider = ProxyProvider.objects.create( name="test", internal_host="http://localhost", - external_host="http://localhost", + external_host="https://localhost", authorization_flow=Flow.objects.first(), ) + provider2: ProxyProvider = ProxyProvider.objects.create( + name="test2", + internal_host="http://otherhost", + external_host="https://otherhost", + mode=ProxyMode.FORWARD_SINGLE, + authorization_flow=Flow.objects.first(), + ) + service_connection = KubernetesServiceConnection.objects.first() outpost: Outpost = Outpost.objects.create( name="test", @@ -52,8 +76,19 @@ class TestProxyKubernetes(TestCase): service_connection=service_connection, ) outpost.providers.add(provider) - outpost.save() - controller = ProxyKubernetesController(outpost, service_connection) - controller.up() - controller.down() + self.controller = ProxyKubernetesController(outpost, service_connection) + + ingress_rec = IngressReconciler(self.controller) + ingress = ingress_rec.retrieve() + + self.assertEqual(len(ingress.spec.rules), 1) + self.assertEqual(ingress.spec.rules[0].host, "localhost") + + # add provider, check again + outpost.providers.add(provider2) + ingress = ingress_rec.retrieve() + + self.assertEqual(len(ingress.spec.rules), 2) + self.assertEqual(ingress.spec.rules[0].host, "localhost") + self.assertEqual(ingress.spec.rules[1].host, "otherhost") From c8c7202c61bf3781ffb8278e41c8647e29c15170 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 28 Jul 2021 21:01:10 +0200 Subject: [PATCH 04/24] web/admin: fix LDAP Provider bind flow list being empty closes #1192 Signed-off-by: Jens Langhammer --- web/src/pages/providers/ldap/LDAPProviderForm.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/pages/providers/ldap/LDAPProviderForm.ts b/web/src/pages/providers/ldap/LDAPProviderForm.ts index e8d60844..44e30cae 100644 --- a/web/src/pages/providers/ldap/LDAPProviderForm.ts +++ b/web/src/pages/providers/ldap/LDAPProviderForm.ts @@ -54,7 +54,7 @@ export class LDAPProviderFormPage extends ModelForm { name="authorizationFlow"> { + const current = (ev.target as HTMLInputElement).value; + this.selectedFlow = current; + }}> + ${until(new FlowsApi(DEFAULT_CONFIG).flowsInstancesList({ + ordering: "pk", + designation: FlowsInstancesListDesignationEnum.Enrollment, + }).then(flows => { + return flows.results.map(flow => { + return html``; + }); + }), html``)} + + + + +
+
+ ${t`Link to use the invitation.`} +
+
+
+ +
+
+
+ `; + } + +} diff --git a/web/src/pages/stages/invitation/InvitationListPage.ts b/web/src/pages/stages/invitation/InvitationListPage.ts index ed351e4b..08dbb691 100644 --- a/web/src/pages/stages/invitation/InvitationListPage.ts +++ b/web/src/pages/stages/invitation/InvitationListPage.ts @@ -8,6 +8,7 @@ import "../../../elements/buttons/SpinnerButton"; import "../../../elements/forms/DeleteForm"; import "../../../elements/forms/ModalForm"; import "./InvitationForm"; +import "./InvitationListLink"; import { TableColumn } from "../../../elements/table/Table"; import { PAGE_SIZE } from "../../../constants"; import { Invitation, StagesApi } from "authentik-api"; @@ -15,6 +16,8 @@ import { DEFAULT_CONFIG } from "../../../api/Config"; @customElement("ak-stage-invitation-list") export class InvitationListPage extends TablePage { + expandable = true; + searchEnabled(): boolean { return true; } @@ -75,6 +78,18 @@ export class InvitationListPage extends TablePage { ]; } + renderExpanded(item: Invitation): TemplateResult { + return html` + +
+ +
+ + + + `; + } + renderToolbar(): TemplateResult { return html` From 16e6e4c3b7c5819d2b6a6ecd8b0eb7e59a611a88 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sun, 1 Aug 2021 11:47:39 +0200 Subject: [PATCH 13/24] web/admin: add re-authenticate button for plex Signed-off-by: Jens Langhammer #1205 --- web/src/locales/en.po | 4 ++++ web/src/locales/pseudo-LOCALE.po | 4 ++++ web/src/pages/sources/plex/PlexSourceForm.ts | 8 +++++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/web/src/locales/en.po b/web/src/locales/en.po index 06701eaf..5f5de231 100644 --- a/web/src/locales/en.po +++ b/web/src/locales/en.po @@ -3015,6 +3015,10 @@ msgstr "RSA-SHA384" msgid "RSA-SHA512" msgstr "RSA-SHA512" +#: src/pages/sources/plex/PlexSourceForm.ts +msgid "Re-authenticate with plex" +msgstr "Re-authenticate with plex" + #: src/pages/flows/StageBindingForm.ts msgid "Re-evaluate policies" msgstr "Re-evaluate policies" diff --git a/web/src/locales/pseudo-LOCALE.po b/web/src/locales/pseudo-LOCALE.po index caf2014d..ed51dac9 100644 --- a/web/src/locales/pseudo-LOCALE.po +++ b/web/src/locales/pseudo-LOCALE.po @@ -3007,6 +3007,10 @@ msgstr "" msgid "RSA-SHA512" msgstr "" +#: src/pages/sources/plex/PlexSourceForm.ts +msgid "Re-authenticate with plex" +msgstr "" + #: src/pages/flows/StageBindingForm.ts msgid "Re-evaluate policies" msgstr "" diff --git a/web/src/pages/sources/plex/PlexSourceForm.ts b/web/src/pages/sources/plex/PlexSourceForm.ts index ecce835c..726a6fb2 100644 --- a/web/src/pages/sources/plex/PlexSourceForm.ts +++ b/web/src/pages/sources/plex/PlexSourceForm.ts @@ -85,7 +85,13 @@ export class PlexSourceForm extends ModelForm { ${t`Load servers`} `; } - return html` + return html` + +