From b285814e24686d6512ec9dc99a7c46346c476358 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sun, 3 Oct 2021 00:30:35 +0200 Subject: [PATCH 01/18] sources/ldap: fix logic error in Active Directory account disabled status Signed-off-by: Jens Langhammer --- CONTRIBUTING.md | 2 +- Makefile | 6 +----- authentik/sources/ldap/sync/users.py | 2 +- pyproject.toml | 2 +- web/package-lock.json | 4 ++-- 5 files changed, 6 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8b7c42585..e9f4d9ea4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -117,7 +117,7 @@ This section guides you through submitting a bug report for authentik. Following Whenever authentik encounters an error, it will be logged as an Event with the type `system_exception`. This event type has a button to directly open a pre-filled GitHub issue form. -This form will have the full stack trace of the error that ocurred and shouldn't contain any sensitive data. +This form will have the full stack trace of the error that occurred and shouldn't contain any sensitive data. ### Suggesting Enhancements diff --git a/Makefile b/Makefile index 59b6159eb..373d2bfba 100644 --- a/Makefile +++ b/Makefile @@ -20,11 +20,7 @@ test: lint-fix: isort authentik tests lifecycle black authentik tests lifecycle - codespell -I .github/codespell-words.txt -w authentik - codespell -I .github/codespell-words.txt -w internal - codespell -I .github/codespell-words.txt -w cmd - codespell -I .github/codespell-words.txt -w web/src - codespell -I .github/codespell-words.txt -w website/src + codespell -I .github/codespell-words.txt -S 'web/src/locales/**' -w authentik internal cmd web/src website/src lint: pyright authentik tests lifecycle diff --git a/authentik/sources/ldap/sync/users.py b/authentik/sources/ldap/sync/users.py index 42b6a6f60..6a8aefb27 100644 --- a/authentik/sources/ldap/sync/users.py +++ b/authentik/sources/ldap/sync/users.py @@ -78,6 +78,6 @@ class UserLDAPSynchronizer(BaseLDAPSynchronizer): ak_user.save() if "userAccountControl" in attributes: uac = UserAccountControl(attributes.get("userAccountControl")) - ak_user.is_active = not uac.ACCOUNTDISABLE + ak_user.is_active = UserAccountControl.ACCOUNTDISABLE in uac ak_user.save() return user_count diff --git a/pyproject.toml b/pyproject.toml index 95e1750e1..f4709f32a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,7 +53,7 @@ disable = [ "cyclic-import", "protected-access", "raise-missing-from", - # To preverse django's translation function we need to use %-formatting + # To preserve django's translation function we need to use %-formatting "consider-using-f-string", ] diff --git a/web/package-lock.json b/web/package-lock.json index b4d3661a2..008b49638 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -6992,7 +6992,7 @@ "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/view==", "engines": { "node": ">=0.10.0" } @@ -13757,7 +13757,7 @@ "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/view==" }, "require-main-filename": { "version": "2.0.0", From fcd879034c4dcba356cc70f30cf64e6f1f0bd51f Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sat, 2 Oct 2021 21:17:15 +0200 Subject: [PATCH 02/18] outpost/proxy: fix missing negation for internal host ssl verification Signed-off-by: Jens Langhammer --- internal/outpost/proxyv2/application/mode_proxy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/outpost/proxyv2/application/mode_proxy.go b/internal/outpost/proxyv2/application/mode_proxy.go index 14c0e1e63..6630d1687 100644 --- a/internal/outpost/proxyv2/application/mode_proxy.go +++ b/internal/outpost/proxyv2/application/mode_proxy.go @@ -17,7 +17,7 @@ import ( func (a *Application) getUpstreamTransport() http.RoundTripper { return &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: *a.proxyConfig.InternalHostSslValidation}, + TLSClientConfig: &tls.Config{InsecureSkipVerify: !*a.proxyConfig.InternalHostSslValidation}, } } From 39d87841d0fbca04624ae3229747e109a830988e Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sat, 2 Oct 2021 22:00:23 +0200 Subject: [PATCH 03/18] outposts/proxy: add new headers with unified naming Signed-off-by: Jens Langhammer --- authentik/providers/proxy/controllers/k8s/traefik.py | 7 +++++++ internal/outpost/proxyv2/application/mode_common.go | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/authentik/providers/proxy/controllers/k8s/traefik.py b/authentik/providers/proxy/controllers/k8s/traefik.py index f453a2e5b..8f3cb816a 100644 --- a/authentik/providers/proxy/controllers/k8s/traefik.py +++ b/authentik/providers/proxy/controllers/k8s/traefik.py @@ -109,11 +109,18 @@ class TraefikMiddlewareReconciler(KubernetesObjectReconciler[TraefikMiddleware]) address=f"http://{self.name}.{self.namespace}:9000/akprox/auth/traefik", authResponseHeaders=[ "Set-Cookie", + # Legacy headers, remove after 2022.1 "X-Auth-Username", "X-Auth-Groups", "X-Forwarded-Email", "X-Forwarded-Preferred-Username", "X-Forwarded-User", + # New headers, unique prefix + "X-authentik-username", + "X-authentik-groups", + "X-authentik-email", + "X-authentik-name", + "X-authentik-uid", ], trustForwardHeader=True, ) diff --git a/internal/outpost/proxyv2/application/mode_common.go b/internal/outpost/proxyv2/application/mode_common.go index 64d244201..b49438e20 100644 --- a/internal/outpost/proxyv2/application/mode_common.go +++ b/internal/outpost/proxyv2/application/mode_common.go @@ -9,12 +9,21 @@ import ( func (a *Application) addHeaders(r *http.Request, c *Claims) { // https://goauthentik.io/docs/providers/proxy/proxy + + // Legacy headers, remove after 2022.1 r.Header.Set("X-Auth-Username", c.PreferredUsername) r.Header.Set("X-Auth-Groups", strings.Join(c.Groups, "|")) r.Header.Set("X-Forwarded-Email", c.Email) r.Header.Set("X-Forwarded-Preferred-Username", c.PreferredUsername) r.Header.Set("X-Forwarded-User", c.Sub) + // New headers, unique prefix + r.Header.Set("X-authentik-username", c.PreferredUsername) + r.Header.Set("X-authentik-groups", strings.Join(c.Groups, "|")) + r.Header.Set("X-authentik-email", c.Email) + r.Header.Set("X-authentik-name", c.Name) + r.Header.Set("X-authentik-uid", c.Sub) + userAttributes := c.Proxy.UserAttributes // Attempt to set basic auth based on user's attributes if *a.proxyConfig.BasicAuthEnabled { From d676cf6e3fbc83aa47ed73ffb3ce25bcc749e597 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sat, 2 Oct 2021 22:00:37 +0200 Subject: [PATCH 04/18] outposts/proxy: show full error message when user is authenticated Signed-off-by: Jens Langhammer --- internal/outpost/proxyv2/application/error.go | 7 ++++++- internal/outpost/proxyv2/application/mode_proxy.go | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/internal/outpost/proxyv2/application/error.go b/internal/outpost/proxyv2/application/error.go index 1c4f75cdf..d2f50b8e4 100644 --- a/internal/outpost/proxyv2/application/error.go +++ b/internal/outpost/proxyv2/application/error.go @@ -1,6 +1,7 @@ package application import ( + "fmt" "html/template" "net/http" @@ -8,8 +9,9 @@ import ( ) // NewProxyErrorHandler creates a ProxyErrorHandler using the template given. -func NewProxyErrorHandler(errorTemplate *template.Template) func(http.ResponseWriter, *http.Request, error) { +func (a *Application) newProxyErrorHandler(errorTemplate *template.Template) func(http.ResponseWriter, *http.Request, error) { return func(rw http.ResponseWriter, req *http.Request, proxyErr error) { + claims, _ := a.getClaims(req) log.WithError(proxyErr).Warning("Error proxying to upstream server") rw.WriteHeader(http.StatusBadGateway) data := struct { @@ -21,6 +23,9 @@ func NewProxyErrorHandler(errorTemplate *template.Template) func(http.ResponseWr Message: "Error proxying to upstream server", ProxyPrefix: "/akprox", } + if claims != nil { + data.Message = fmt.Sprintf("Error proxying to upstream server: %s", proxyErr.Error()) + } err := errorTemplate.Execute(rw, data) if err != nil { http.Error(rw, "Internal Server Error", http.StatusInternalServerError) diff --git a/internal/outpost/proxyv2/application/mode_proxy.go b/internal/outpost/proxyv2/application/mode_proxy.go index 6630d1687..7c25f0932 100644 --- a/internal/outpost/proxyv2/application/mode_proxy.go +++ b/internal/outpost/proxyv2/application/mode_proxy.go @@ -29,7 +29,7 @@ func (a *Application) configureProxy() error { } rp := &httputil.ReverseProxy{Director: a.proxyModifyRequest(u)} rp.Transport = ak.NewTracingTransport(context.TODO(), a.getUpstreamTransport()) - rp.ErrorHandler = NewProxyErrorHandler(templates.GetTemplates()) + rp.ErrorHandler = a.newProxyErrorHandler(templates.GetTemplates()) rp.ModifyResponse = a.proxyModifyResponse a.mux.PathPrefix("/").HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { claims, err := a.getClaims(r) From c296e1214c8071296e8a936db19b8598fc65af90 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sun, 3 Oct 2021 00:51:52 +0200 Subject: [PATCH 05/18] web: fix package lock Signed-off-by: Jens Langhammer --- authentik/sources/ldap/sync/users.py | 2 +- authentik/sources/ldap/tests/mock_ad.py | 5 ++++- web/package-lock.json | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/authentik/sources/ldap/sync/users.py b/authentik/sources/ldap/sync/users.py index 6a8aefb27..e48485af8 100644 --- a/authentik/sources/ldap/sync/users.py +++ b/authentik/sources/ldap/sync/users.py @@ -78,6 +78,6 @@ class UserLDAPSynchronizer(BaseLDAPSynchronizer): ak_user.save() if "userAccountControl" in attributes: uac = UserAccountControl(attributes.get("userAccountControl")) - ak_user.is_active = UserAccountControl.ACCOUNTDISABLE in uac + ak_user.is_active = UserAccountControl.ACCOUNTDISABLE not in uac ak_user.save() return user_count diff --git a/authentik/sources/ldap/tests/mock_ad.py b/authentik/sources/ldap/tests/mock_ad.py index 3418e52af..0858fe86a 100644 --- a/authentik/sources/ldap/tests/mock_ad.py +++ b/authentik/sources/ldap/tests/mock_ad.py @@ -2,6 +2,8 @@ from ldap3 import MOCK_SYNC, OFFLINE_AD_2012_R2, Connection, Server +from authentik.sources.ldap.sync.vendor.ad import UserAccountControl + def mock_ad_connection(password: str) -> Connection: """Create mock AD connection""" @@ -54,7 +56,8 @@ def mock_ad_connection(password: str) -> Connection: "objectSid": "user0", "objectClass": "person", "distinguishedName": "cn=user0,ou=users,dc=goauthentik,dc=io", - "userAccountControl": 66050, + "userAccountControl": UserAccountControl.ACCOUNTDISABLE + + UserAccountControl.NORMAL_ACCOUNT, }, ) # User without SID diff --git a/web/package-lock.json b/web/package-lock.json index 008b49638..b4d3661a2 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -6992,7 +6992,7 @@ "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/view==", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "engines": { "node": ">=0.10.0" } @@ -13757,7 +13757,7 @@ "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/view==" + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" }, "require-main-filename": { "version": "2.0.0", From d28fcca34471c38dc1743af65cbf61b85c6edd11 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sun, 3 Oct 2021 19:09:52 +0200 Subject: [PATCH 06/18] outposts: check ports of deployment in kubernetes outpost controller Signed-off-by: Jens Langhammer --- authentik/outposts/controllers/k8s/deployment.py | 7 ++++++- authentik/outposts/controllers/k8s/service.py | 9 +++------ authentik/outposts/controllers/k8s/utils.py | 12 ++++++++++++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/authentik/outposts/controllers/k8s/deployment.py b/authentik/outposts/controllers/k8s/deployment.py index 9c9aefc70..47353f94c 100644 --- a/authentik/outposts/controllers/k8s/deployment.py +++ b/authentik/outposts/controllers/k8s/deployment.py @@ -18,6 +18,7 @@ from kubernetes.client import ( from authentik.outposts.controllers.base import FIELD_MANAGER from authentik.outposts.controllers.k8s.base import KubernetesObjectReconciler, NeedsUpdate +from authentik.outposts.controllers.k8s.utils import compare_ports from authentik.outposts.models import Outpost if TYPE_CHECKING: @@ -35,7 +36,10 @@ class DeploymentReconciler(KubernetesObjectReconciler[V1Deployment]): self.outpost = self.controller.outpost def reconcile(self, current: V1Deployment, reference: V1Deployment): - super().reconcile(current, reference) + compare_ports( + current.spec.template.spec.containers[0].ports, + reference.spec.template.spec.containers[0].ports, + ) if current.spec.replicas != reference.spec.replicas: raise NeedsUpdate() if ( @@ -43,6 +47,7 @@ class DeploymentReconciler(KubernetesObjectReconciler[V1Deployment]): != reference.spec.template.spec.containers[0].image ): raise NeedsUpdate() + super().reconcile(current, reference) def get_pod_meta(self) -> dict[str, str]: """Get common object metadata""" diff --git a/authentik/outposts/controllers/k8s/service.py b/authentik/outposts/controllers/k8s/service.py index 12b50c222..d84d64ea6 100644 --- a/authentik/outposts/controllers/k8s/service.py +++ b/authentik/outposts/controllers/k8s/service.py @@ -4,8 +4,9 @@ from typing import TYPE_CHECKING from kubernetes.client import CoreV1Api, V1Service, V1ServicePort, V1ServiceSpec from authentik.outposts.controllers.base import FIELD_MANAGER -from authentik.outposts.controllers.k8s.base import KubernetesObjectReconciler, NeedsRecreate +from authentik.outposts.controllers.k8s.base import KubernetesObjectReconciler from authentik.outposts.controllers.k8s.deployment import DeploymentReconciler +from authentik.outposts.controllers.k8s.utils import compare_ports if TYPE_CHECKING: from authentik.outposts.controllers.kubernetes import KubernetesController @@ -19,11 +20,7 @@ class ServiceReconciler(KubernetesObjectReconciler[V1Service]): self.api = CoreV1Api(controller.client) def reconcile(self, current: V1Service, reference: V1Service): - if len(current.spec.ports) != len(reference.spec.ports): - raise NeedsRecreate() - for port in reference.spec.ports: - if port not in current.spec.ports: - raise NeedsRecreate() + compare_ports(current.spec, reference.spec) # run the base reconcile last, as that will probably raise NeedsUpdate # after an authentik update. However the ports might have also changed during # the update, so this causes the service to be re-created with higher diff --git a/authentik/outposts/controllers/k8s/utils.py b/authentik/outposts/controllers/k8s/utils.py index ed9663064..ad158e7e8 100644 --- a/authentik/outposts/controllers/k8s/utils.py +++ b/authentik/outposts/controllers/k8s/utils.py @@ -1,8 +1,11 @@ """k8s utils""" from pathlib import Path +from kubernetes.client.models.v1_container_port import V1ContainerPort from kubernetes.config.incluster_config import SERVICE_TOKEN_FILENAME +from authentik.outposts.controllers.k8s.base import NeedsRecreate + def get_namespace() -> str: """Get the namespace if we're running in a pod, otherwise default to default""" @@ -11,3 +14,12 @@ def get_namespace() -> str: with open(path, "r", encoding="utf8") as _namespace_file: return _namespace_file.read() return "default" + + +def compare_ports(current: list[V1ContainerPort], reference: list[V1ContainerPort]): + """Compare ports of a list""" + if len(current) != len(reference): + raise NeedsRecreate() + for port in reference: + if port not in current: + raise NeedsRecreate() From e31a3307b5be6eb0f14f7698edfadcf0905ea52b Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sun, 3 Oct 2021 19:14:27 +0200 Subject: [PATCH 07/18] providers/proxy: always check ingress secret in kubernetes controller Signed-off-by: Jens Langhammer --- authentik/providers/proxy/controllers/k8s/ingress.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/authentik/providers/proxy/controllers/k8s/ingress.py b/authentik/providers/proxy/controllers/k8s/ingress.py index 07d3d8c08..601cf9c1b 100644 --- a/authentik/providers/proxy/controllers/k8s/ingress.py +++ b/authentik/providers/proxy/controllers/k8s/ingress.py @@ -63,8 +63,15 @@ class IngressReconciler(KubernetesObjectReconciler[NetworkingV1beta1Ingress]): have_hosts_tls = [] if current.spec.tls: for tls_config in current.spec.tls: - if tls_config and tls_config.hosts: + if not tls_config: + continue + if tls_config.hosts: have_hosts_tls += tls_config.hosts + if ( + tls_config.secret_name + != self.controller.outpost.config.kubernetes_ingress_secret_name + ): + raise NeedsUpdate() have_hosts_tls.sort() if have_hosts != expected_hosts: From 45f99fbaf0b11e32a1d1dd995816c4480d54a907 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sun, 3 Oct 2021 19:25:18 +0200 Subject: [PATCH 08/18] outposts: fix circular import in kubernetes controller Signed-off-by: Jens Langhammer --- authentik/outposts/controllers/k8s/base.py | 14 +------------- authentik/outposts/controllers/k8s/deployment.py | 3 ++- authentik/outposts/controllers/k8s/secret.py | 3 ++- authentik/outposts/controllers/k8s/triggers.py | 14 ++++++++++++++ authentik/outposts/controllers/k8s/utils.py | 2 +- .../providers/proxy/controllers/k8s/ingress.py | 7 ++----- .../providers/proxy/controllers/k8s/traefik.py | 3 ++- tests/integration/test_outpost_kubernetes.py | 2 +- 8 files changed, 25 insertions(+), 23 deletions(-) create mode 100644 authentik/outposts/controllers/k8s/triggers.py diff --git a/authentik/outposts/controllers/k8s/base.py b/authentik/outposts/controllers/k8s/base.py index d06a72b53..de7c244a2 100644 --- a/authentik/outposts/controllers/k8s/base.py +++ b/authentik/outposts/controllers/k8s/base.py @@ -10,7 +10,7 @@ from structlog.stdlib import get_logger from urllib3.exceptions import HTTPError from authentik import __version__ -from authentik.lib.sentry import SentryIgnoredException +from authentik.outposts.controllers.k8s.triggers import NeedsRecreate, NeedsUpdate from authentik.outposts.managed import MANAGED_OUTPOST if TYPE_CHECKING: @@ -20,18 +20,6 @@ if TYPE_CHECKING: T = TypeVar("T", V1Pod, V1Deployment) -class ReconcileTrigger(SentryIgnoredException): - """Base trigger raised by child classes to notify us""" - - -class NeedsRecreate(ReconcileTrigger): - """Exception to trigger a complete recreate of the Kubernetes Object""" - - -class NeedsUpdate(ReconcileTrigger): - """Exception to trigger an update to the Kubernetes Object""" - - class KubernetesObjectReconciler(Generic[T]): """Base Kubernetes Reconciler, handles the basic logic.""" diff --git a/authentik/outposts/controllers/k8s/deployment.py b/authentik/outposts/controllers/k8s/deployment.py index 47353f94c..5d3d1a74c 100644 --- a/authentik/outposts/controllers/k8s/deployment.py +++ b/authentik/outposts/controllers/k8s/deployment.py @@ -17,7 +17,8 @@ from kubernetes.client import ( ) from authentik.outposts.controllers.base import FIELD_MANAGER -from authentik.outposts.controllers.k8s.base import KubernetesObjectReconciler, NeedsUpdate +from authentik.outposts.controllers.k8s.base import KubernetesObjectReconciler +from authentik.outposts.controllers.k8s.triggers import NeedsUpdate from authentik.outposts.controllers.k8s.utils import compare_ports from authentik.outposts.models import Outpost diff --git a/authentik/outposts/controllers/k8s/secret.py b/authentik/outposts/controllers/k8s/secret.py index d7cb8c03c..fc8dc8296 100644 --- a/authentik/outposts/controllers/k8s/secret.py +++ b/authentik/outposts/controllers/k8s/secret.py @@ -5,7 +5,8 @@ from typing import TYPE_CHECKING from kubernetes.client import CoreV1Api, V1Secret from authentik.outposts.controllers.base import FIELD_MANAGER -from authentik.outposts.controllers.k8s.base import KubernetesObjectReconciler, NeedsUpdate +from authentik.outposts.controllers.k8s.base import KubernetesObjectReconciler +from authentik.outposts.controllers.k8s.triggers import NeedsUpdate if TYPE_CHECKING: from authentik.outposts.controllers.kubernetes import KubernetesController diff --git a/authentik/outposts/controllers/k8s/triggers.py b/authentik/outposts/controllers/k8s/triggers.py new file mode 100644 index 000000000..284acd3bc --- /dev/null +++ b/authentik/outposts/controllers/k8s/triggers.py @@ -0,0 +1,14 @@ +"""exceptions used by the kubernetes reconciler to trigger updates""" +from authentik.lib.sentry import SentryIgnoredException + + +class ReconcileTrigger(SentryIgnoredException): + """Base trigger raised by child classes to notify us""" + + +class NeedsRecreate(ReconcileTrigger): + """Exception to trigger a complete recreate of the Kubernetes Object""" + + +class NeedsUpdate(ReconcileTrigger): + """Exception to trigger an update to the Kubernetes Object""" diff --git a/authentik/outposts/controllers/k8s/utils.py b/authentik/outposts/controllers/k8s/utils.py index ad158e7e8..c44200555 100644 --- a/authentik/outposts/controllers/k8s/utils.py +++ b/authentik/outposts/controllers/k8s/utils.py @@ -4,7 +4,7 @@ from pathlib import Path from kubernetes.client.models.v1_container_port import V1ContainerPort from kubernetes.config.incluster_config import SERVICE_TOKEN_FILENAME -from authentik.outposts.controllers.k8s.base import NeedsRecreate +from authentik.outposts.controllers.k8s.triggers import NeedsRecreate def get_namespace() -> str: diff --git a/authentik/providers/proxy/controllers/k8s/ingress.py b/authentik/providers/proxy/controllers/k8s/ingress.py index 601cf9c1b..14eaa0d6e 100644 --- a/authentik/providers/proxy/controllers/k8s/ingress.py +++ b/authentik/providers/proxy/controllers/k8s/ingress.py @@ -14,11 +14,8 @@ from kubernetes.client import ( from kubernetes.client.models.networking_v1beta1_ingress_rule import NetworkingV1beta1IngressRule from authentik.outposts.controllers.base import FIELD_MANAGER -from authentik.outposts.controllers.k8s.base import ( - KubernetesObjectReconciler, - NeedsRecreate, - NeedsUpdate, -) +from authentik.outposts.controllers.k8s.base import KubernetesObjectReconciler +from authentik.outposts.controllers.k8s.triggers import NeedsRecreate, NeedsUpdate from authentik.providers.proxy.models import ProxyMode, ProxyProvider if TYPE_CHECKING: diff --git a/authentik/providers/proxy/controllers/k8s/traefik.py b/authentik/providers/proxy/controllers/k8s/traefik.py index 8f3cb816a..623c343a8 100644 --- a/authentik/providers/proxy/controllers/k8s/traefik.py +++ b/authentik/providers/proxy/controllers/k8s/traefik.py @@ -6,7 +6,8 @@ from dacite import from_dict from kubernetes.client import ApiextensionsV1Api, CustomObjectsApi from authentik.outposts.controllers.base import FIELD_MANAGER -from authentik.outposts.controllers.k8s.base import KubernetesObjectReconciler, NeedsUpdate +from authentik.outposts.controllers.k8s.base import KubernetesObjectReconciler +from authentik.outposts.controllers.k8s.triggers import NeedsUpdate from authentik.providers.proxy.models import ProxyMode, ProxyProvider if TYPE_CHECKING: diff --git a/tests/integration/test_outpost_kubernetes.py b/tests/integration/test_outpost_kubernetes.py index a82261854..40d96e833 100644 --- a/tests/integration/test_outpost_kubernetes.py +++ b/tests/integration/test_outpost_kubernetes.py @@ -3,8 +3,8 @@ from django.test import TestCase from authentik.flows.models import Flow from authentik.lib.config import CONFIG -from authentik.outposts.controllers.k8s.base import NeedsUpdate from authentik.outposts.controllers.k8s.deployment import DeploymentReconciler +from authentik.outposts.controllers.k8s.triggers import NeedsUpdate from authentik.outposts.controllers.kubernetes import KubernetesController from authentik.outposts.models import KubernetesServiceConnection, Outpost, OutpostType from authentik.outposts.tasks import outpost_local_connection From 3634bf4629147c0ac6e062e33eefab6646a42837 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sun, 3 Oct 2021 22:54:07 +0200 Subject: [PATCH 09/18] tests/integration: fix tests failing due to incorrect comparison Signed-off-by: Jens Langhammer --- authentik/outposts/controllers/k8s/service.py | 2 +- tests/integration/test_outpost_kubernetes.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/authentik/outposts/controllers/k8s/service.py b/authentik/outposts/controllers/k8s/service.py index d84d64ea6..0d04ffb89 100644 --- a/authentik/outposts/controllers/k8s/service.py +++ b/authentik/outposts/controllers/k8s/service.py @@ -20,7 +20,7 @@ class ServiceReconciler(KubernetesObjectReconciler[V1Service]): self.api = CoreV1Api(controller.client) def reconcile(self, current: V1Service, reference: V1Service): - compare_ports(current.spec, reference.spec) + compare_ports(current.spec.ports, reference.spec.ports) # run the base reconcile last, as that will probably raise NeedsUpdate # after an authentik update. However the ports might have also changed during # the update, so this causes the service to be re-created with higher diff --git a/tests/integration/test_outpost_kubernetes.py b/tests/integration/test_outpost_kubernetes.py index 40d96e833..c9000ede8 100644 --- a/tests/integration/test_outpost_kubernetes.py +++ b/tests/integration/test_outpost_kubernetes.py @@ -5,9 +5,9 @@ from authentik.flows.models import Flow from authentik.lib.config import CONFIG from authentik.outposts.controllers.k8s.deployment import DeploymentReconciler from authentik.outposts.controllers.k8s.triggers import NeedsUpdate -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.kubernetes import ProxyKubernetesController from authentik.providers.proxy.models import ProxyProvider @@ -35,7 +35,7 @@ class OutpostKubernetesTests(TestCase): def test_deployment_reconciler(self): """test that deployment requires update""" - controller = KubernetesController(self.outpost, self.service_connection) + controller = ProxyKubernetesController(self.outpost, self.service_connection) deployment_reconciler = DeploymentReconciler(controller) self.assertIsNotNone(deployment_reconciler.retrieve()) From c0329140920d121ddaeca1c23db56ee657dfab90 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Mon, 4 Oct 2021 09:41:16 +0200 Subject: [PATCH 10/18] web/admin: fix search group label 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 dc3f859d8..ec6aec83e 100644 --- a/web/src/pages/providers/ldap/LDAPProviderForm.ts +++ b/web/src/pages/providers/ldap/LDAPProviderForm.ts @@ -95,7 +95,7 @@ export class LDAPProviderFormPage extends ModelForm { ${t`Flow used for users to authenticate. Currently only identification and password stages are supported.`}

- + + + +

+ ${t`When a user returns from the email successfully, their account will be activated.`} +

+
Date: Mon, 4 Oct 2021 18:52:27 +0200 Subject: [PATCH 17/18] web: Update Web API Client version (#1526) Signed-off-by: Jens Langhammer --- web/package-lock.json | 14 +++++++------- web/package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index b4d3661a2..d6f10c87f 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -15,7 +15,7 @@ "@babel/preset-env": "^7.15.6", "@babel/preset-typescript": "^7.15.0", "@fortawesome/fontawesome-free": "^5.15.4", - "@goauthentik/api": "^2021.9.2-1632578262", + "@goauthentik/api": "^2021.9.4-1633366097", "@lingui/cli": "^3.11.1", "@lingui/core": "^3.11.1", "@lingui/macro": "^3.11.1", @@ -1691,9 +1691,9 @@ } }, "node_modules/@goauthentik/api": { - "version": "2021.9.2-1632578262", - "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.9.2-1632578262.tgz", - "integrity": "sha512-pOFIODBsWPCDA3z+ZSp5UPDb0/cvuj6uVbDzVkPUJxF/fymgvmBcdY8MTIKz/usLhL7qvPra1h4RZWITWVxa6g==" + "version": "2021.9.4-1633366097", + "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.9.4-1633366097.tgz", + "integrity": "sha512-k0RX5kHNfkgmciwPD6a7o8Movj9nfYt/uqvuJ0+5ptttJTDkB177c+okS0hqBtZF8n1u662w85gMvffAYrvU/Q==" }, "node_modules/@humanwhocodes/config-array": { "version": "0.5.0", @@ -9760,9 +9760,9 @@ "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==" }, "@goauthentik/api": { - "version": "2021.9.2-1632578262", - "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.9.2-1632578262.tgz", - "integrity": "sha512-pOFIODBsWPCDA3z+ZSp5UPDb0/cvuj6uVbDzVkPUJxF/fymgvmBcdY8MTIKz/usLhL7qvPra1h4RZWITWVxa6g==" + "version": "2021.9.4-1633366097", + "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.9.4-1633366097.tgz", + "integrity": "sha512-k0RX5kHNfkgmciwPD6a7o8Movj9nfYt/uqvuJ0+5ptttJTDkB177c+okS0hqBtZF8n1u662w85gMvffAYrvU/Q==" }, "@humanwhocodes/config-array": { "version": "0.5.0", diff --git a/web/package.json b/web/package.json index 867731a9d..1e91440b9 100644 --- a/web/package.json +++ b/web/package.json @@ -47,7 +47,7 @@ "@babel/preset-env": "^7.15.6", "@babel/preset-typescript": "^7.15.0", "@fortawesome/fontawesome-free": "^5.15.4", - "@goauthentik/api": "^2021.9.2-1632578262", + "@goauthentik/api": "^2021.9.4-1633366097", "@lingui/cli": "^3.11.1", "@lingui/core": "^3.11.1", "@lingui/macro": "^3.11.1", From bcf7e162a48a30e369cec49b4b6adfc18b6054c9 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Mon, 4 Oct 2021 20:08:46 +0200 Subject: [PATCH 18/18] release: 2021.9.5 --- .bumpversion.cfg | 2 +- .github/workflows/release-publish.yml | 20 +++++++++---------- authentik/__init__.py | 2 +- docker-compose.yml | 4 ++-- internal/constants/constants.go | 2 +- schema.yml | 2 +- web/src/constants.ts | 2 +- website/docs/installation/docker-compose.md | 4 ++-- .../outposts/manual-deploy-docker-compose.md | 4 ++-- .../docs/outposts/manual-deploy-kubernetes.md | 14 ++++++------- 10 files changed, 28 insertions(+), 28 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index fdc1210c6..9c432a0a8 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 2021.9.4 +current_version = 2021.9.5 tag = True commit = True parse = (?P\d+)\.(?P\d+)\.(?P\d+)\-?(?P.*) diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml index a25e45b8e..70d4d9fe7 100644 --- a/.github/workflows/release-publish.yml +++ b/.github/workflows/release-publish.yml @@ -33,14 +33,14 @@ jobs: with: push: ${{ github.event_name == 'release' }} tags: | - beryju/authentik:2021.9.4, + beryju/authentik:2021.9.5, beryju/authentik:latest, - ghcr.io/goauthentik/server:2021.9.4, + ghcr.io/goauthentik/server:2021.9.5, ghcr.io/goauthentik/server:latest platforms: linux/amd64,linux/arm64 context: . - name: Building Docker Image (stable) - if: ${{ github.event_name == 'release' && !contains('2021.9.4', 'rc') }} + if: ${{ github.event_name == 'release' && !contains('2021.9.5', 'rc') }} run: | docker pull beryju/authentik:latest docker tag beryju/authentik:latest beryju/authentik:stable @@ -75,14 +75,14 @@ jobs: with: push: ${{ github.event_name == 'release' }} tags: | - beryju/authentik-proxy:2021.9.4, + beryju/authentik-proxy:2021.9.5, beryju/authentik-proxy:latest, - ghcr.io/goauthentik/proxy:2021.9.4, + ghcr.io/goauthentik/proxy:2021.9.5, ghcr.io/goauthentik/proxy:latest file: proxy.Dockerfile platforms: linux/amd64,linux/arm64 - name: Building Docker Image (stable) - if: ${{ github.event_name == 'release' && !contains('2021.9.4', 'rc') }} + if: ${{ github.event_name == 'release' && !contains('2021.9.5', 'rc') }} run: | docker pull beryju/authentik-proxy:latest docker tag beryju/authentik-proxy:latest beryju/authentik-proxy:stable @@ -117,14 +117,14 @@ jobs: with: push: ${{ github.event_name == 'release' }} tags: | - beryju/authentik-ldap:2021.9.4, + beryju/authentik-ldap:2021.9.5, beryju/authentik-ldap:latest, - ghcr.io/goauthentik/ldap:2021.9.4, + ghcr.io/goauthentik/ldap:2021.9.5, ghcr.io/goauthentik/ldap:latest file: ldap.Dockerfile platforms: linux/amd64,linux/arm64 - name: Building Docker Image (stable) - if: ${{ github.event_name == 'release' && !contains('2021.9.4', 'rc') }} + if: ${{ github.event_name == 'release' && !contains('2021.9.5', 'rc') }} run: | docker pull beryju/authentik-ldap:latest docker tag beryju/authentik-ldap:latest beryju/authentik-ldap:stable @@ -175,7 +175,7 @@ jobs: SENTRY_PROJECT: authentik SENTRY_URL: https://sentry.beryju.org with: - version: authentik@2021.9.4 + version: authentik@2021.9.5 environment: beryjuorg-prod sourcemaps: './web/dist' url_prefix: '~/static/dist' diff --git a/authentik/__init__.py b/authentik/__init__.py index cfcd652a8..ba9f6e8ca 100644 --- a/authentik/__init__.py +++ b/authentik/__init__.py @@ -1,3 +1,3 @@ """authentik""" -__version__ = "2021.9.4" +__version__ = "2021.9.5" ENV_GIT_HASH_KEY = "GIT_BUILD_HASH" diff --git a/docker-compose.yml b/docker-compose.yml index 19e35e00d..a2ac306dd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,7 +21,7 @@ services: networks: - internal server: - image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2021.9.4} + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2021.9.5} restart: unless-stopped command: server environment: @@ -44,7 +44,7 @@ services: - "0.0.0.0:9000:9000" - "0.0.0.0:9443:9443" worker: - image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2021.9.4} + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2021.9.5} restart: unless-stopped command: worker networks: diff --git a/internal/constants/constants.go b/internal/constants/constants.go index 63503bba6..9a0e220cf 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -17,4 +17,4 @@ func OutpostUserAgent() string { return fmt.Sprintf("authentik-outpost@%s (build=%s)", VERSION, BUILD()) } -const VERSION = "2021.9.4" +const VERSION = "2021.9.5" diff --git a/schema.yml b/schema.yml index d094ce173..9aba2a107 100644 --- a/schema.yml +++ b/schema.yml @@ -1,7 +1,7 @@ openapi: 3.0.3 info: title: authentik - version: 2021.9.4 + version: 2021.9.5 description: Making authentication simple. contact: email: hello@beryju.org diff --git a/web/src/constants.ts b/web/src/constants.ts index cf347c990..a783d832d 100644 --- a/web/src/constants.ts +++ b/web/src/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 = "2021.9.4"; +export const VERSION = "2021.9.5"; export const PAGE_SIZE = 20; export const TITLE_DEFAULT = "authentik"; export const ROUTE_SEPARATOR = ";"; diff --git a/website/docs/installation/docker-compose.md b/website/docs/installation/docker-compose.md index a0302a78f..40d98c64a 100644 --- a/website/docs/installation/docker-compose.md +++ b/website/docs/installation/docker-compose.md @@ -12,9 +12,9 @@ This installation method is for test-setups and small-scale productive setups. ## Preparation -Download the latest `docker-compose.yml` from [here](https://raw.githubusercontent.com/goauthentik/authentik/version/2021.9.4/docker-compose.yml). Place it in a directory of your choice. +Download the latest `docker-compose.yml` from [here](https://raw.githubusercontent.com/goauthentik/authentik/version/2021.9.5/docker-compose.yml). Place it in a directory of your choice. -To optionally deploy a different version run `echo AUTHENTIK_TAG=2021.9.4 >> .env` +To optionally deploy a different version run `echo AUTHENTIK_TAG=2021.9.5 >> .env` If this is a fresh authentik install run the following commands to generate a password: diff --git a/website/docs/outposts/manual-deploy-docker-compose.md b/website/docs/outposts/manual-deploy-docker-compose.md index 50da5123c..0b76fc711 100644 --- a/website/docs/outposts/manual-deploy-docker-compose.md +++ b/website/docs/outposts/manual-deploy-docker-compose.md @@ -13,7 +13,7 @@ version: "3.5" services: authentik_proxy: - image: ghcr.io/goauthentik/proxy:2021.9.4 + image: ghcr.io/goauthentik/proxy:2021.9.5 # Optionally specify which networks the container should be # might be needed to reach the core authentik server # networks: @@ -40,7 +40,7 @@ version: "3.5" services: authentik_ldap: - image: ghcr.io/goauthentik/ldap:2021.9.4 + image: ghcr.io/goauthentik/ldap:2021.9.5 # Optionally specify which networks the container should be # might be needed to reach the core authentik server # networks: diff --git a/website/docs/outposts/manual-deploy-kubernetes.md b/website/docs/outposts/manual-deploy-kubernetes.md index ab91247fe..45faa447f 100644 --- a/website/docs/outposts/manual-deploy-kubernetes.md +++ b/website/docs/outposts/manual-deploy-kubernetes.md @@ -14,7 +14,7 @@ metadata: app.kubernetes.io/instance: __OUTPOST_NAME__ app.kubernetes.io/managed-by: goauthentik.io app.kubernetes.io/name: authentik-proxy - app.kubernetes.io/version: 2021.9.4 + app.kubernetes.io/version: 2021.9.5 name: authentik-outpost-api stringData: authentik_host: "__AUTHENTIK_URL__" @@ -29,7 +29,7 @@ metadata: app.kubernetes.io/instance: __OUTPOST_NAME__ app.kubernetes.io/managed-by: goauthentik.io app.kubernetes.io/name: authentik-proxy - app.kubernetes.io/version: 2021.9.4 + app.kubernetes.io/version: 2021.9.5 name: authentik-outpost spec: ports: @@ -54,7 +54,7 @@ metadata: app.kubernetes.io/instance: __OUTPOST_NAME__ app.kubernetes.io/managed-by: goauthentik.io app.kubernetes.io/name: authentik-proxy - app.kubernetes.io/version: 2021.9.4 + app.kubernetes.io/version: 2021.9.5 name: authentik-outpost spec: selector: @@ -62,14 +62,14 @@ spec: app.kubernetes.io/instance: __OUTPOST_NAME__ app.kubernetes.io/managed-by: goauthentik.io app.kubernetes.io/name: authentik-proxy - app.kubernetes.io/version: 2021.9.4 + app.kubernetes.io/version: 2021.9.5 template: metadata: labels: app.kubernetes.io/instance: __OUTPOST_NAME__ app.kubernetes.io/managed-by: goauthentik.io app.kubernetes.io/name: authentik-proxy - app.kubernetes.io/version: 2021.9.4 + app.kubernetes.io/version: 2021.9.5 spec: containers: - env: @@ -88,7 +88,7 @@ spec: secretKeyRef: key: authentik_host_insecure name: authentik-outpost-api - image: ghcr.io/goauthentik/proxy:2021.9.4 + image: ghcr.io/goauthentik/proxy:2021.9.5 name: proxy ports: - containerPort: 9000 @@ -110,7 +110,7 @@ metadata: app.kubernetes.io/instance: __OUTPOST_NAME__ app.kubernetes.io/managed-by: goauthentik.io app.kubernetes.io/name: authentik-proxy - app.kubernetes.io/version: 2021.9.4 + app.kubernetes.io/version: 2021.9.5 name: authentik-outpost spec: rules: