From 9a8f62f42eccfc462e31cc600c452f0e4375ea88 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 1 Dec 2021 17:07:00 +0100 Subject: [PATCH 01/46] web/admin: don't show disabled http basic as red Signed-off-by: Jens Langhammer --- web/src/pages/providers/proxy/ProxyProviderViewPage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/pages/providers/proxy/ProxyProviderViewPage.ts b/web/src/pages/providers/proxy/ProxyProviderViewPage.ts index aae9c6f68..8165419d1 100644 --- a/web/src/pages/providers/proxy/ProxyProviderViewPage.ts +++ b/web/src/pages/providers/proxy/ProxyProviderViewPage.ts @@ -176,7 +176,7 @@ export class ProxyProviderViewPage extends LitElement { ${this.provider.basicAuthEnabled ? t`Yes` : t`No`} From 3b068610b96dd2fffcc54995a4bd8bc21ad47372 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 1 Dec 2021 20:05:56 +0100 Subject: [PATCH 02/46] outposts/proxy: clean up header setting (don't copy all headers) Signed-off-by: Jens Langhammer --- .../proxyv2/application/mode_common.go | 34 +++++++------------ .../proxyv2/application/mode_forward.go | 8 ++--- .../outpost/proxyv2/application/mode_proxy.go | 2 +- 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/internal/outpost/proxyv2/application/mode_common.go b/internal/outpost/proxyv2/application/mode_common.go index b49438e20..795ba5e41 100644 --- a/internal/outpost/proxyv2/application/mode_common.go +++ b/internal/outpost/proxyv2/application/mode_common.go @@ -7,22 +7,22 @@ import ( "strings" ) -func (a *Application) addHeaders(r *http.Request, c *Claims) { +func (a *Application) addHeaders(headers http.Header, 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) + headers.Set("X-Auth-Username", c.PreferredUsername) + headers.Set("X-Auth-Groups", strings.Join(c.Groups, "|")) + headers.Set("X-Forwarded-Email", c.Email) + headers.Set("X-Forwarded-Preferred-Username", c.PreferredUsername) + headers.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) + headers.Set("X-authentik-username", c.PreferredUsername) + headers.Set("X-authentik-groups", strings.Join(c.Groups, "|")) + headers.Set("X-authentik-email", c.Email) + headers.Set("X-authentik-name", c.Name) + headers.Set("X-authentik-uid", c.Sub) userAttributes := c.Proxy.UserAttributes // Attempt to set basic auth based on user's attributes @@ -39,7 +39,7 @@ func (a *Application) addHeaders(r *http.Request, c *Claims) { } authVal := base64.StdEncoding.EncodeToString([]byte(username + ":" + password)) a.log.WithField("username", username).Trace("setting http basic auth") - r.Header["Authorization"] = []string{fmt.Sprintf("Basic %s", authVal)} + headers.Set("Authorization", fmt.Sprintf("Basic %s", authVal)) } // Check if user has additional headers set that we should sent if additionalHeaders, ok := userAttributes["additionalHeaders"].(map[string]interface{}); ok { @@ -48,15 +48,7 @@ func (a *Application) addHeaders(r *http.Request, c *Claims) { return } for key, value := range additionalHeaders { - r.Header.Set(key, toString(value)) - } - } -} - -func copyHeadersToResponse(rw http.ResponseWriter, r *http.Request) { - for headerKey, headers := range r.Header { - for _, value := range headers { - rw.Header().Set(headerKey, value) + headers.Set(key, toString(value)) } } } diff --git a/internal/outpost/proxyv2/application/mode_forward.go b/internal/outpost/proxyv2/application/mode_forward.go index c5e25cb55..6a4a83193 100644 --- a/internal/outpost/proxyv2/application/mode_forward.go +++ b/internal/outpost/proxyv2/application/mode_forward.go @@ -26,8 +26,8 @@ func (a *Application) configureForward() error { func (a *Application) forwardHandleTraefik(rw http.ResponseWriter, r *http.Request) { claims, err := a.getClaims(r) if claims != nil && err == nil { - a.addHeaders(r, claims) - copyHeadersToResponse(rw, r) + a.addHeaders(rw.Header(), claims) + a.log.WithField("headers", rw.Header()).Trace("headers written to forward_auth") return } else if claims == nil && a.IsAllowlisted(r) { a.log.Trace("path can be accessed without authentication") @@ -69,9 +69,9 @@ func (a *Application) forwardHandleTraefik(rw http.ResponseWriter, r *http.Reque func (a *Application) forwardHandleNginx(rw http.ResponseWriter, r *http.Request) { claims, err := a.getClaims(r) if claims != nil && err == nil { - a.addHeaders(r, claims) - copyHeadersToResponse(rw, r) + a.addHeaders(rw.Header(), claims) rw.WriteHeader(200) + a.log.WithField("headers", rw.Header()).Trace("headers written to forward_auth") return } else if claims == nil && a.IsAllowlisted(r) { a.log.Trace("path can be accessed without authentication") diff --git a/internal/outpost/proxyv2/application/mode_proxy.go b/internal/outpost/proxyv2/application/mode_proxy.go index 7c25f0932..72d831157 100644 --- a/internal/outpost/proxyv2/application/mode_proxy.go +++ b/internal/outpost/proxyv2/application/mode_proxy.go @@ -39,7 +39,7 @@ func (a *Application) configureProxy() error { a.redirectToStart(rw, r) return } else { - a.addHeaders(r, claims) + a.addHeaders(r.Header, claims) } before := time.Now() rp.ServeHTTP(rw, r) From 382b0e8941721653853b58eaae0670a9e95ef502 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 1 Dec 2021 20:13:05 +0100 Subject: [PATCH 03/46] root: fix overlay outpost api generation Signed-off-by: Jens Langhammer --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 572bc094e..1b9a85854 100644 --- a/Makefile +++ b/Makefile @@ -68,7 +68,7 @@ gen-outpost: docker run \ --rm -v ${PWD}:/local \ --user ${UID}:${GID} \ - openapitools/openapi-generator-cli generate \ + openapitools/openapi-generator-cli:v5.2.1 generate \ -i /local/schema.yml \ -g go \ -o /local/api \ From 60b95271ebe39dcebe394a1441a89ff07ec13b8d Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 1 Dec 2021 20:19:09 +0100 Subject: [PATCH 04/46] outposts/proxy: add additional headers Signed-off-by: Jens Langhammer --- authentik/providers/proxy/api.py | 7 +++- .../proxyv2/application/mode_common.go | 5 +++ schema.yml | 10 +++++ website/docs/providers/proxy/proxy.md | 42 +++++++++++++++---- 4 files changed, 55 insertions(+), 9 deletions(-) diff --git a/authentik/providers/proxy/api.py b/authentik/providers/proxy/api.py index af9b84630..3ca998614 100644 --- a/authentik/providers/proxy/api.py +++ b/authentik/providers/proxy/api.py @@ -3,7 +3,7 @@ from typing import Any, Optional from drf_spectacular.utils import extend_schema_field from rest_framework.exceptions import ValidationError -from rest_framework.fields import CharField, ListField, SerializerMethodField +from rest_framework.fields import CharField, ListField, ReadOnlyField, SerializerMethodField from rest_framework.serializers import ModelSerializer from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet @@ -109,6 +109,9 @@ class ProxyProviderViewSet(UsedByMixin, ModelViewSet): class ProxyOutpostConfigSerializer(ModelSerializer): """Proxy provider serializer for outposts""" + assigned_application_slug = ReadOnlyField(source="application.slug") + assigned_application_name = ReadOnlyField(source="application.name") + oidc_configuration = SerializerMethodField() token_validity = SerializerMethodField() scopes_to_request = SerializerMethodField() @@ -152,6 +155,8 @@ class ProxyOutpostConfigSerializer(ModelSerializer): "cookie_domain", "token_validity", "scopes_to_request", + "assigned_application_slug", + "assigned_application_name", ] diff --git a/internal/outpost/proxyv2/application/mode_common.go b/internal/outpost/proxyv2/application/mode_common.go index 795ba5e41..e3ff6ad30 100644 --- a/internal/outpost/proxyv2/application/mode_common.go +++ b/internal/outpost/proxyv2/application/mode_common.go @@ -24,6 +24,11 @@ func (a *Application) addHeaders(headers http.Header, c *Claims) { headers.Set("X-authentik-name", c.Name) headers.Set("X-authentik-uid", c.Sub) + // System headers + headers.Set("X-authentik-meta-outpost", a.outpostName) + headers.Set("X-authentik-meta-provider", a.proxyConfig.Name) + headers.Set("X-authentik-meta-app", a.proxyConfig.AssignedApplicationSlug) + userAttributes := c.Proxy.UserAttributes // Attempt to set basic auth based on user's attributes if *a.proxyConfig.BasicAuthEnabled { diff --git a/schema.yml b/schema.yml index 0077029a1..77905dc2b 100644 --- a/schema.yml +++ b/schema.yml @@ -28984,7 +28984,17 @@ components: items: type: string readOnly: true + assigned_application_slug: + type: string + description: Internal application name, used in URLs. + readOnly: true + assigned_application_name: + type: string + description: Application's display Name. + readOnly: true required: + - assigned_application_name + - assigned_application_slug - external_host - name - oidc_configuration diff --git a/website/docs/providers/proxy/proxy.md b/website/docs/providers/proxy/proxy.md index dfaeb883f..8f4c94533 100644 --- a/website/docs/providers/proxy/proxy.md +++ b/website/docs/providers/proxy/proxy.md @@ -2,20 +2,46 @@ title: Overview --- -The proxy outpost sets the following headers: +The proxy outpost sets the following user-specific headers: -``` -X-authentik-username: akadmin # The username of the currently logged in user -X-authentik-groups: foo|bar|baz # The groups the user is member of, separated by a pipe -X-authentik-email: root@localhost # The email address of the currently logged in user -X-authentik-name: authentik Default Admin # Full name of the current user -X-authentik-uid: 900347b8a29876b45ca6f75722635ecfedf0e931c6022e3a29a8aa13fb5516fb # The hashed identifier of the currently logged in user. -``` +- X-authentik-username: `akadmin` + + The username of the currently logged in user + +- X-authentik-groups: `foo|bar|baz` + + The groups the user is member of, separated by a pipe + +- X-authentik-email: `root@localhost` + + The email address of the currently logged in user + +- X-authentik-name: `authentik Default Admin` + + Full name of the current user + +- X-authentik-uid: `900347b8a29876b45ca6f75722635ecfedf0e931c6022e3a29a8aa13fb5516fb` + + The hashed identifier of the currently logged in user. Additionally, you can set `additionalHeaders` on groups or users to set additional headers. If you enable *Set HTTP-Basic Authentication* option, the HTTP Authorization header is being set. +Besides these user-specific headers, some application specific headers are also set: + +- X-authentik-meta-outpost: `authentik Embedded Outpost` + + The authentik outpost's name. + +- X-authentik-meta-provider: `test` + + The authentik provider's name. + +- X-authentik-meta-app: `test` + + The authentik application's slug. + # HTTPS The outpost listens on both 9000 for HTTP and 9443 for HTTPS. From 7aa8e35f8742fd0a64982a4e65d40c37843ae608 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 1 Dec 2021 20:19:35 +0100 Subject: [PATCH 05/46] providers/proxy: use wildcard for traefik headers copy Signed-off-by: Jens Langhammer --- .../providers/proxy/controllers/k8s/traefik.py | 18 ++---------------- .../docs/providers/proxy/_traefik_compose.md | 2 +- .../docs/providers/proxy/_traefik_ingress.md | 8 +------- .../providers/proxy/_traefik_standalone.md | 8 +------- 4 files changed, 5 insertions(+), 31 deletions(-) diff --git a/authentik/providers/proxy/controllers/k8s/traefik.py b/authentik/providers/proxy/controllers/k8s/traefik.py index 623c343a8..0e87eb2be 100644 --- a/authentik/providers/proxy/controllers/k8s/traefik.py +++ b/authentik/providers/proxy/controllers/k8s/traefik.py @@ -20,7 +20,7 @@ class TraefikMiddlewareSpecForwardAuth: address: str # pylint: disable=invalid-name - authResponseHeaders: list[str] + authResponseHeadersRegex: str # pylint: disable=invalid-name trustForwardHeader: bool @@ -108,21 +108,7 @@ class TraefikMiddlewareReconciler(KubernetesObjectReconciler[TraefikMiddleware]) spec=TraefikMiddlewareSpec( forwardAuth=TraefikMiddlewareSpecForwardAuth( 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", - ], + authResponseHeadersRegex="^.*$", trustForwardHeader=True, ) ), diff --git a/website/docs/providers/proxy/_traefik_compose.md b/website/docs/providers/proxy/_traefik_compose.md index 25564f07a..bd88ffac3 100644 --- a/website/docs/providers/proxy/_traefik_compose.md +++ b/website/docs/providers/proxy/_traefik_compose.md @@ -50,7 +50,7 @@ services: traefik.http.routers.authentik.tls: true traefik.http.middlewares.authentik.forwardauth.address: http://outpost.company:9000/akprox/auth/traefik traefik.http.middlewares.authentik.forwardauth.trustForwardHeader: true - traefik.http.middlewares.authentik.forwardauth.authResponseHeaders: Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid + traefik.http.middlewares.authentik.forwardauth.authResponseHeadersRegex: ^.*$ restart: unless-stopped whoami: diff --git a/website/docs/providers/proxy/_traefik_ingress.md b/website/docs/providers/proxy/_traefik_ingress.md index dd0c2236f..da8ccbf76 100644 --- a/website/docs/providers/proxy/_traefik_ingress.md +++ b/website/docs/providers/proxy/_traefik_ingress.md @@ -9,13 +9,7 @@ spec: forwardAuth: address: http://outpost.company:9000/akprox/auth/traefik trustForwardHeader: true - authResponseHeaders: - - Set-Cookie - - X-authentik-username - - X-authentik-groups - - X-authentik-email - - X-authentik-name - - X-authentik-uid + authResponseHeadersRegex: ^.*$ ``` Add the following settings to your IngressRoute diff --git a/website/docs/providers/proxy/_traefik_standalone.md b/website/docs/providers/proxy/_traefik_standalone.md index c23157c29..1f0f555eb 100644 --- a/website/docs/providers/proxy/_traefik_standalone.md +++ b/website/docs/providers/proxy/_traefik_standalone.md @@ -5,13 +5,7 @@ http: forwardAuth: address: http://outpost.company:9000/akprox/auth/traefik trustForwardHeader: true - authResponseHeaders: - - Set-Cookie - - X-authentik-username - - X-authentik-groups - - X-authentik-email - - X-authentik-name - - X-authentik-uid + authResponseHeadersRegex: ^.*$ routers: default-router: rule: "Host(`app.company`)" From 62dc86be7b469b4e5e490f3398a55e72fc83caf3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 1 Dec 2021 20:21:51 +0100 Subject: [PATCH 06/46] web: Update Web API Client version (#1870) Signed-off-by: GitHub Co-authored-by: BeryJu --- 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 006bc6495..0a6ecde70 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -15,7 +15,7 @@ "@babel/preset-env": "^7.16.4", "@babel/preset-typescript": "^7.16.0", "@fortawesome/fontawesome-free": "^5.15.4", - "@goauthentik/api": "^2021.10.4-1638190705", + "@goauthentik/api": "^2021.10.4-1638386397", "@jackfranklin/rollup-plugin-markdown": "^0.3.0", "@lingui/cli": "^3.13.0", "@lingui/core": "^3.13.0", @@ -1708,9 +1708,9 @@ } }, "node_modules/@goauthentik/api": { - "version": "2021.10.4-1638190705", - "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.10.4-1638190705.tgz", - "integrity": "sha512-fEtKGX8F9BDnYWIF9vTxLEkqGkABRl+0M2sgCOd4XqiflNveDEQYMVZAK5yvNzCK8L4wIcbn7y8s/lCncEKJ2Q==" + "version": "2021.10.4-1638386397", + "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.10.4-1638386397.tgz", + "integrity": "sha512-W5iFNK9bcYdOYg7CVuloPmd2T7Ct+OWFMSWwiYSQcMzt3hj1Ff6g+CBLt2yCgq6zAQGeh5Le8lfk+uQKixc/Fw==" }, "node_modules/@humanwhocodes/config-array": { "version": "0.6.0", @@ -9895,9 +9895,9 @@ "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==" }, "@goauthentik/api": { - "version": "2021.10.4-1638190705", - "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.10.4-1638190705.tgz", - "integrity": "sha512-fEtKGX8F9BDnYWIF9vTxLEkqGkABRl+0M2sgCOd4XqiflNveDEQYMVZAK5yvNzCK8L4wIcbn7y8s/lCncEKJ2Q==" + "version": "2021.10.4-1638386397", + "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.10.4-1638386397.tgz", + "integrity": "sha512-W5iFNK9bcYdOYg7CVuloPmd2T7Ct+OWFMSWwiYSQcMzt3hj1Ff6g+CBLt2yCgq6zAQGeh5Le8lfk+uQKixc/Fw==" }, "@humanwhocodes/config-array": { "version": "0.6.0", diff --git a/web/package.json b/web/package.json index eb0e089b1..2606a43ae 100644 --- a/web/package.json +++ b/web/package.json @@ -51,7 +51,7 @@ "@babel/preset-env": "^7.16.4", "@babel/preset-typescript": "^7.16.0", "@fortawesome/fontawesome-free": "^5.15.4", - "@goauthentik/api": "^2021.10.4-1638190705", + "@goauthentik/api": "^2021.10.4-1638386397", "@jackfranklin/rollup-plugin-markdown": "^0.3.0", "@lingui/cli": "^3.13.0", "@lingui/core": "^3.13.0", From 31d597005fe385e2488e772c154b034c9956bf93 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Dec 2021 20:30:25 +0100 Subject: [PATCH 07/46] build(deps): bump goauthentik.io/api from 0.2021104.6 to 0.2021104.7 (#1871) Bumps [goauthentik.io/api](https://github.com/goauthentik/client-go) from 0.2021104.6 to 0.2021104.7. - [Release notes](https://github.com/goauthentik/client-go/releases) - [Commits](https://github.com/goauthentik/client-go/compare/v0.2021104.6...v0.2021104.7) --- updated-dependencies: - dependency-name: goauthentik.io/api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5fafe7245..5418b95ad 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/prometheus/client_golang v1.11.0 github.com/recws-org/recws v1.3.1 github.com/sirupsen/logrus v1.8.1 - goauthentik.io/api v0.2021104.6 + goauthentik.io/api v0.2021104.7 golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect golang.org/x/net v0.0.0-20210510120150-4163338589ed // indirect golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558 diff --git a/go.sum b/go.sum index 93a7fe65c..457f683a7 100644 --- a/go.sum +++ b/go.sum @@ -561,8 +561,8 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -goauthentik.io/api v0.2021104.6 h1:1Vyw1gnVm9D7htUXWTcy7Gg7ldU0V0vIhT8RFo9G/Iw= -goauthentik.io/api v0.2021104.6/go.mod h1:02nnD4FRd8lu8A1+ZuzqownBgvAhdCKzqkKX8v7JMTE= +goauthentik.io/api v0.2021104.7 h1:JWKypuvYWWPqq8c8xLN8qVv5ny8TqsfmLdqNwJM9bZk= +goauthentik.io/api v0.2021104.7/go.mod h1:02nnD4FRd8lu8A1+ZuzqownBgvAhdCKzqkKX8v7JMTE= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= From f2023a7af25170dfcfb31ef742c82e15e8171d38 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 1 Dec 2021 20:35:28 +0100 Subject: [PATCH 08/46] *: don't use go embed to make using custom files easier Signed-off-by: Jens Langhammer --- internal/outpost/proxyv2/handlers.go | 3 +-- internal/web/static.go | 23 ++++------------------- web/static.go | 8 +------- website/static.go | 6 ------ 4 files changed, 6 insertions(+), 34 deletions(-) delete mode 100644 website/static.go diff --git a/internal/outpost/proxyv2/handlers.go b/internal/outpost/proxyv2/handlers.go index 95045cc9c..8e1209473 100644 --- a/internal/outpost/proxyv2/handlers.go +++ b/internal/outpost/proxyv2/handlers.go @@ -10,7 +10,6 @@ import ( "github.com/prometheus/client_golang/prometheus" "goauthentik.io/internal/outpost/proxyv2/metrics" "goauthentik.io/internal/utils/web" - staticWeb "goauthentik.io/web" ) func (ps *ProxyServer) HandlePing(rw http.ResponseWriter, r *http.Request) { @@ -29,7 +28,7 @@ func (ps *ProxyServer) HandlePing(rw http.ResponseWriter, r *http.Request) { } func (ps *ProxyServer) HandleStatic(rw http.ResponseWriter, r *http.Request) { - staticFs := http.FileServer(http.FS(staticWeb.StaticDist)) + staticFs := http.FileServer(http.Dir("./website/static/")) before := time.Now() web.DisableIndex(http.StripPrefix("/akprox/static", staticFs)).ServeHTTP(rw, r) after := time.Since(before) diff --git a/internal/web/static.go b/internal/web/static.go index 0cb034696..9b47b2d61 100644 --- a/internal/web/static.go +++ b/internal/web/static.go @@ -9,7 +9,6 @@ import ( "goauthentik.io/internal/constants" "goauthentik.io/internal/utils/web" staticWeb "goauthentik.io/web" - staticDocs "goauthentik.io/website" ) func (ws *WebServer) configureStatic() { @@ -18,24 +17,10 @@ func (ws *WebServer) configureStatic() { indexLessRouter.Use(web.DisableIndex) // Media files, always local fs := http.FileServer(http.Dir(config.G.Paths.Media)) - var distHandler http.Handler - var distFs http.Handler - var authentikHandler http.Handler - var helpHandler http.Handler - if config.G.Debug || config.G.Web.LoadLocalFiles { - ws.log.Debug("Using local static files") - distFs = http.FileServer(http.Dir("./web/dist")) - distHandler = http.StripPrefix("/static/dist/", distFs) - authentikHandler = http.StripPrefix("/static/authentik/", http.FileServer(http.Dir("./web/authentik"))) - helpHandler = http.FileServer(http.Dir("./website/help/")) - } else { - statRouter.Use(ws.staticHeaderMiddleware) - ws.log.Debug("Using packaged static files with aggressive caching") - distFs = http.FileServer(http.FS(staticWeb.StaticDist)) - distHandler = http.StripPrefix("/static", distFs) - authentikHandler = http.StripPrefix("/static", http.FileServer(http.FS(staticWeb.StaticAuthentik))) - helpHandler = http.FileServer(http.FS(staticDocs.Help)) - } + distFs := http.FileServer(http.Dir("./web/dist")) + distHandler := http.StripPrefix("/static/dist/", distFs) + authentikHandler := http.StripPrefix("/static/authentik/", http.FileServer(http.Dir("./web/authentik"))) + helpHandler := http.FileServer(http.Dir("./website/help/")) indexLessRouter.PathPrefix("/static/dist/").Handler(distHandler) indexLessRouter.PathPrefix("/static/authentik/").Handler(authentikHandler) diff --git a/web/static.go b/web/static.go index 44ce69706..77934988b 100644 --- a/web/static.go +++ b/web/static.go @@ -1,12 +1,6 @@ package web -import "embed" - -//go:embed dist/* -var StaticDist embed.FS - -//go:embed authentik -var StaticAuthentik embed.FS +import _ "embed" //go:embed robots.txt var RobotsTxt []byte diff --git a/website/static.go b/website/static.go deleted file mode 100644 index 1c44b1d66..000000000 --- a/website/static.go +++ /dev/null @@ -1,6 +0,0 @@ -package web - -import "embed" - -//go:embed help/* -var Help embed.FS From d0ceafe79eb47bf933050cf504206491bf71c125 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 1 Dec 2021 20:41:55 +0100 Subject: [PATCH 09/46] outposts/proxy: add X-authentik-meta-version Signed-off-by: Jens Langhammer --- Dockerfile | 1 - internal/outpost/proxyv2/application/mode_common.go | 3 +++ internal/web/static.go | 1 + website/docs/providers/proxy/proxy.md | 4 ++++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index cb1a3f55e..f06df4d4c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -40,7 +40,6 @@ COPY --from=website-builder /work/website/help/ /work/website/help/ COPY ./cmd /work/cmd COPY ./web/static.go /work/web/static.go -COPY ./website/static.go /work/website/static.go COPY ./internal /work/internal COPY ./go.mod /work/go.mod COPY ./go.sum /work/go.sum diff --git a/internal/outpost/proxyv2/application/mode_common.go b/internal/outpost/proxyv2/application/mode_common.go index e3ff6ad30..1b0e94199 100644 --- a/internal/outpost/proxyv2/application/mode_common.go +++ b/internal/outpost/proxyv2/application/mode_common.go @@ -5,6 +5,8 @@ import ( "fmt" "net/http" "strings" + + "goauthentik.io/internal/constants" ) func (a *Application) addHeaders(headers http.Header, c *Claims) { @@ -28,6 +30,7 @@ func (a *Application) addHeaders(headers http.Header, c *Claims) { headers.Set("X-authentik-meta-outpost", a.outpostName) headers.Set("X-authentik-meta-provider", a.proxyConfig.Name) headers.Set("X-authentik-meta-app", a.proxyConfig.AssignedApplicationSlug) + headers.Set("X-authentik-meta-version", constants.OutpostUserAgent()) userAttributes := c.Proxy.UserAttributes // Attempt to set basic auth based on user's attributes diff --git a/internal/web/static.go b/internal/web/static.go index 9b47b2d61..7e7cf6772 100644 --- a/internal/web/static.go +++ b/internal/web/static.go @@ -13,6 +13,7 @@ import ( func (ws *WebServer) configureStatic() { statRouter := ws.lh.NewRoute().Subrouter() + statRouter.Use(ws.staticHeaderMiddleware) indexLessRouter := statRouter.NewRoute().Subrouter() indexLessRouter.Use(web.DisableIndex) // Media files, always local diff --git a/website/docs/providers/proxy/proxy.md b/website/docs/providers/proxy/proxy.md index 8f4c94533..ffcf643f3 100644 --- a/website/docs/providers/proxy/proxy.md +++ b/website/docs/providers/proxy/proxy.md @@ -42,6 +42,10 @@ Besides these user-specific headers, some application specific headers are also The authentik application's slug. +- X-authentik-meta-version: `authentik-outpost@1.2.3 (build=tagged)` + + The authentik outpost's version. + # HTTPS The outpost listens on both 9000 for HTTP and 9443 for HTTPS. From 0d237969894273f1b1fceda32887585226a8b241 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 1 Dec 2021 21:25:01 +0100 Subject: [PATCH 10/46] root: fix paths for dockerfile Signed-off-by: Jens Langhammer --- Dockerfile | 6 +++--- web/security.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index f06df4d4c..82de5c25a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,9 +34,6 @@ WORKDIR /work COPY --from=web-builder /work/web/robots.txt /work/web/robots.txt COPY --from=web-builder /work/web/security.txt /work/web/security.txt -COPY --from=web-builder /work/web/dist/ /work/web/dist/ -COPY --from=web-builder /work/web/authentik/ /work/web/authentik/ -COPY --from=website-builder /work/website/help/ /work/website/help/ COPY ./cmd /work/cmd COPY ./web/static.go /work/web/static.go @@ -77,6 +74,9 @@ COPY ./tests /tests COPY ./manage.py / COPY ./lifecycle/ /lifecycle COPY --from=builder /work/authentik /authentik-proxy +COPY --from=web-builder /work/web/dist/ /web/dist/ +COPY --from=web-builder /work/web/authentik/ /web/authentik/ +COPY --from=website-builder /work/website/help/ /website/help/ USER authentik diff --git a/web/security.txt b/web/security.txt index 8e62db8c1..32a882543 100644 --- a/web/security.txt +++ b/web/security.txt @@ -1,4 +1,4 @@ Contact: mailto:security@beryju.org -Expires: Sat, 1 Jan 2022 00:00 +0200 +Expires: Sat, 1 Jan 2023 00:00 +0200 Preferred-Languages: en, de Policy: https://github.com/goauthentik/authentik/blob/master/SECURITY.md From b4963bec76b7a42534580cf6ed197db7752c6a28 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Wed, 1 Dec 2021 21:47:13 +0100 Subject: [PATCH 11/46] providers/proxy: fix defaults for traefik integration Signed-off-by: Jens Langhammer --- authentik/providers/proxy/controllers/k8s/traefik.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/authentik/providers/proxy/controllers/k8s/traefik.py b/authentik/providers/proxy/controllers/k8s/traefik.py index 0e87eb2be..9a0602ff3 100644 --- a/authentik/providers/proxy/controllers/k8s/traefik.py +++ b/authentik/providers/proxy/controllers/k8s/traefik.py @@ -20,9 +20,11 @@ class TraefikMiddlewareSpecForwardAuth: address: str # pylint: disable=invalid-name - authResponseHeadersRegex: str + authResponseHeadersRegex: str = field(default="") # pylint: disable=invalid-name - trustForwardHeader: bool + authResponseHeaders: list[str] = field(default_factory=list) + # pylint: disable=invalid-name + trustForwardHeader: bool = field(default=True) @dataclass @@ -108,6 +110,7 @@ class TraefikMiddlewareReconciler(KubernetesObjectReconciler[TraefikMiddleware]) spec=TraefikMiddlewareSpec( forwardAuth=TraefikMiddlewareSpecForwardAuth( address=f"http://{self.name}.{self.namespace}:9000/akprox/auth/traefik", + authResponseHeaders=[], authResponseHeadersRegex="^.*$", trustForwardHeader=True, ) From e917e756cce2fa17ed0b0c0f2d65067cd2303812 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 09:58:50 +0100 Subject: [PATCH 12/46] outposts/proxy: make logging fields more consistent Signed-off-by: Jens Langhammer --- internal/outpost/proxyv2/application/application.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/outpost/proxyv2/application/application.go b/internal/outpost/proxyv2/application/application.go index 24dc153ab..c086c1096 100644 --- a/internal/outpost/proxyv2/application/application.go +++ b/internal/outpost/proxyv2/application/application.go @@ -94,14 +94,14 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore if !ok { return l } - return l.WithField("request_username", c.Email) + return l.WithField("request_username", c.PreferredUsername) })) mux.Use(func(inner http.Handler) http.Handler { return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { c, _ := a.getClaims(r) user := "" if c != nil { - user = c.Email + user = c.PreferredUsername } before := time.Now() inner.ServeHTTP(rw, r) From e42ad8db9312f512b0b80f3a4d5056200e1bddcc Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 10:01:54 +0100 Subject: [PATCH 13/46] outposts/proxy: copy user-agent header from upstream request Signed-off-by: Jens Langhammer --- internal/outpost/proxyv2/application/mode_forward.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/outpost/proxyv2/application/mode_forward.go b/internal/outpost/proxyv2/application/mode_forward.go index 6a4a83193..889e115c2 100644 --- a/internal/outpost/proxyv2/application/mode_forward.go +++ b/internal/outpost/proxyv2/application/mode_forward.go @@ -27,6 +27,7 @@ func (a *Application) forwardHandleTraefik(rw http.ResponseWriter, r *http.Reque claims, err := a.getClaims(r) if claims != nil && err == nil { a.addHeaders(rw.Header(), claims) + rw.Header().Set("User-Agent", r.Header.Get("User-Agent")) a.log.WithField("headers", rw.Header()).Trace("headers written to forward_auth") return } else if claims == nil && a.IsAllowlisted(r) { @@ -70,6 +71,7 @@ func (a *Application) forwardHandleNginx(rw http.ResponseWriter, r *http.Request claims, err := a.getClaims(r) if claims != nil && err == nil { a.addHeaders(rw.Header(), claims) + rw.Header().Set("User-Agent", r.Header.Get("User-Agent")) rw.WriteHeader(200) a.log.WithField("headers", rw.Header()).Trace("headers written to forward_auth") return From f0d7edb963306151a8a9306a605d29d0b9dcdca5 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 10:05:51 +0100 Subject: [PATCH 14/46] *: fix @prefill_task Signed-off-by: Jens Langhammer --- authentik/admin/tasks.py | 2 +- authentik/core/tasks.py | 4 ++-- authentik/events/monitored_tasks.py | 10 +++++----- authentik/managed/tasks.py | 2 +- authentik/outposts/tasks.py | 4 ++-- authentik/policies/reputation/tasks.py | 4 ++-- authentik/sources/saml/tasks.py | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/authentik/admin/tasks.py b/authentik/admin/tasks.py index 3602a24e4..2c7e91810 100644 --- a/authentik/admin/tasks.py +++ b/authentik/admin/tasks.py @@ -54,7 +54,7 @@ def clear_update_notifications(): @CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task() +@prefill_task def update_latest_version(self: MonitoredTask): """Update latest version info""" if CONFIG.y_bool("disable_update_check"): diff --git a/authentik/core/tasks.py b/authentik/core/tasks.py index df45b4d4b..3e18c50b4 100644 --- a/authentik/core/tasks.py +++ b/authentik/core/tasks.py @@ -29,7 +29,7 @@ LOGGER = get_logger() @CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task() +@prefill_task def clean_expired_models(self: MonitoredTask): """Remove expired objects""" messages = [] @@ -69,7 +69,7 @@ def should_backup() -> bool: @CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task() +@prefill_task def backup_database(self: MonitoredTask): # pragma: no cover """Database backup""" self.result_timeout_hours = 25 diff --git a/authentik/events/monitored_tasks.py b/authentik/events/monitored_tasks.py index 707aa0d3c..9c71ca6f5 100644 --- a/authentik/events/monitored_tasks.py +++ b/authentik/events/monitored_tasks.py @@ -112,13 +112,13 @@ class TaskInfo: cache.set(key, self, timeout=timeout_hours * 60 * 60) -def prefill_task(): +def prefill_task(func): """Ensure a task's details are always in cache, so it can always be triggered via API""" - def inner_wrap(func): + def wrapper(*args, **kwargs): status = TaskInfo.by_name(func.__name__) if status: - return func + return func(*args, **kwargs) TaskInfo( task_name=func.__name__, task_description=func.__doc__, @@ -131,9 +131,9 @@ def prefill_task(): finish_time=datetime.now(), ).save(86400) LOGGER.debug("prefilled task", task_name=func.__name__) - return func + return func(*args, **kwargs) - return inner_wrap + return wrapper class MonitoredTask(Task): diff --git a/authentik/managed/tasks.py b/authentik/managed/tasks.py index 5d2ebd996..2cc9b21d2 100644 --- a/authentik/managed/tasks.py +++ b/authentik/managed/tasks.py @@ -12,7 +12,7 @@ from authentik.managed.manager import ObjectManager @CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task() +@prefill_task def managed_reconcile(self: MonitoredTask): """Run ObjectManager to ensure objects are up-to-date""" try: diff --git a/authentik/outposts/tasks.py b/authentik/outposts/tasks.py index 63d7f4370..737b1ef15 100644 --- a/authentik/outposts/tasks.py +++ b/authentik/outposts/tasks.py @@ -76,7 +76,7 @@ def outpost_service_connection_state(connection_pk: Any): @CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task() +@prefill_task def outpost_service_connection_monitor(self: MonitoredTask): """Regularly check the state of Outpost Service Connections""" connections = OutpostServiceConnection.objects.all() @@ -126,7 +126,7 @@ def outpost_controller( @CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task() +@prefill_task def outpost_token_ensurer(self: MonitoredTask): """Periodically ensure that all Outposts have valid Service Accounts and Tokens""" diff --git a/authentik/policies/reputation/tasks.py b/authentik/policies/reputation/tasks.py index eb6dcd6e3..3126dfca8 100644 --- a/authentik/policies/reputation/tasks.py +++ b/authentik/policies/reputation/tasks.py @@ -16,7 +16,7 @@ LOGGER = get_logger() @CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task() +@prefill_task def save_ip_reputation(self: MonitoredTask): """Save currently cached reputation to database""" objects_to_update = [] @@ -30,7 +30,7 @@ def save_ip_reputation(self: MonitoredTask): @CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task() +@prefill_task def save_user_reputation(self: MonitoredTask): """Save currently cached reputation to database""" objects_to_update = [] diff --git a/authentik/sources/saml/tasks.py b/authentik/sources/saml/tasks.py index 5c495956f..cb72d55d0 100644 --- a/authentik/sources/saml/tasks.py +++ b/authentik/sources/saml/tasks.py @@ -17,7 +17,7 @@ LOGGER = get_logger() @CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task() +@prefill_task def clean_temporary_users(self: MonitoredTask): """Remove temporary users created by SAML Sources""" _now = now() From 4f54ce6afb95064c5fd81b2ed0f3399a0f2a752b Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 12:56:29 +0100 Subject: [PATCH 15/46] providers/saml: fix error when using post bindings and user freshly logged in Signed-off-by: Jens Langhammer #1873 --- authentik/flows/views/executor.py | 1 + authentik/policies/views.py | 6 +++++- authentik/providers/saml/views/sso.py | 16 +++++++++++----- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/authentik/flows/views/executor.py b/authentik/flows/views/executor.py index a1a4691ae..82707e9fd 100644 --- a/authentik/flows/views/executor.py +++ b/authentik/flows/views/executor.py @@ -53,6 +53,7 @@ NEXT_ARG_NAME = "next" SESSION_KEY_PLAN = "authentik_flows_plan" SESSION_KEY_APPLICATION_PRE = "authentik_flows_application_pre" SESSION_KEY_GET = "authentik_flows_get" +SESSION_KEY_POST = "authentik_flows_post" SESSION_KEY_HISTORY = "authentik_flows_history" diff --git a/authentik/policies/views.py b/authentik/policies/views.py index c45cc9943..192183017 100644 --- a/authentik/policies/views.py +++ b/authentik/policies/views.py @@ -10,7 +10,7 @@ from django.views.generic.base import View from structlog.stdlib import get_logger from authentik.core.models import Application, Provider, User -from authentik.flows.views.executor import SESSION_KEY_APPLICATION_PRE +from authentik.flows.views.executor import SESSION_KEY_APPLICATION_PRE, SESSION_KEY_POST from authentik.lib.sentry import SentryIgnoredException from authentik.policies.denied import AccessDeniedResponse from authentik.policies.engine import PolicyEngine @@ -84,6 +84,10 @@ class PolicyAccessView(AccessMixin, View): a hint on the Identification Stage what the user should login for.""" if self.application: self.request.session[SESSION_KEY_APPLICATION_PRE] = self.application + # Because this view might get hit with a POST request, we need to preserve that data + # since later views might need it (mostly SAML) + if self.request.method.lower() == "post": + self.request.session[SESSION_KEY_POST] = self.request.POST return redirect_to_login( self.request.get_full_path(), self.get_login_url(), diff --git a/authentik/providers/saml/views/sso.py b/authentik/providers/saml/views/sso.py index 3e470b087..4a534c09d 100644 --- a/authentik/providers/saml/views/sso.py +++ b/authentik/providers/saml/views/sso.py @@ -13,7 +13,7 @@ from authentik.core.models import Application from authentik.events.models import Event, EventAction from authentik.flows.models import in_memory_stage from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, PLAN_CONTEXT_SSO, FlowPlanner -from authentik.flows.views.executor import SESSION_KEY_PLAN +from authentik.flows.views.executor import SESSION_KEY_PLAN, SESSION_KEY_POST from authentik.lib.utils.urls import redirect_with_qs from authentik.lib.views import bad_request_message from authentik.policies.views import PolicyAccessView @@ -37,7 +37,7 @@ LOGGER = get_logger() class SAMLSSOView(PolicyAccessView): - """ "SAML SSO Base View, which plans a flow and injects our final stage. + """SAML SSO Base View, which plans a flow and injects our final stage. Calls get/post handler.""" def resolve_provider_application(self): @@ -120,14 +120,20 @@ class SAMLSSOBindingPOSTView(SAMLSSOView): def check_saml_request(self) -> Optional[HttpRequest]: """Handle POST bindings""" - if REQUEST_KEY_SAML_REQUEST not in self.request.POST: + payload = self.request.POST + # Restore the post body from the session + # This happens when using POST bindings but the user isn't logged in + # (user gets redirected and POST body is 'lost') + if SESSION_KEY_POST in self.request.session: + payload = self.request.session[SESSION_KEY_POST] + if REQUEST_KEY_SAML_REQUEST not in payload: LOGGER.info("check_saml_request: SAML payload missing") return bad_request_message(self.request, "The SAML request payload is missing.") try: auth_n_request = AuthNRequestParser(self.provider).parse( - self.request.POST[REQUEST_KEY_SAML_REQUEST], - self.request.POST.get(REQUEST_KEY_RELAY_STATE), + payload[REQUEST_KEY_SAML_REQUEST], + payload.get(REQUEST_KEY_RELAY_STATE), ) self.request.session[SESSION_KEY_AUTH_N_REQUEST] = auth_n_request except CannotHandleAssertion as exc: From 20c738c384c22922aeb5a2abb104a9b8cf9c4807 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 13:00:41 +0100 Subject: [PATCH 16/46] crypto: fix default API not having an ordering Signed-off-by: Jens Langhammer --- authentik/crypto/api.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/authentik/crypto/api.py b/authentik/crypto/api.py index 2c9a0baaa..4eb02dddc 100644 --- a/authentik/crypto/api.py +++ b/authentik/crypto/api.py @@ -144,6 +144,8 @@ class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet): queryset = CertificateKeyPair.objects.exclude(managed__isnull=False) serializer_class = CertificateKeyPairSerializer filterset_class = CertificateKeyPairFilter + ordering = ["name"] + search_fields = ["name"] @permission_required(None, ["authentik_crypto.add_certificatekeypair"]) @extend_schema( From cf78c898309ed71607d04a72cb274bb25b928cfc Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 13:29:08 +0100 Subject: [PATCH 17/46] events: replace @prefill_task with custom base class to prefill Signed-off-by: Jens Langhammer --- authentik/admin/tasks.py | 12 ++----- authentik/core/tasks.py | 17 +++------ authentik/events/monitored_tasks.py | 50 +++++++++++++------------- authentik/managed/tasks.py | 12 ++----- authentik/outposts/tasks.py | 12 +++---- authentik/policies/reputation/tasks.py | 17 +++------ authentik/sources/saml/tasks.py | 12 ++----- 7 files changed, 50 insertions(+), 82 deletions(-) diff --git a/authentik/admin/tasks.py b/authentik/admin/tasks.py index 2c7e91810..e5672a132 100644 --- a/authentik/admin/tasks.py +++ b/authentik/admin/tasks.py @@ -11,12 +11,7 @@ from structlog.stdlib import get_logger from authentik import ENV_GIT_HASH_KEY, __version__ from authentik.events.models import Event, EventAction, Notification -from authentik.events.monitored_tasks import ( - MonitoredTask, - TaskResult, - TaskResultStatus, - prefill_task, -) +from authentik.events.monitored_tasks import PrefilledMonitoredTask, TaskResult, TaskResultStatus from authentik.lib.config import CONFIG from authentik.lib.utils.http import get_http_session from authentik.root.celery import CELERY_APP @@ -53,9 +48,8 @@ def clear_update_notifications(): notification.delete() -@CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task -def update_latest_version(self: MonitoredTask): +@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) +def update_latest_version(self: PrefilledMonitoredTask): """Update latest version info""" if CONFIG.y_bool("disable_update_check"): cache.set(VERSION_CACHE_KEY, "0.0.0", VERSION_CACHE_TIMEOUT) diff --git a/authentik/core/tasks.py b/authentik/core/tasks.py index 3e18c50b4..79e250202 100644 --- a/authentik/core/tasks.py +++ b/authentik/core/tasks.py @@ -16,21 +16,15 @@ from kubernetes.config.incluster_config import SERVICE_HOST_ENV_NAME from structlog.stdlib import get_logger from authentik.core.models import AuthenticatedSession, ExpiringModel -from authentik.events.monitored_tasks import ( - MonitoredTask, - TaskResult, - TaskResultStatus, - prefill_task, -) +from authentik.events.monitored_tasks import PrefilledMonitoredTask, TaskResult, TaskResultStatus from authentik.lib.config import CONFIG from authentik.root.celery import CELERY_APP LOGGER = get_logger() -@CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task -def clean_expired_models(self: MonitoredTask): +@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) +def clean_expired_models(self: PrefilledMonitoredTask): """Remove expired objects""" messages = [] for cls in ExpiringModel.__subclasses__(): @@ -68,9 +62,8 @@ def should_backup() -> bool: return True -@CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task -def backup_database(self: MonitoredTask): # pragma: no cover +@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) +def backup_database(self: PrefilledMonitoredTask): # pragma: no cover """Database backup""" self.result_timeout_hours = 25 if not should_backup(): diff --git a/authentik/events/monitored_tasks.py b/authentik/events/monitored_tasks.py index 9c71ca6f5..138b4070c 100644 --- a/authentik/events/monitored_tasks.py +++ b/authentik/events/monitored_tasks.py @@ -112,30 +112,6 @@ class TaskInfo: cache.set(key, self, timeout=timeout_hours * 60 * 60) -def prefill_task(func): - """Ensure a task's details are always in cache, so it can always be triggered via API""" - - def wrapper(*args, **kwargs): - status = TaskInfo.by_name(func.__name__) - if status: - return func(*args, **kwargs) - TaskInfo( - task_name=func.__name__, - task_description=func.__doc__, - result=TaskResult(TaskResultStatus.UNKNOWN, messages=[_("Task has not been run yet.")]), - task_call_module=func.__module__, - task_call_func=func.__name__, - # We don't have real values for these attributes but they cannot be null - start_timestamp=default_timer(), - finish_timestamp=default_timer(), - finish_time=datetime.now(), - ).save(86400) - LOGGER.debug("prefilled task", task_name=func.__name__) - return func(*args, **kwargs) - - return wrapper - - class MonitoredTask(Task): """Task which can save its state to the cache""" @@ -210,5 +186,31 @@ class MonitoredTask(Task): raise NotImplementedError +class PrefilledMonitoredTask(MonitoredTask): + """Subclass of MonitoredTask, but create entry in cache if task hasn't been run + Does not support UID""" + + def __init__(self, *args, **kwargs) -> None: + super().__init__(*args, **kwargs) + status = TaskInfo.by_name(self.__name__) + if status: + return + TaskInfo( + task_name=self.__name__, + task_description=self.__doc__, + result=TaskResult(TaskResultStatus.UNKNOWN, messages=[_("Task has not been run yet.")]), + task_call_module=self.__module__, + task_call_func=self.__name__, + # We don't have real values for these attributes but they cannot be null + start_timestamp=default_timer(), + finish_timestamp=default_timer(), + finish_time=datetime.now(), + ).save(86400) + LOGGER.debug("prefilled task", task_name=self.__name__) + + def run(self, *args, **kwargs): + raise NotImplementedError + + for task in TaskInfo.all().values(): task.set_prom_metrics() diff --git a/authentik/managed/tasks.py b/authentik/managed/tasks.py index 2cc9b21d2..118b9c370 100644 --- a/authentik/managed/tasks.py +++ b/authentik/managed/tasks.py @@ -2,18 +2,12 @@ from django.db import DatabaseError from authentik.core.tasks import CELERY_APP -from authentik.events.monitored_tasks import ( - MonitoredTask, - TaskResult, - TaskResultStatus, - prefill_task, -) +from authentik.events.monitored_tasks import PrefilledMonitoredTask, TaskResult, TaskResultStatus from authentik.managed.manager import ObjectManager -@CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task -def managed_reconcile(self: MonitoredTask): +@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) +def managed_reconcile(self: PrefilledMonitoredTask): """Run ObjectManager to ensure objects are up-to-date""" try: ObjectManager().run() diff --git a/authentik/outposts/tasks.py b/authentik/outposts/tasks.py index 737b1ef15..820f585f6 100644 --- a/authentik/outposts/tasks.py +++ b/authentik/outposts/tasks.py @@ -19,9 +19,9 @@ from structlog.stdlib import get_logger from authentik.events.monitored_tasks import ( MonitoredTask, + PrefilledMonitoredTask, TaskResult, TaskResultStatus, - prefill_task, ) from authentik.lib.utils.reflection import path_to_class from authentik.outposts.controllers.base import BaseController, ControllerException @@ -75,9 +75,8 @@ def outpost_service_connection_state(connection_pk: Any): cache.set(connection.state_key, state, timeout=None) -@CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task -def outpost_service_connection_monitor(self: MonitoredTask): +@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) +def outpost_service_connection_monitor(self: PrefilledMonitoredTask): """Regularly check the state of Outpost Service Connections""" connections = OutpostServiceConnection.objects.all() for connection in connections.iterator(): @@ -125,9 +124,8 @@ def outpost_controller( self.set_status(TaskResult(TaskResultStatus.SUCCESSFUL, logs)) -@CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task -def outpost_token_ensurer(self: MonitoredTask): +@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) +def outpost_token_ensurer(self: PrefilledMonitoredTask): """Periodically ensure that all Outposts have valid Service Accounts and Tokens""" all_outposts = Outpost.objects.all() diff --git a/authentik/policies/reputation/tasks.py b/authentik/policies/reputation/tasks.py index 3126dfca8..49b1590d1 100644 --- a/authentik/policies/reputation/tasks.py +++ b/authentik/policies/reputation/tasks.py @@ -2,12 +2,7 @@ from django.core.cache import cache from structlog.stdlib import get_logger -from authentik.events.monitored_tasks import ( - MonitoredTask, - TaskResult, - TaskResultStatus, - prefill_task, -) +from authentik.events.monitored_tasks import PrefilledMonitoredTask, TaskResult, TaskResultStatus from authentik.policies.reputation.models import IPReputation, UserReputation from authentik.policies.reputation.signals import CACHE_KEY_IP_PREFIX, CACHE_KEY_USER_PREFIX from authentik.root.celery import CELERY_APP @@ -15,9 +10,8 @@ from authentik.root.celery import CELERY_APP LOGGER = get_logger() -@CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task -def save_ip_reputation(self: MonitoredTask): +@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) +def save_ip_reputation(self: PrefilledMonitoredTask): """Save currently cached reputation to database""" objects_to_update = [] for key, score in cache.get_many(cache.keys(CACHE_KEY_IP_PREFIX + "*")).items(): @@ -29,9 +23,8 @@ def save_ip_reputation(self: MonitoredTask): self.set_status(TaskResult(TaskResultStatus.SUCCESSFUL, ["Successfully updated IP Reputation"])) -@CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task -def save_user_reputation(self: MonitoredTask): +@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) +def save_user_reputation(self: PrefilledMonitoredTask): """Save currently cached reputation to database""" objects_to_update = [] for key, score in cache.get_many(cache.keys(CACHE_KEY_USER_PREFIX + "*")).items(): diff --git a/authentik/sources/saml/tasks.py b/authentik/sources/saml/tasks.py index cb72d55d0..fb85b3088 100644 --- a/authentik/sources/saml/tasks.py +++ b/authentik/sources/saml/tasks.py @@ -3,12 +3,7 @@ from django.utils.timezone import now from structlog.stdlib import get_logger from authentik.core.models import AuthenticatedSession, User -from authentik.events.monitored_tasks import ( - MonitoredTask, - TaskResult, - TaskResultStatus, - prefill_task, -) +from authentik.events.monitored_tasks import PrefilledMonitoredTask, TaskResult, TaskResultStatus from authentik.lib.utils.time import timedelta_from_string from authentik.root.celery import CELERY_APP from authentik.sources.saml.models import SAMLSource @@ -16,9 +11,8 @@ from authentik.sources.saml.models import SAMLSource LOGGER = get_logger() -@CELERY_APP.task(bind=True, base=MonitoredTask) -@prefill_task -def clean_temporary_users(self: MonitoredTask): +@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) +def clean_temporary_users(self: PrefilledMonitoredTask): """Remove temporary users created by SAML Sources""" _now = now() messages = [] From 347c3793fc265879d50fb31bce2a494bdf8a11f5 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 14:19:57 +0100 Subject: [PATCH 18/46] outposts/proxy: add additional headers Signed-off-by: Jens Langhammer --- internal/outpost/proxyv2/application/claims.go | 2 ++ internal/outpost/proxyv2/application/mode_common.go | 2 ++ internal/outpost/proxyv2/application/oauth_callback.go | 1 + 3 files changed, 5 insertions(+) diff --git a/internal/outpost/proxyv2/application/claims.go b/internal/outpost/proxyv2/application/claims.go index 40cd148a2..4ff89dbff 100644 --- a/internal/outpost/proxyv2/application/claims.go +++ b/internal/outpost/proxyv2/application/claims.go @@ -13,4 +13,6 @@ type Claims struct { Name string `json:"name"` PreferredUsername string `json:"preferred_username"` Groups []string `json:"groups"` + + RawToken string } diff --git a/internal/outpost/proxyv2/application/mode_common.go b/internal/outpost/proxyv2/application/mode_common.go index 1b0e94199..a1430ad1e 100644 --- a/internal/outpost/proxyv2/application/mode_common.go +++ b/internal/outpost/proxyv2/application/mode_common.go @@ -25,8 +25,10 @@ func (a *Application) addHeaders(headers http.Header, c *Claims) { headers.Set("X-authentik-email", c.Email) headers.Set("X-authentik-name", c.Name) headers.Set("X-authentik-uid", c.Sub) + headers.Set("X-authentik-jwt", c.RawToken) // System headers + headers.Set("X-authentik-meta-jwks", a.proxyConfig.OidcConfiguration.JwksUri) headers.Set("X-authentik-meta-outpost", a.outpostName) headers.Set("X-authentik-meta-provider", a.proxyConfig.Name) headers.Set("X-authentik-meta-app", a.proxyConfig.AssignedApplicationSlug) diff --git a/internal/outpost/proxyv2/application/oauth_callback.go b/internal/outpost/proxyv2/application/oauth_callback.go index 7f2937184..acd66cf31 100644 --- a/internal/outpost/proxyv2/application/oauth_callback.go +++ b/internal/outpost/proxyv2/application/oauth_callback.go @@ -45,5 +45,6 @@ func (a *Application) redeemCallback(r *http.Request, shouldState string) (*Clai if err := idToken.Claims(&claims); err != nil { return nil, err } + claims.RawToken = rawIDToken return claims, nil } From 66c530ea06d02f52464856bf4561c3a8aa5df4e5 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 15:06:14 +0100 Subject: [PATCH 19/46] outposts: always trigger outpost reconcile on startup Signed-off-by: Jens Langhammer --- authentik/outposts/apps.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/authentik/outposts/apps.py b/authentik/outposts/apps.py index 0ee7aa9d1..c4e9554ec 100644 --- a/authentik/outposts/apps.py +++ b/authentik/outposts/apps.py @@ -19,8 +19,9 @@ class AuthentikOutpostConfig(AppConfig): import_module("authentik.outposts.signals") import_module("authentik.outposts.managed") try: - from authentik.outposts.tasks import outpost_local_connection + from authentik.outposts.tasks import outpost_controller_all, outpost_local_connection outpost_local_connection.delay() + outpost_controller_all.delay() except ProgrammingError: pass From 85a417d22e926aa40d25b24bd345838188cb5b0b Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 15:17:32 +0100 Subject: [PATCH 20/46] outposts/proxy: re-add rs256 support Signed-off-by: Jens Langhammer --- internal/outpost/proxyv2/application/application.go | 11 +++++++++-- internal/outpost/proxyv2/application/utils.go | 9 +++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/internal/outpost/proxyv2/application/application.go b/internal/outpost/proxyv2/application/application.go index c086c1096..c88bc9b54 100644 --- a/internal/outpost/proxyv2/application/application.go +++ b/internal/outpost/proxyv2/application/application.go @@ -1,6 +1,7 @@ package application import ( + "context" "crypto/tls" "encoding/gob" "fmt" @@ -52,11 +53,17 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore return nil, fmt.Errorf("failed to parse URL, skipping provider") } - ks := hs256.NewKeySet(*p.ClientSecret) + var ks oidc.KeySet + if contains(p.OidcConfiguration.IdTokenSigningAlgValuesSupported, "HS256") { + ks = hs256.NewKeySet(*p.ClientSecret) + } else { + ctx := context.WithValue(context.Background(), oauth2.HTTPClient, c) + ks = oidc.NewRemoteKeySet(ctx, p.OidcConfiguration.JwksUri) + } var verifier = oidc.NewVerifier(p.OidcConfiguration.Issuer, ks, &oidc.Config{ ClientID: *p.ClientId, - SupportedSigningAlgs: []string{"HS256"}, + SupportedSigningAlgs: []string{"RS256", "HS256"}, }) // Configure an OpenID Connect aware OAuth2 client. diff --git a/internal/outpost/proxyv2/application/utils.go b/internal/outpost/proxyv2/application/utils.go index fad584620..d2423e125 100644 --- a/internal/outpost/proxyv2/application/utils.go +++ b/internal/outpost/proxyv2/application/utils.go @@ -56,3 +56,12 @@ func toString(in interface{}) string { } return "" } + +func contains(s []string, e string) bool { + for _, a := range s { + if a == e { + return true + } + } + return false +} From fdd5211253dc8ce8d13c5207e59545ddb5ca123b Mon Sep 17 00:00:00 2001 From: Jeremy Willans <31495062+jeremywillans@users.noreply.github.com> Date: Thu, 2 Dec 2021 22:27:47 +0800 Subject: [PATCH 21/46] web/flows: Revise duo authenticator login prompt text (#1872) --- .../authenticator_validate/AuthenticatorValidateStage.ts | 2 +- web/src/locales/en.po | 4 ++-- web/src/locales/pseudo-LOCALE.po | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/web/src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts b/web/src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts index 7418f6a10..9721122c5 100644 --- a/web/src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts +++ b/web/src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts @@ -101,7 +101,7 @@ export class AuthenticatorValidateStage

${t`Duo push-notifications`}

${t`Receive a push notification on your phone to prove your identity.`}${t`Receive a push notification on your device.`}
`; case DeviceClassesEnum.Webauthn: diff --git a/web/src/locales/en.po b/web/src/locales/en.po index ba30103b8..c261429d2 100644 --- a/web/src/locales/en.po +++ b/web/src/locales/en.po @@ -3612,8 +3612,8 @@ msgid "Re-evaluate policies" msgstr "Re-evaluate policies" #: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts -msgid "Receive a push notification on your phone to prove your identity." -msgstr "Receive a push notification on your phone to prove your identity." +msgid "Receive a push notification on your device." +msgstr "Receive a push notification on your device." #: src/pages/flows/utils.ts #: src/pages/tokens/TokenListPage.ts diff --git a/web/src/locales/pseudo-LOCALE.po b/web/src/locales/pseudo-LOCALE.po index c7636c6de..f58cab15b 100644 --- a/web/src/locales/pseudo-LOCALE.po +++ b/web/src/locales/pseudo-LOCALE.po @@ -3604,7 +3604,7 @@ msgid "Re-evaluate policies" msgstr "" #: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts -msgid "Receive a push notification on your phone to prove your identity." +msgid "Receive a push notification on your device." msgstr "" #: src/pages/flows/utils.ts From 40404ff41d6327eced46b3e9c3a91c9e23abe535 Mon Sep 17 00:00:00 2001 From: Ilya Kogan <1840337+ikogan@users.noreply.github.com> Date: Thu, 2 Dec 2021 09:28:58 -0500 Subject: [PATCH 22/46] outposts/ldap: Rework/improve LDAP search logic. (#1687) * outposts/ldap: Refactor searching so we key primarily off base dn * docs: Updating guides on sssd and the ldap outpost. --- go.mod | 1 + go.sum | 2 + internal/outpost/ldap/constants/constants.go | 45 ++++ internal/outpost/ldap/instance.go | 84 ++++++ internal/outpost/ldap/search/direct/direct.go | 252 +++++++++++------- internal/outpost/ldap/search/memory/base.go | 54 ---- internal/outpost/ldap/search/memory/memory.go | 190 ++++++++----- internal/outpost/ldap/search/searcher.go | 4 +- internal/outpost/ldap/server/base.go | 4 + internal/outpost/ldap/utils/utils.go | 33 +++ website/docs/providers/ldap.md | 5 + website/integrations/services/sssd/index.md | 141 ++++++++++ website/sidebarsIntegrations.js | 1 + 13 files changed, 597 insertions(+), 219 deletions(-) delete mode 100644 internal/outpost/ldap/search/memory/base.go create mode 100644 website/integrations/services/sssd/index.md diff --git a/go.mod b/go.mod index 5418b95ad..66d5e72d3 100644 --- a/go.mod +++ b/go.mod @@ -33,6 +33,7 @@ require ( golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect golang.org/x/net v0.0.0-20210510120150-4163338589ed // indirect golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558 + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect google.golang.org/appengine v1.6.7 // indirect gopkg.in/boj/redistore.v1 v1.0.0-20160128113310-fc113767cd6b gopkg.in/square/go-jose.v2 v2.5.1 // indirect diff --git a/go.sum b/go.sum index 457f683a7..0279435df 100644 --- a/go.sum +++ b/go.sum @@ -672,6 +672,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/internal/outpost/ldap/constants/constants.go b/internal/outpost/ldap/constants/constants.go index d791544d9..f4a5a612d 100644 --- a/internal/outpost/ldap/constants/constants.go +++ b/internal/outpost/ldap/constants/constants.go @@ -1,5 +1,11 @@ package constants +const ( + OCTop = "top" + OCDomain = "domain" + OCNSContainer = "nsContainer" +) + const ( OCGroup = "group" OCGroupOfUniqueNames = "groupOfUniqueNames" @@ -19,3 +25,42 @@ const ( OUGroups = "groups" OUVirtualGroups = "virtual-groups" ) + +func GetDomainOCs() map[string]bool { + return map[string]bool{ + OCTop: true, + OCDomain: true, + } +} + +func GetContainerOCs() map[string]bool { + return map[string]bool{ + OCTop: true, + OCNSContainer: true, + } +} + +func GetUserOCs() map[string]bool { + return map[string]bool{ + OCUser: true, + OCOrgPerson: true, + OCInetOrgPerson: true, + OCAKUser: true, + } +} + +func GetGroupOCs() map[string]bool { + return map[string]bool{ + OCGroup: true, + OCGroupOfUniqueNames: true, + OCAKGroup: true, + } +} + +func GetVirtualGroupOCs() map[string]bool { + return map[string]bool{ + OCGroup: true, + OCGroupOfUniqueNames: true, + OCAKVirtualGroup: true, + } +} diff --git a/internal/outpost/ldap/instance.go b/internal/outpost/ldap/instance.go index 21352518f..1e1d40a4b 100644 --- a/internal/outpost/ldap/instance.go +++ b/internal/outpost/ldap/instance.go @@ -2,14 +2,20 @@ package ldap import ( "crypto/tls" + "fmt" + "strings" "sync" "github.com/go-openapi/strfmt" + "github.com/nmcclain/ldap" log "github.com/sirupsen/logrus" "goauthentik.io/api" + "goauthentik.io/internal/constants" "goauthentik.io/internal/outpost/ldap/bind" + ldapConstants "goauthentik.io/internal/outpost/ldap/constants" "goauthentik.io/internal/outpost/ldap/flags" "goauthentik.io/internal/outpost/ldap/search" + "goauthentik.io/internal/outpost/ldap/utils" ) type ProviderInstance struct { @@ -50,6 +56,10 @@ func (pi *ProviderInstance) GetBaseGroupDN() string { return pi.GroupDN } +func (pi *ProviderInstance) GetBaseVirtualGroupDN() string { + return pi.VirtualGroupDN +} + func (pi *ProviderInstance) GetBaseUserDN() string { return pi.UserDN } @@ -82,3 +92,77 @@ func (pi *ProviderInstance) GetFlowSlug() string { func (pi *ProviderInstance) GetSearchAllowedGroups() []*strfmt.UUID { return pi.searchAllowedGroups } + +func (pi *ProviderInstance) GetBaseEntry() *ldap.Entry { + return &ldap.Entry{ + DN: pi.GetBaseDN(), + Attributes: []*ldap.EntryAttribute{ + { + Name: "distinguishedName", + Values: []string{pi.GetBaseDN()}, + }, + { + Name: "objectClass", + Values: []string{ldapConstants.OCTop, ldapConstants.OCDomain}, + }, + { + Name: "supportedLDAPVersion", + Values: []string{"3"}, + }, + { + Name: "namingContexts", + Values: []string{ + pi.GetBaseDN(), + pi.GetBaseUserDN(), + pi.GetBaseGroupDN(), + pi.GetBaseVirtualGroupDN(), + }, + }, + { + Name: "vendorName", + Values: []string{"goauthentik.io"}, + }, + { + Name: "vendorVersion", + Values: []string{fmt.Sprintf("authentik LDAP Outpost Version %s (build %s)", constants.VERSION, constants.BUILD())}, + }, + }, + } +} + +func (pi *ProviderInstance) GetNeededObjects(scope int, baseDN string, filterOC string) (bool, bool) { + needUsers := false + needGroups := false + + // We only want to load users/groups if we're actually going to be asked + // for at least one user or group based on the search's base DN and scope. + // + // If our requested base DN doesn't match any of the container DNs, then + // we're probably loading a user or group. If it does, then make sure our + // scope will eventually take us to users or groups. + if (baseDN == pi.BaseDN || strings.HasSuffix(baseDN, pi.UserDN)) && utils.IncludeObjectClass(filterOC, ldapConstants.GetUserOCs()) { + if baseDN != pi.UserDN && baseDN != pi.BaseDN || + baseDN == pi.BaseDN && scope > 1 || + baseDN == pi.UserDN && scope > 0 { + needUsers = true + } + } + + if (baseDN == pi.BaseDN || strings.HasSuffix(baseDN, pi.GroupDN)) && utils.IncludeObjectClass(filterOC, ldapConstants.GetGroupOCs()) { + if baseDN != pi.GroupDN && baseDN != pi.BaseDN || + baseDN == pi.BaseDN && scope > 1 || + baseDN == pi.GroupDN && scope > 0 { + needGroups = true + } + } + + if (baseDN == pi.BaseDN || strings.HasSuffix(baseDN, pi.VirtualGroupDN)) && utils.IncludeObjectClass(filterOC, ldapConstants.GetVirtualGroupOCs()) { + if baseDN != pi.VirtualGroupDN && baseDN != pi.BaseDN || + baseDN == pi.BaseDN && scope > 1 || + baseDN == pi.VirtualGroupDN && scope > 0 { + needUsers = true + } + } + + return needUsers, needGroups +} diff --git a/internal/outpost/ldap/search/direct/direct.go b/internal/outpost/ldap/search/direct/direct.go index eda11b2bb..40efcee65 100644 --- a/internal/outpost/ldap/search/direct/direct.go +++ b/internal/outpost/ldap/search/direct/direct.go @@ -4,16 +4,15 @@ import ( "errors" "fmt" "strings" - "sync" log "github.com/sirupsen/logrus" + "golang.org/x/sync/errgroup" "github.com/getsentry/sentry-go" "github.com/nmcclain/ldap" "github.com/prometheus/client_golang/prometheus" "goauthentik.io/api" "goauthentik.io/internal/outpost/ldap/constants" - "goauthentik.io/internal/outpost/ldap/flags" "goauthentik.io/internal/outpost/ldap/group" "goauthentik.io/internal/outpost/ldap/metrics" "goauthentik.io/internal/outpost/ldap/search" @@ -35,26 +34,11 @@ func NewDirectSearcher(si server.LDAPServerInstance) *DirectSearcher { return ds } -func (ds *DirectSearcher) SearchMe(req *search.Request, f flags.UserFlags) (ldap.ServerSearchResult, error) { - if f.UserInfo == nil { - u, _, err := ds.si.GetAPIClient().CoreApi.CoreUsersRetrieve(req.Context(), f.UserPk).Execute() - if err != nil { - req.Log().WithError(err).Warning("Failed to get user info") - return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultOperationsError}, fmt.Errorf("failed to get userinfo") - } - f.UserInfo = &u - } - entries := make([]*ldap.Entry, 1) - entries[0] = ds.si.UserEntry(*f.UserInfo) - return ldap.ServerSearchResult{Entries: entries, Referrals: []string{}, Controls: []ldap.Control{}, ResultCode: ldap.LDAPResultSuccess}, nil -} - func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult, error) { accsp := sentry.StartSpan(req.Context(), "authentik.providers.ldap.search.check_access") - baseDN := strings.ToLower("," + ds.si.GetBaseDN()) + baseDN := strings.ToLower(ds.si.GetBaseDN()) - entries := []*ldap.Entry{} - filterEntity, err := ldap.GetFilterObjectClass(req.Filter) + filterOC, err := ldap.GetFilterObjectClass(req.Filter) if err != nil { metrics.RequestsRejected.With(prometheus.Labels{ "outpost_name": ds.si.GetOutpostName(), @@ -75,7 +59,7 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult, }).Inc() return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultInsufficientAccessRights}, fmt.Errorf("Search Error: Anonymous BindDN not allowed %s", req.BindDN) } - if !strings.HasSuffix(req.BindDN, baseDN) { + if !strings.HasSuffix(req.BindDN, ","+baseDN) { metrics.RequestsRejected.With(prometheus.Labels{ "outpost_name": ds.si.GetOutpostName(), "type": "search", @@ -98,15 +82,6 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult, }).Inc() return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultInsufficientAccessRights}, errors.New("access denied") } - - if req.Scope == ldap.ScopeBaseObject { - req.Log().Debug("base scope, showing domain info") - return ds.SearchBase(req, flags.CanSearch) - } - if !flags.CanSearch { - req.Log().Debug("User can't search, showing info about user") - return ds.SearchMe(req, flags) - } accsp.Finish() parsedFilter, err := ldap.CompileFilter(req.Filter) @@ -121,99 +96,176 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult, return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultOperationsError}, fmt.Errorf("Search Error: error parsing filter: %s", req.Filter) } + entries := make([]*ldap.Entry, 0) + // Create a custom client to set additional headers c := api.NewAPIClient(ds.si.GetAPIClient().GetConfig()) c.GetConfig().AddDefaultHeader("X-authentik-outpost-ldap-query", req.Filter) - switch filterEntity { - default: - metrics.RequestsRejected.With(prometheus.Labels{ - "outpost_name": ds.si.GetOutpostName(), - "type": "search", - "reason": "unhandled_filter_type", - "dn": req.BindDN, - "client": req.RemoteAddr(), - }).Inc() - return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultOperationsError}, fmt.Errorf("Search Error: unhandled filter type: %s [%s]", filterEntity, req.Filter) - case constants.OCGroupOfUniqueNames: - fallthrough - case constants.OCAKGroup: - fallthrough - case constants.OCAKVirtualGroup: - fallthrough - case constants.OCGroup: - wg := sync.WaitGroup{} - wg.Add(2) + scope := req.SearchRequest.Scope + needUsers, needGroups := ds.si.GetNeededObjects(scope, req.BaseDN, filterOC) - gEntries := make([]*ldap.Entry, 0) - uEntries := make([]*ldap.Entry, 0) + if scope >= 0 && req.BaseDN == baseDN { + if utils.IncludeObjectClass(filterOC, constants.GetDomainOCs()) { + entries = append(entries, ds.si.GetBaseEntry()) + } - go func() { - defer wg.Done() + scope -= 1 // Bring it from WholeSubtree to SingleLevel and so on + } + + var users *[]api.User + var groups *[]api.Group + + errs, _ := errgroup.WithContext(req.Context()) + + if needUsers { + errs.Go(func() error { + if flags.CanSearch { + uapisp := sentry.StartSpan(req.Context(), "authentik.providers.ldap.search.api_user") + searchReq, skip := utils.ParseFilterForUser(c.CoreApi.CoreUsersList(uapisp.Context()), parsedFilter, false) + + if skip { + req.Log().Trace("Skip backend request") + return nil + } + + u, _, e := searchReq.Execute() + uapisp.Finish() + + if err != nil { + req.Log().WithError(err).Warning("failed to get users") + return e + } + + users = &u.Results + } else { + if flags.UserInfo == nil { + uapisp := sentry.StartSpan(req.Context(), "authentik.providers.ldap.search.api_user") + u, _, err := c.CoreApi.CoreUsersRetrieve(req.Context(), flags.UserPk).Execute() + uapisp.Finish() + + if err != nil { + req.Log().WithError(err).Warning("Failed to get user info") + return fmt.Errorf("failed to get userinfo") + } + + flags.UserInfo = &u + } + + u := make([]api.User, 1) + u[0] = *flags.UserInfo + + users = &u + } + + return nil + }) + } + + if needGroups { + errs.Go(func() error { gapisp := sentry.StartSpan(req.Context(), "authentik.providers.ldap.search.api_group") searchReq, skip := utils.ParseFilterForGroup(c.CoreApi.CoreGroupsList(gapisp.Context()), parsedFilter, false) if skip { req.Log().Trace("Skip backend request") - return + return nil } - groups, _, err := searchReq.Execute() + + if !flags.CanSearch { + // If they can't search, filter all groups by those they're a member of + searchReq = searchReq.MembersByPk([]int32{flags.UserPk}) + } + + g, _, err := searchReq.Execute() gapisp.Finish() if err != nil { req.Log().WithError(err).Warning("failed to get groups") - return + return err } - req.Log().WithField("count", len(groups.Results)).Trace("Got results from API") + req.Log().WithField("count", len(g.Results)).Trace("Got results from API") - for _, g := range groups.Results { - gEntries = append(gEntries, group.FromAPIGroup(g, ds.si).Entry()) - } - }() - - go func() { - defer wg.Done() - uapisp := sentry.StartSpan(req.Context(), "authentik.providers.ldap.search.api_user") - searchReq, skip := utils.ParseFilterForUser(c.CoreApi.CoreUsersList(uapisp.Context()), parsedFilter, false) - if skip { - req.Log().Trace("Skip backend request") - return - } - users, _, err := searchReq.Execute() - uapisp.Finish() - if err != nil { - req.Log().WithError(err).Warning("failed to get users") - return + if !flags.CanSearch { + for i, results := range g.Results { + // If they can't search, remove any users from the group results except the one we're looking for. + g.Results[i].Users = []int32{flags.UserPk} + for _, u := range results.UsersObj { + if u.Pk == flags.UserPk { + g.Results[i].UsersObj = []api.GroupMember{u} + break + } + } + } } - for _, u := range users.Results { - uEntries = append(uEntries, group.FromAPIUser(u, ds.si).Entry()) - } - }() - wg.Wait() - entries = append(gEntries, uEntries...) - case "": - fallthrough - case constants.OCOrgPerson: - fallthrough - case constants.OCInetOrgPerson: - fallthrough - case constants.OCAKUser: - fallthrough - case constants.OCUser: - uapisp := sentry.StartSpan(req.Context(), "authentik.providers.ldap.search.api_user") - searchReq, skip := utils.ParseFilterForUser(c.CoreApi.CoreUsersList(uapisp.Context()), parsedFilter, false) - if skip { - req.Log().Trace("Skip backend request") - return ldap.ServerSearchResult{Entries: entries, Referrals: []string{}, Controls: []ldap.Control{}, ResultCode: ldap.LDAPResultSuccess}, nil + groups = &g.Results + + return nil + }) + } + + err = errs.Wait() + + if err != nil { + return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultOperationsError}, err + } + + if scope >= 0 && (req.BaseDN == ds.si.GetBaseDN() || strings.HasSuffix(req.BaseDN, ds.si.GetBaseUserDN())) { + singleu := strings.HasSuffix(req.BaseDN, ","+ds.si.GetBaseUserDN()) + + if !singleu && utils.IncludeObjectClass(filterOC, constants.GetContainerOCs()) { + entries = append(entries, utils.GetContainerEntry(filterOC, ds.si.GetBaseUserDN(), constants.OUUsers)) + scope -= 1 } - users, _, err := searchReq.Execute() - uapisp.Finish() - if err != nil { - return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultOperationsError}, fmt.Errorf("API Error: %s", err) + if scope >= 0 && users != nil && utils.IncludeObjectClass(filterOC, constants.GetUserOCs()) { + for _, u := range *users { + entry := ds.si.UserEntry(u) + if req.BaseDN == entry.DN || !singleu { + entries = append(entries, entry) + } + } } - for _, u := range users.Results { - entries = append(entries, ds.si.UserEntry(u)) + + scope += 1 // Return the scope to what it was before we descended + } + + if scope >= 0 && (req.BaseDN == ds.si.GetBaseDN() || strings.HasSuffix(req.BaseDN, ds.si.GetBaseGroupDN())) { + singleg := strings.HasSuffix(req.BaseDN, ","+ds.si.GetBaseGroupDN()) + + if !singleg && utils.IncludeObjectClass(filterOC, constants.GetContainerOCs()) { + entries = append(entries, utils.GetContainerEntry(filterOC, ds.si.GetBaseGroupDN(), constants.OUGroups)) + scope -= 1 + } + + if scope >= 0 && groups != nil && utils.IncludeObjectClass(filterOC, constants.GetGroupOCs()) { + for _, g := range *groups { + entry := group.FromAPIGroup(g, ds.si).Entry() + if req.BaseDN == entry.DN || !singleg { + entries = append(entries, entry) + } + } + } + + scope += 1 // Return the scope to what it was before we descended + } + + if scope >= 0 && (req.BaseDN == ds.si.GetBaseDN() || strings.HasSuffix(req.BaseDN, ds.si.GetBaseVirtualGroupDN())) { + singlevg := strings.HasSuffix(req.BaseDN, ","+ds.si.GetBaseVirtualGroupDN()) + + if !singlevg || utils.IncludeObjectClass(filterOC, constants.GetContainerOCs()) { + entries = append(entries, utils.GetContainerEntry(filterOC, ds.si.GetBaseVirtualGroupDN(), constants.OUVirtualGroups)) + scope -= 1 + } + + if scope >= 0 && users != nil && utils.IncludeObjectClass(filterOC, constants.GetVirtualGroupOCs()) { + for _, u := range *users { + entry := group.FromAPIUser(u, ds.si).Entry() + if req.BaseDN == entry.DN || !singlevg { + entries = append(entries, entry) + } + } } } + return ldap.ServerSearchResult{Entries: entries, Referrals: []string{}, Controls: []ldap.Control{}, ResultCode: ldap.LDAPResultSuccess}, nil } diff --git a/internal/outpost/ldap/search/memory/base.go b/internal/outpost/ldap/search/memory/base.go deleted file mode 100644 index 123d4a7ad..000000000 --- a/internal/outpost/ldap/search/memory/base.go +++ /dev/null @@ -1,54 +0,0 @@ -package memory - -import ( - "fmt" - - "github.com/nmcclain/ldap" - "goauthentik.io/internal/constants" - "goauthentik.io/internal/outpost/ldap/search" -) - -func (ms *MemorySearcher) SearchBase(req *search.Request, authz bool) (ldap.ServerSearchResult, error) { - dn := "" - if authz { - dn = req.SearchRequest.BaseDN - } - return ldap.ServerSearchResult{ - Entries: []*ldap.Entry{ - { - DN: dn, - Attributes: []*ldap.EntryAttribute{ - { - Name: "distinguishedName", - Values: []string{ms.si.GetBaseDN()}, - }, - { - Name: "objectClass", - Values: []string{"top", "domain"}, - }, - { - Name: "supportedLDAPVersion", - Values: []string{"3"}, - }, - { - Name: "namingContexts", - Values: []string{ - ms.si.GetBaseDN(), - ms.si.GetBaseUserDN(), - ms.si.GetBaseGroupDN(), - }, - }, - { - Name: "vendorName", - Values: []string{"goauthentik.io"}, - }, - { - Name: "vendorVersion", - Values: []string{fmt.Sprintf("authentik LDAP Outpost Version %s (build %s)", constants.VERSION, constants.BUILD())}, - }, - }, - }, - }, - Referrals: []string{}, Controls: []ldap.Control{}, ResultCode: ldap.LDAPResultSuccess, - }, nil -} diff --git a/internal/outpost/ldap/search/memory/memory.go b/internal/outpost/ldap/search/memory/memory.go index bb77b5610..c58bd9f40 100644 --- a/internal/outpost/ldap/search/memory/memory.go +++ b/internal/outpost/ldap/search/memory/memory.go @@ -11,11 +11,11 @@ import ( log "github.com/sirupsen/logrus" "goauthentik.io/api" "goauthentik.io/internal/outpost/ldap/constants" - "goauthentik.io/internal/outpost/ldap/flags" "goauthentik.io/internal/outpost/ldap/group" "goauthentik.io/internal/outpost/ldap/metrics" "goauthentik.io/internal/outpost/ldap/search" "goauthentik.io/internal/outpost/ldap/server" + "goauthentik.io/internal/outpost/ldap/utils" ) type MemorySearcher struct { @@ -37,29 +37,11 @@ func NewMemorySearcher(si server.LDAPServerInstance) *MemorySearcher { return ms } -func (ms *MemorySearcher) SearchMe(req *search.Request, f flags.UserFlags) (ldap.ServerSearchResult, error) { - if f.UserInfo == nil { - for _, u := range ms.users { - if u.Pk == f.UserPk { - f.UserInfo = &u - } - } - if f.UserInfo == nil { - req.Log().WithField("pk", f.UserPk).Warning("User with pk is not in local cache") - return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultOperationsError}, fmt.Errorf("failed to get userinfo") - } - } - entries := make([]*ldap.Entry, 1) - entries[0] = ms.si.UserEntry(*f.UserInfo) - return ldap.ServerSearchResult{Entries: entries, Referrals: []string{}, Controls: []ldap.Control{}, ResultCode: ldap.LDAPResultSuccess}, nil -} - func (ms *MemorySearcher) Search(req *search.Request) (ldap.ServerSearchResult, error) { accsp := sentry.StartSpan(req.Context(), "authentik.providers.ldap.search.check_access") - baseDN := strings.ToLower("," + ms.si.GetBaseDN()) + baseDN := strings.ToLower(ms.si.GetBaseDN()) - entries := []*ldap.Entry{} - filterEntity, err := ldap.GetFilterObjectClass(req.Filter) + filterOC, err := ldap.GetFilterObjectClass(req.Filter) if err != nil { metrics.RequestsRejected.With(prometheus.Labels{ "outpost_name": ms.si.GetOutpostName(), @@ -80,7 +62,7 @@ func (ms *MemorySearcher) Search(req *search.Request) (ldap.ServerSearchResult, }).Inc() return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultInsufficientAccessRights}, fmt.Errorf("Search Error: Anonymous BindDN not allowed %s", req.BindDN) } - if !strings.HasSuffix(req.BindDN, baseDN) { + if !strings.HasSuffix(req.BindDN, ","+baseDN) { metrics.RequestsRejected.With(prometheus.Labels{ "outpost_name": ms.si.GetOutpostName(), "type": "search", @@ -103,52 +85,132 @@ func (ms *MemorySearcher) Search(req *search.Request) (ldap.ServerSearchResult, }).Inc() return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultInsufficientAccessRights}, errors.New("access denied") } - - if req.Scope == ldap.ScopeBaseObject { - req.Log().Debug("base scope, showing domain info") - return ms.SearchBase(req, flags.CanSearch) - } - if !flags.CanSearch { - req.Log().Debug("User can't search, showing info about user") - return ms.SearchMe(req, flags) - } accsp.Finish() - switch filterEntity { - default: - metrics.RequestsRejected.With(prometheus.Labels{ - "outpost_name": ms.si.GetOutpostName(), - "type": "search", - "reason": "unhandled_filter_type", - "dn": req.BindDN, - "client": req.RemoteAddr(), - }).Inc() - return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultOperationsError}, fmt.Errorf("Search Error: unhandled filter type: %s [%s]", filterEntity, req.Filter) - case constants.OCGroupOfUniqueNames: - fallthrough - case constants.OCAKGroup: - fallthrough - case constants.OCAKVirtualGroup: - fallthrough - case constants.OCGroup: - for _, g := range ms.groups { - entries = append(entries, group.FromAPIGroup(g, ms.si).Entry()) + entries := make([]*ldap.Entry, 0) + + scope := req.SearchRequest.Scope + needUsers, needGroups := ms.si.GetNeededObjects(scope, req.BaseDN, filterOC) + + if scope >= 0 && req.BaseDN == baseDN { + if utils.IncludeObjectClass(filterOC, constants.GetDomainOCs()) { + entries = append(entries, ms.si.GetBaseEntry()) } - for _, u := range ms.users { - entries = append(entries, group.FromAPIUser(u, ms.si).Entry()) - } - case "": - fallthrough - case constants.OCOrgPerson: - fallthrough - case constants.OCInetOrgPerson: - fallthrough - case constants.OCAKUser: - fallthrough - case constants.OCUser: - for _, u := range ms.users { - entries = append(entries, ms.si.UserEntry(u)) + + scope -= 1 // Bring it from WholeSubtree to SingleLevel and so on + } + + var users *[]api.User + var groups []*group.LDAPGroup + + if needUsers { + if flags.CanSearch { + users = &ms.users + } else { + if flags.UserInfo == nil { + for i, u := range ms.users { + if u.Pk == flags.UserPk { + flags.UserInfo = &ms.users[i] + } + } + + if flags.UserInfo == nil { + req.Log().WithField("pk", flags.UserPk).Warning("User with pk is not in local cache") + err = fmt.Errorf("failed to get userinfo") + } + } + + u := make([]api.User, 1) + u[0] = *flags.UserInfo + + users = &u } } + + if needGroups { + groups = make([]*group.LDAPGroup, 0) + + for _, g := range ms.groups { + if flags.CanSearch { + groups = append(groups, group.FromAPIGroup(g, ms.si)) + } else { + // If the user cannot search, we're going to only return + // the groups they're in _and_ only return themselves + // as a member. + for _, u := range g.UsersObj { + if flags.UserPk == u.Pk { + // TODO: Is there a better way to clone this object? + fg := api.NewGroup(g.Pk, g.Name, g.Parent, g.ParentName, []int32{flags.UserPk}, []api.GroupMember{u}) + fg.SetAttributes(*g.Attributes) + fg.SetIsSuperuser(*g.IsSuperuser) + groups = append(groups, group.FromAPIGroup(*fg, ms.si)) + break + } + } + } + } + } + + if err != nil { + return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultOperationsError}, err + } + + if scope >= 0 && (req.BaseDN == ms.si.GetBaseDN() || strings.HasSuffix(req.BaseDN, ms.si.GetBaseUserDN())) { + singleu := strings.HasSuffix(req.BaseDN, ","+ms.si.GetBaseUserDN()) + + if !singleu && utils.IncludeObjectClass(filterOC, constants.GetContainerOCs()) { + entries = append(entries, utils.GetContainerEntry(filterOC, ms.si.GetBaseUserDN(), constants.OUUsers)) + scope -= 1 + } + + if scope >= 0 && users != nil && utils.IncludeObjectClass(filterOC, constants.GetUserOCs()) { + for _, u := range *users { + entry := ms.si.UserEntry(u) + if req.BaseDN == entry.DN || !singleu { + entries = append(entries, entry) + } + } + } + + scope += 1 // Return the scope to what it was before we descended + } + + if scope >= 0 && (req.BaseDN == ms.si.GetBaseDN() || strings.HasSuffix(req.BaseDN, ms.si.GetBaseGroupDN())) { + singleg := strings.HasSuffix(req.BaseDN, ","+ms.si.GetBaseGroupDN()) + + if !singleg && utils.IncludeObjectClass(filterOC, constants.GetContainerOCs()) { + entries = append(entries, utils.GetContainerEntry(filterOC, ms.si.GetBaseGroupDN(), constants.OUGroups)) + scope -= 1 + } + + if scope >= 0 && groups != nil && utils.IncludeObjectClass(filterOC, constants.GetGroupOCs()) { + for _, g := range groups { + if req.BaseDN == g.DN || !singleg { + entries = append(entries, g.Entry()) + } + } + } + + scope += 1 // Return the scope to what it was before we descended + } + + if scope >= 0 && (req.BaseDN == ms.si.GetBaseDN() || strings.HasSuffix(req.BaseDN, ms.si.GetBaseVirtualGroupDN())) { + singlevg := strings.HasSuffix(req.BaseDN, ","+ms.si.GetBaseVirtualGroupDN()) + + if !singlevg && utils.IncludeObjectClass(filterOC, constants.GetContainerOCs()) { + entries = append(entries, utils.GetContainerEntry(filterOC, ms.si.GetBaseVirtualGroupDN(), constants.OUVirtualGroups)) + scope -= 1 + } + + if scope >= 0 && users != nil && utils.IncludeObjectClass(filterOC, constants.GetVirtualGroupOCs()) { + for _, u := range *users { + entry := group.FromAPIUser(u, ms.si).Entry() + if req.BaseDN == entry.DN || !singlevg { + entries = append(entries, entry) + } + } + } + } + return ldap.ServerSearchResult{Entries: entries, Referrals: []string{}, Controls: []ldap.Control{}, ResultCode: ldap.LDAPResultSuccess}, nil } diff --git a/internal/outpost/ldap/search/searcher.go b/internal/outpost/ldap/search/searcher.go index 5adb6d2f5..b9394a212 100644 --- a/internal/outpost/ldap/search/searcher.go +++ b/internal/outpost/ldap/search/searcher.go @@ -1,6 +1,8 @@ package search -import "github.com/nmcclain/ldap" +import ( + "github.com/nmcclain/ldap" +) type Searcher interface { Search(req *Request) (ldap.ServerSearchResult, error) diff --git a/internal/outpost/ldap/server/base.go b/internal/outpost/ldap/server/base.go index 623796441..4317a383d 100644 --- a/internal/outpost/ldap/server/base.go +++ b/internal/outpost/ldap/server/base.go @@ -19,6 +19,7 @@ type LDAPServerInstance interface { GetBaseDN() string GetBaseGroupDN() string + GetBaseVirtualGroupDN() string GetBaseUserDN() string GetUserDN(string) string @@ -32,4 +33,7 @@ type LDAPServerInstance interface { GetFlags(string) (flags.UserFlags, bool) SetFlags(string, flags.UserFlags) + + GetBaseEntry() *ldap.Entry + GetNeededObjects(int, string, string) (bool, bool) } diff --git a/internal/outpost/ldap/utils/utils.go b/internal/outpost/ldap/utils/utils.go index ad725b42f..7bcba5f02 100644 --- a/internal/outpost/ldap/utils/utils.go +++ b/internal/outpost/ldap/utils/utils.go @@ -5,6 +5,7 @@ import ( "github.com/nmcclain/ldap" log "github.com/sirupsen/logrus" + ldapConstants "goauthentik.io/internal/outpost/ldap/constants" ) func BoolToString(in bool) string { @@ -84,3 +85,35 @@ func MustHaveAttribute(attrs []*ldap.EntryAttribute, name string, value []string } return attrs } + +func IncludeObjectClass(searchOC string, ocs map[string]bool) bool { + if searchOC == "" { + return true + } + + return ocs[searchOC] +} + +func GetContainerEntry(filterOC string, dn string, ou string) *ldap.Entry { + if IncludeObjectClass(filterOC, ldapConstants.GetContainerOCs()) { + return &ldap.Entry{ + DN: dn, + Attributes: []*ldap.EntryAttribute{ + { + Name: "distinguishedName", + Values: []string{dn}, + }, + { + Name: "objectClass", + Values: []string{"top", "nsContainer"}, + }, + { + Name: "commonName", + Values: []string{ou}, + }, + }, + } + } + + return nil +} diff --git a/website/docs/providers/ldap.md b/website/docs/providers/ldap.md index 63fe73764..5cfdd0897 100644 --- a/website/docs/providers/ldap.md +++ b/website/docs/providers/ldap.md @@ -73,3 +73,8 @@ Starting with 2021.9.1, custom attributes will override the inbuilt attributes. You can also configure SSL for your LDAP Providers by selecting a certificate and a server name in the provider settings. This enables you to bind on port 636 using LDAPS, StartTLS is not supported. + +## Integrations + +See the integration guide for [sssd](../../integrations/services/sssd/index) for +an example guide. diff --git a/website/integrations/services/sssd/index.md b/website/integrations/services/sssd/index.md new file mode 100644 index 000000000..7e4221890 --- /dev/null +++ b/website/integrations/services/sssd/index.md @@ -0,0 +1,141 @@ +--- +title: sssd +--- + +:::info +This feature is still in technical preview, so please report any +Bugs you run into on [GitHub](https://github.com/goauthentik/authentik/issues) +::: + +## What is sssd + +From https://sssd.io/ + +:::note +**SSSD** is an acronym for System Security Services Daemon. It is the client component of centralized identity management solutions such as FreeIPA, 389 Directory Server, Microsoft Active Directory, OpenLDAP and other directory servers. The client serves and caches the information stored in the remote directory server and provides identity, authentication and authorization services to the host machine. +::: + +Note that Authentik supports _only_ user and group objects. As +a consequence, it cannot be used to provide automount or sudo +configuration nor can it provide netgroups or services to `nss`. +Kerberos is also not supported. + +## Preperation + +The following placeholders will be used: + +- `authentik.company` is the FQDN of the authentik install. +- `ldap.baseDN` is the Base DN you configure in the LDAP provider. +- `ldap.domain` is (typically) an FQDN for your domain. Usually + it is just the components of your base DN. For example, if + `ldap.baseDN` is `dc=ldap,dc=goauthentik,dc=io` then the domain + might be `ldap.goauthentik.io`. +- `ldap.searchGroup` is the "Search Group" that can can see all + users and groups in Authentik. +- `sssd.serviceAccount` is a service account created in Authentik +- `sssd.serviceAccountToken` is the service account token generated + by Authentik. + +Create an LDAP Provider if you don't already have one setup. +This guide assumes you will be running with TLS and that you've +correctly setup certificates both in Authentik and on the host +running sssd. See the [ldap provider docs](../../../docs/providers/ldap) for setting up SSL on the Authentik side. + +Remember the Base DN you have configured for the provider as you'll +need it in the sssd configuration. + +Create a new service account for all of your hosts to use to connect +to LDAP and perform searches. Make sure this service account is added +to `ldap.searchGroup`. + +## Deployment + +Create an outpost deployment for the provider you've created above, as described [here](../../../docs/outposts/outposts). Deploy this Outpost either on the same host or a different host that your +host(s) running sssd can access. + +The outpost will connect to authentik and configure itself. + +## Client Configuration + +First, install the necessary sssd packages on your host. Very likely +the package is just `sssd`. + +:::note +This guide well help you configure the `sssd.conf` for LDAP only. You +will likely need to perform other tasks for a usable setup +like setting up automounted or autocreated home directories that +are beyond the scope of this guide. See the "additional resources" +section for some help. +::: + +Create a file at `/etc/sssd/sssd.conf` with contents similar to +the following: + +```ini +[nss] +filter_groups = root +filter_users = root +reconnection_retries = 3 + +[sssd] +config_file_version = 2 +reconnection_retries = 3 +sbus_timeout = 30 +domains = ${ldap.domain} +services = nss, pam, ssh + +[pam] +reconnection_retries = 3 + +[domain/${ldap.domain}] +cache_credentials = True +id_provider = ldap +chpass_provider = ldap +auth_provider = ldap +access_provider = ldap +ldap_uri = ldaps://${authentik.company}:636 + +ldap_schema = rfc2307bis +ldap_search_base = ${ldap.baseDN} +ldap_user_search_base = ou=users,${ldap.baseDN} +ldap_group_search_base = ${ldap.baseDN} + +ldap_user_object_class = user +ldap_user_name = cn +ldap_group_object_class = group +ldap_group_name = cn + +# Optionally, filter logins to only a specific group +#ldap_access_order = filter +#ldap_access_filter = memberOf=cn=authentik Admins,ou=groups,${ldap.baseDN} + +ldap_default_bind_dn = cn=${sssd.serviceAccount},ou=users,${ldap.baseDN} +ldap_default_authtok = ${sssd.serviceAccountToken} +``` + +You should now be able to start sssd; however, the system may not +yet be setup to use it. Depending on your platform, you may need to +use `authconfig` or `pam-auth-update` to configure your system. See +the additional resources section for details. + +:::note +You can store SSH authorized keys in LDAP by adding the +`sshPublicKey` attribute to any user with their public key as +the value. +::: + +## Additional Resources + +The setup of sssd may vary based on Linux distribution and version, +here are some resources that can help you get this setup: + +:::note +Authentik is providing a simple LDAP server, not an Active Directory +domain. Be sure you're looking at the correct sections in these guides. +::: + +- https://sssd.io/docs/quick-start.html#quick-start-ldap +- https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system-level_authentication_guide/configuring_services +- https://ubuntu.com/server/docs/service-sssd +- https://manpages.debian.org/unstable/sssd-ldap/sssd-ldap.5.en.html +- https://wiki.archlinux.org/title/LDAP_authentication diff --git a/website/sidebarsIntegrations.js b/website/sidebarsIntegrations.js index 3aae6f1e5..52a3f4191 100644 --- a/website/sidebarsIntegrations.js +++ b/website/sidebarsIntegrations.js @@ -47,6 +47,7 @@ module.exports = { "services/proxmox-ve/index", "services/rancher/index", "services/sentry/index", + "services/sssd/index", "services/sonarr/index", "services/tautulli/index", "services/ubuntu-landscape/index", From 02771683a676312ee382ba743d305eeffeaa0384 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 15:32:00 +0100 Subject: [PATCH 23/46] web/flows: fix linting errors Signed-off-by: Jens Langhammer --- .../authenticator_validate/AuthenticatorValidateStage.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/web/src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts b/web/src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts index 9721122c5..aadd5e668 100644 --- a/web/src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts +++ b/web/src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts @@ -100,9 +100,7 @@ export class AuthenticatorValidateStage return html`

${t`Duo push-notifications`}

- ${t`Receive a push notification on your device.`} + ${t`Receive a push notification on your device.`}
`; case DeviceClassesEnum.Webauthn: return html` From 692e75b057b4249d51c583251fd3eaca0f874627 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 15:48:34 +0100 Subject: [PATCH 24/46] website/docs: add passwordless docs closes #1863 Signed-off-by: Jens Langhammer --- website/docs/flow/stages/password/index.md | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/website/docs/flow/stages/password/index.md b/website/docs/flow/stages/password/index.md index 14ef089ac..ca411159d 100644 --- a/website/docs/flow/stages/password/index.md +++ b/website/docs/flow/stages/password/index.md @@ -3,3 +3,27 @@ title: Password stage --- This is a generic password prompt which authenticates the current `pending_user`. This stage allows the selection of the source the user is authenticated against. + +## Passwordless login + +To achieve a "passwordless" experience; authenticating users based only on TOTP/WebAuthn/Duo, create an expression policy and optionally skip the password stage. + +Depending on what kind of device you want to require the user to have: + +#### WebAuthn + +```python +from authentik.stages.authenticator_webauthn.models import WebAuthnDevice +return WebAuthnDevice.objects.filter(user=request.user, active=True).exists() +``` + +#### Duo + +```python +from authentik.stages.authenticator_duo.models import DuoDevice +return DuoDevice.objects.filter(user=request.user, active=True).exists() +``` + +Afterwards, bind the policy you've created to the stage binding of the password stage. + +Make sure to uncheck *Evaluate on plan* and check *Re-evaluate policies*, otherwise an invalid result will be cached. From f8dc7f48f2c7965ab67603c0f78d1e61479f2c95 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 18:47:36 +0100 Subject: [PATCH 25/46] outposts/proxy: fix path for media Signed-off-by: Jens Langhammer --- internal/outpost/proxyv2/handlers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/outpost/proxyv2/handlers.go b/internal/outpost/proxyv2/handlers.go index 8e1209473..d80c2420b 100644 --- a/internal/outpost/proxyv2/handlers.go +++ b/internal/outpost/proxyv2/handlers.go @@ -28,7 +28,7 @@ func (ps *ProxyServer) HandlePing(rw http.ResponseWriter, r *http.Request) { } func (ps *ProxyServer) HandleStatic(rw http.ResponseWriter, r *http.Request) { - staticFs := http.FileServer(http.Dir("./website/static/")) + staticFs := http.FileServer(http.Dir("./web/dist/")) before := time.Now() web.DisableIndex(http.StripPrefix("/akprox/static", staticFs)).ServeHTTP(rw, r) after := time.Since(before) From b77b4b5c80060929b0aa8dac7af27af9d78dac5d Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 19:19:45 +0100 Subject: [PATCH 26/46] root: fix paths in proxy dockerfile Signed-off-by: Jens Langhammer --- proxy.Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proxy.Dockerfile b/proxy.Dockerfile index 1c4c76a07..2c626eef2 100644 --- a/proxy.Dockerfile +++ b/proxy.Dockerfile @@ -12,10 +12,6 @@ FROM docker.io/golang:1.17.3-bullseye AS builder WORKDIR /go/src/goauthentik.io COPY . . -COPY --from=web-builder /static/robots.txt /work/web/robots.txt -COPY --from=web-builder /static/security.txt /work/web/security.txt -COPY --from=web-builder /static/dist/ /work/web/dist/ -COPY --from=web-builder /static/authentik/ /work/web/authentik/ ENV CGO_ENABLED=0 RUN go build -o /go/proxy ./cmd/proxy @@ -27,6 +23,10 @@ ARG GIT_BUILD_HASH ENV GIT_BUILD_HASH=$GIT_BUILD_HASH COPY --from=builder /go/proxy / +COPY --from=web-builder /static/robots.txt /web/robots.txt +COPY --from=web-builder /static/security.txt /web/security.txt +COPY --from=web-builder /static/dist/ /web/dist/ +COPY --from=web-builder /static/authentik/ /web/authentik/ HEALTHCHECK CMD [ "wget", "--spider", "http://localhost:9300/akprox/ping" ] From ea097afeae557419da772f3930c9dbe73f490a67 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 19:21:40 +0100 Subject: [PATCH 27/46] outposts/proxy: fix path prefix in static handler Signed-off-by: Jens Langhammer --- internal/outpost/proxyv2/handlers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/outpost/proxyv2/handlers.go b/internal/outpost/proxyv2/handlers.go index d80c2420b..2fee7e226 100644 --- a/internal/outpost/proxyv2/handlers.go +++ b/internal/outpost/proxyv2/handlers.go @@ -30,7 +30,7 @@ func (ps *ProxyServer) HandlePing(rw http.ResponseWriter, r *http.Request) { func (ps *ProxyServer) HandleStatic(rw http.ResponseWriter, r *http.Request) { staticFs := http.FileServer(http.Dir("./web/dist/")) before := time.Now() - web.DisableIndex(http.StripPrefix("/akprox/static", staticFs)).ServeHTTP(rw, r) + web.DisableIndex(http.StripPrefix("/akprox/static/dist", staticFs)).ServeHTTP(rw, r) after := time.Since(before) metrics.Requests.With(prometheus.Labels{ "outpost_name": ps.akAPI.Outpost.Name, From 5594ad0b360de21119b0f3e37efe363f2f28e549 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 19:34:17 +0100 Subject: [PATCH 28/46] web/admin: add spinner to table refresh to show progress Signed-off-by: Jens Langhammer --- web/src/elements/table/Table.ts | 43 +++++++++------------------------ web/src/locales/fr_FR.po | 8 ++++-- 2 files changed, 18 insertions(+), 33 deletions(-) diff --git a/web/src/elements/table/Table.ts b/web/src/elements/table/Table.ts index 7753f3f62..7a73b6ba6 100644 --- a/web/src/elements/table/Table.ts +++ b/web/src/elements/table/Table.ts @@ -17,6 +17,7 @@ import { AKResponse } from "../../api/Client"; import { EVENT_REFRESH } from "../../constants"; import { groupBy } from "../../utils"; import "../EmptyState"; +import "../buttons/SpinnerButton"; import "../chips/Chip"; import "../chips/ChipGroup"; import { getURLParam, updateURLParams } from "../router/RouteMatch"; @@ -162,12 +163,12 @@ export abstract class Table extends LitElement { }); } - public fetch(): void { + public async fetch(): Promise { if (this.isLoading) { return; } this.isLoading = true; - this.apiEndpoint(this.page) + return this.apiEndpoint(this.page) .then((r) => { this.data = r; this.page = r.pagination.current; @@ -319,19 +320,14 @@ export abstract class Table extends LitElement { } renderToolbar(): TemplateResult { - return html``; + ${t`Refresh`}`; } renderToolbarSelected(): TemplateResult { @@ -350,12 +346,7 @@ export abstract class Table extends LitElement { value=${ifDefined(this.search)} .onSearch=${(value: string) => { this.search = value; - this.dispatchEvent( - new CustomEvent(EVENT_REFRESH, { - bubbles: true, - composed: true, - }), - ); + this.fetch(); updateURLParams({ search: value, }); @@ -382,12 +373,7 @@ export abstract class Table extends LitElement { .pages=${this.data?.pagination} .pageChangeHandler=${(page: number) => { this.page = page; - this.dispatchEvent( - new CustomEvent(EVENT_REFRESH, { - bubbles: true, - composed: true, - }), - ); + this.fetch(); }} > ` @@ -442,12 +428,7 @@ export abstract class Table extends LitElement { .pages=${this.data?.pagination} .pageChangeHandler=${(page: number) => { this.page = page; - this.dispatchEvent( - new CustomEvent(EVENT_REFRESH, { - bubbles: true, - composed: true, - }), - ); + this.fetch(); }} > diff --git a/web/src/locales/fr_FR.po b/web/src/locales/fr_FR.po index 9c8dc5b1d..22615c3ad 100644 --- a/web/src/locales/fr_FR.po +++ b/web/src/locales/fr_FR.po @@ -3582,8 +3582,12 @@ msgid "Re-evaluate policies" msgstr "Ré-évaluer les politiques" #: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts -msgid "Receive a push notification on your phone to prove your identity." -msgstr "Recevez une notification push sur votre téléphone pour prouver votre identité." +msgid "Receive a push notification on your device." +msgstr "" + +#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts +#~ msgid "Receive a push notification on your phone to prove your identity." +#~ msgstr "Recevez une notification push sur votre téléphone pour prouver votre identité." #: src/pages/flows/utils.ts #: src/pages/tokens/TokenListPage.ts From 7e316b5fc25db1431df430b3063f90321fe73d69 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 19:54:37 +0100 Subject: [PATCH 29/46] root: add missing sample_rate default Signed-off-by: Jens Langhammer --- authentik/lib/default.yml | 1 + authentik/root/settings.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/authentik/lib/default.yml b/authentik/lib/default.yml index 1e4986785..08b462746 100644 --- a/authentik/lib/default.yml +++ b/authentik/lib/default.yml @@ -47,6 +47,7 @@ error_reporting: enabled: false environment: customer send_pii: false + sample_rate: 0.5 # Global email settings email: diff --git a/authentik/root/settings.py b/authentik/root/settings.py index 4099cc757..8feb335d7 100644 --- a/authentik/root/settings.py +++ b/authentik/root/settings.py @@ -424,7 +424,7 @@ if _ERROR_REPORTING: ], before_send=before_send, release=f"authentik@{__version__}", - traces_sample_rate=float(CONFIG.y("error_reporting.sample_rate", 0.4)), + traces_sample_rate=float(CONFIG.y("error_reporting.sample_rate", 0.5)), environment=CONFIG.y("error_reporting.environment", "customer"), send_default_pii=CONFIG.y_bool("error_reporting.send_pii", False), ) From 75051687e6a98c7613cef0c482a884b9d7f09f19 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 20:15:11 +0100 Subject: [PATCH 30/46] sources/ldap: allow multiple server URIs for loadbalancing and failover closes #1874 Signed-off-by: Jens Langhammer --- authentik/lib/models.py | 4 +-- authentik/sources/ldap/models.py | 25 ++++++++++++++++--- web/src/locales/en.po | 4 +++ web/src/locales/fr_FR.po | 4 +++ web/src/locales/pseudo-LOCALE.po | 4 +++ web/src/pages/sources/ldap/LDAPSourceForm.ts | 3 +++ .../sources/active-directory/index.md | 4 +++ website/integrations/sources/freeipa/index.md | 7 +++++- website/integrations/sources/ldap/index.md | 5 ++++ 9 files changed, 53 insertions(+), 7 deletions(-) diff --git a/authentik/lib/models.py b/authentik/lib/models.py index 795cf8c4b..3c7ba9c65 100644 --- a/authentik/lib/models.py +++ b/authentik/lib/models.py @@ -68,9 +68,9 @@ class DomainlessURLValidator(URLValidator): ) self.schemes = ["http", "https", "blank"] + list(self.schemes) - def __call__(self, value): + def __call__(self, value: str): # Check if the scheme is valid. scheme = value.split("://")[0].lower() if scheme not in self.schemes: value = "default" + value - return super().__call__(value) + super().__call__(value) diff --git a/authentik/sources/ldap/models.py b/authentik/sources/ldap/models.py index c5a6c123a..53912c5de 100644 --- a/authentik/sources/ldap/models.py +++ b/authentik/sources/ldap/models.py @@ -3,7 +3,7 @@ from typing import Optional, Type from django.db import models from django.utils.translation import gettext_lazy as _ -from ldap3 import ALL, Connection, Server +from ldap3 import ALL, ROUND_ROBIN, Connection, Server, ServerPool from rest_framework.serializers import Serializer from authentik.core.models import Group, PropertyMapping, Source @@ -12,11 +12,22 @@ from authentik.lib.models import DomainlessURLValidator LDAP_TIMEOUT = 15 +class MultiURLValidator(DomainlessURLValidator): + """Same as DomainlessURLValidator but supports multiple URLs separated with a comma.""" + + def __call__(self, value: str): + if "," in value: + for url in value.split(","): + super().__call__(url) + else: + super().__call__(value) + + class LDAPSource(Source): """Federate LDAP Directory with authentik, or create new accounts in LDAP.""" server_uri = models.TextField( - validators=[DomainlessURLValidator(schemes=["ldap", "ldaps"])], + validators=[MultiURLValidator(schemes=["ldap", "ldaps"])], verbose_name=_("Server URI"), ) bind_cn = models.TextField(verbose_name=_("Bind CN"), blank=True) @@ -88,9 +99,15 @@ class LDAPSource(Source): def connection(self) -> Connection: """Get a fully connected and bound LDAP Connection""" if not self._connection: - server = Server(self.server_uri, get_info=ALL, connect_timeout=LDAP_TIMEOUT) + servers = [] + if "," in self.server_uri: + for server in self.server_uri.split(","): + servers.append(Server(server, get_info=ALL, connect_timeout=LDAP_TIMEOUT)) + else: + servers = [Server(self.server_uri, get_info=ALL, connect_timeout=LDAP_TIMEOUT)] + pool = ServerPool(servers, ROUND_ROBIN, active=True, exhaust=True) self._connection = Connection( - server, + pool, raise_exceptions=True, user=self.bind_cn, password=self.bind_password, diff --git a/web/src/locales/en.po b/web/src/locales/en.po index c261429d2..15bc01096 100644 --- a/web/src/locales/en.po +++ b/web/src/locales/en.po @@ -4199,6 +4199,10 @@ msgstr "Sources" msgid "Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves." msgstr "Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves." +#: src/pages/sources/ldap/LDAPSourceForm.ts +msgid "Specify multiple server URIs by separating them with a comma." +msgstr "Specify multiple server URIs by separating them with a comma." + #: src/pages/flows/BoundStagesList.ts #: src/pages/flows/StageBindingForm.ts msgid "Stage" diff --git a/web/src/locales/fr_FR.po b/web/src/locales/fr_FR.po index 22615c3ad..39c9ccbc5 100644 --- a/web/src/locales/fr_FR.po +++ b/web/src/locales/fr_FR.po @@ -4162,6 +4162,10 @@ msgstr "Sources" msgid "Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves." msgstr "Sources d'identités, qui peuvent soit être synchronisées dans la base de données d'Authentik, soit être utilisées par les utilisateurs pour s'authentifier et s'inscrire." +#: src/pages/sources/ldap/LDAPSourceForm.ts +msgid "Specify multiple server URIs by separating them with a comma." +msgstr "" + #: src/pages/flows/BoundStagesList.ts #: src/pages/flows/StageBindingForm.ts msgid "Stage" diff --git a/web/src/locales/pseudo-LOCALE.po b/web/src/locales/pseudo-LOCALE.po index f58cab15b..102f50448 100644 --- a/web/src/locales/pseudo-LOCALE.po +++ b/web/src/locales/pseudo-LOCALE.po @@ -4191,6 +4191,10 @@ msgstr "" msgid "Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves." msgstr "" +#: src/pages/sources/ldap/LDAPSourceForm.ts +msgid "Specify multiple server URIs by separating them with a comma." +msgstr "" + #: src/pages/flows/BoundStagesList.ts #: src/pages/flows/StageBindingForm.ts msgid "Stage" diff --git a/web/src/pages/sources/ldap/LDAPSourceForm.ts b/web/src/pages/sources/ldap/LDAPSourceForm.ts index 3eccb6051..9c8982711 100644 --- a/web/src/pages/sources/ldap/LDAPSourceForm.ts +++ b/web/src/pages/sources/ldap/LDAPSourceForm.ts @@ -124,6 +124,9 @@ export class LDAPSourceForm extends ModelForm { class="pf-c-form-control" required /> +

+ ${t`Specify multiple server URIs by separating them with a comma.`} +

diff --git a/website/integrations/sources/active-directory/index.md b/website/integrations/sources/active-directory/index.md index faa9087af..769d3eb5d 100644 --- a/website/integrations/sources/active-directory/index.md +++ b/website/integrations/sources/active-directory/index.md @@ -43,6 +43,10 @@ Use these settings: For authentik to be able to write passwords back to Active Directory, make sure to use `ldaps://` + You can specify multiple servers by separating URIs with a comma, like `ldap://dc1.ad.company,ldap://dc2.ad.company`. + + When using a DNS entry with multiple Records, authentik will select a random entry when first connecting. + - Bind CN: `@ad.company` - Bind Password: The password you've given the user above - Base DN: The base DN which you want authentik to sync diff --git a/website/integrations/sources/freeipa/index.md b/website/integrations/sources/freeipa/index.md index 146109d0f..193521c33 100644 --- a/website/integrations/sources/freeipa/index.md +++ b/website/integrations/sources/freeipa/index.md @@ -30,7 +30,7 @@ The following placeholders will be used: ``` $ ldapmodify -x -D "cn=Directory Manager" -W -h ipa1.freeipa.company -p 389 - + dn: cn=ipa_pwd_extop,cn=plugins,cn=config changetype: modify add: passSyncManagersDNs @@ -45,6 +45,11 @@ In authentik, create a new LDAP Source in Resources -> Sources. Use these settings: - Server URI: `ldaps://ipa1.freeipa.company` + + You can specify multiple servers by separating URIs with a comma, like `ldap://ipa1.freeipa.company,ldap://ipa2.freeipa.company`. + + When using a DNS entry with multiple Records, authentik will select a random entry when first connecting. + - Bind CN: `uid=svc_authentik,cn=users,cn=accounts,dc=freeipa,dc=company` - Bind Password: The password you've given the user above - Base DN: `dc=freeipa,dc=company` diff --git a/website/integrations/sources/ldap/index.md b/website/integrations/sources/ldap/index.md index a4eef3086..d373af381 100644 --- a/website/integrations/sources/ldap/index.md +++ b/website/integrations/sources/ldap/index.md @@ -15,6 +15,11 @@ For FreeIPA, follow the [FreeIPA Integration](../freeipa/index.md) ::: - Server URI: URI to your LDAP server/Domain Controller. + + You can specify multiple servers by separating URIs with a comma, like `ldap://ldap1.company,ldap://ldap2.company`. + + When using a DNS entry with multiple Records, authentik will select a random entry when first connecting. + - Bind CN: CN of the bind user. This can also be a UPN in the format of `user@domain.tld`. - Bind password: Password used during the bind process. - Enable StartTLS: Enables StartTLS functionality. To use LDAPS instead, use port `636`. From 2eb5a5cc76bb224d44906bdc54b89d20c4ae7ab7 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 20:24:24 +0100 Subject: [PATCH 31/46] sources/ldap: handle typeerror during creation of objects when using wrong kwargs params Signed-off-by: Jens Langhammer --- authentik/sources/ldap/sync/groups.py | 2 +- authentik/sources/ldap/sync/users.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/authentik/sources/ldap/sync/groups.py b/authentik/sources/ldap/sync/groups.py index 318038a14..99c1793ad 100644 --- a/authentik/sources/ldap/sync/groups.py +++ b/authentik/sources/ldap/sync/groups.py @@ -51,7 +51,7 @@ class GroupLDAPSynchronizer(BaseLDAPSynchronizer): }, defaults, ) - except (IntegrityError, FieldError) as exc: + except (IntegrityError, FieldError, TypeError) as exc: Event.new( EventAction.CONFIGURATION_ERROR, message=( diff --git a/authentik/sources/ldap/sync/users.py b/authentik/sources/ldap/sync/users.py index 00a1574b7..8038303da 100644 --- a/authentik/sources/ldap/sync/users.py +++ b/authentik/sources/ldap/sync/users.py @@ -45,7 +45,7 @@ class UserLDAPSynchronizer(BaseLDAPSynchronizer): ak_user, created = self.update_or_create_attributes( User, {f"attributes__{LDAP_UNIQUENESS}": uniq}, defaults ) - except (IntegrityError, FieldError) as exc: + except (IntegrityError, FieldError, TypeError) as exc: Event.new( EventAction.CONFIGURATION_ERROR, message=( From 4bd1cd127b481bc595dab3161c741c0803d69cf6 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 20:30:03 +0100 Subject: [PATCH 32/46] providers/saml: fix IndexError in signature check Signed-off-by: Jens Langhammer --- authentik/providers/saml/processors/request_parser.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/authentik/providers/saml/processors/request_parser.py b/authentik/providers/saml/processors/request_parser.py index f33f17a1b..6965766cf 100644 --- a/authentik/providers/saml/processors/request_parser.py +++ b/authentik/providers/saml/processors/request_parser.py @@ -100,14 +100,13 @@ class AuthNRequestParser: xmlsec.tree.add_ids(root, ["ID"]) signature_nodes = root.xpath("/samlp:AuthnRequest/ds:Signature", namespaces=NS_MAP) # No signatures, no verifier configured -> decode xml directly - if len(signature_nodes) < 1 and not verifier: - return self._parse_xml(decoded_xml, relay_state) + if len(signature_nodes) < 1: + if not verifier: + return self._parse_xml(decoded_xml, relay_state) + raise CannotHandleAssertion(ERROR_SIGNATURE_REQUIRED_BUT_ABSENT) signature_node = signature_nodes[0] - if verifier and signature_node is None: - raise CannotHandleAssertion(ERROR_SIGNATURE_REQUIRED_BUT_ABSENT) - if signature_node is not None: if not verifier: raise CannotHandleAssertion(ERROR_SIGNATURE_EXISTS_BUT_NO_VERIFIER) From 83ac42ac431dbc6f6f47790cb85ba2eb7689343b Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 20:32:09 +0100 Subject: [PATCH 33/46] stages/prompt: fix error when both default and required are set Signed-off-by: Jens Langhammer --- authentik/stages/prompt/models.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/authentik/stages/prompt/models.py b/authentik/stages/prompt/models.py index d5ca18bff..bd6381d36 100644 --- a/authentik/stages/prompt/models.py +++ b/authentik/stages/prompt/models.py @@ -113,6 +113,9 @@ class Prompt(SerializerModel): kwargs["label"] = "" if default: kwargs["default"] = default + # May not set both `required` and `default` + if "default" in kwargs: + kwargs.pop("required", None) return field_class(**kwargs) def save(self, *args, **kwargs): From ac432e78e2f3d742c807d9e049af44cb249cb2f9 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Thu, 2 Dec 2021 21:11:55 +0100 Subject: [PATCH 34/46] sources/ldap: don't cache LDAP Connection, use random server Signed-off-by: Jens Langhammer --- authentik/sources/ldap/auth.py | 2 +- authentik/sources/ldap/models.py | 45 ++++++++++++++++---------------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/authentik/sources/ldap/auth.py b/authentik/sources/ldap/auth.py index 7b8233c7f..608a27974 100644 --- a/authentik/sources/ldap/auth.py +++ b/authentik/sources/ldap/auth.py @@ -58,7 +58,7 @@ class LDAPBackend(InbuiltBackend): LOGGER.debug("Attempting Binding as user", user=user) try: temp_connection = ldap3.Connection( - source.connection.server, + source.server, user=user.attributes.get(LDAP_DISTINGUISHED_NAME), password=password, raise_exceptions=True, diff --git a/authentik/sources/ldap/models.py b/authentik/sources/ldap/models.py index 53912c5de..1e9535849 100644 --- a/authentik/sources/ldap/models.py +++ b/authentik/sources/ldap/models.py @@ -1,9 +1,9 @@ """authentik LDAP Models""" -from typing import Optional, Type +from typing import Type from django.db import models from django.utils.translation import gettext_lazy as _ -from ldap3 import ALL, ROUND_ROBIN, Connection, Server, ServerPool +from ldap3 import ALL, RANDOM, Connection, Server, ServerPool from rest_framework.serializers import Serializer from authentik.core.models import Group, PropertyMapping, Source @@ -93,31 +93,32 @@ class LDAPSource(Source): return LDAPSourceSerializer - _connection: Optional[Connection] = None + @property + def server(self) -> Server: + """Get LDAP Server/ServerPool""" + servers = [] + if "," in self.server_uri: + for server in self.server_uri.split(","): + servers.append(Server(server, get_info=ALL, connect_timeout=LDAP_TIMEOUT)) + else: + servers = [Server(self.server_uri, get_info=ALL, connect_timeout=LDAP_TIMEOUT)] + return ServerPool(servers, RANDOM, active=True, exhaust=True) @property def connection(self) -> Connection: """Get a fully connected and bound LDAP Connection""" - if not self._connection: - servers = [] - if "," in self.server_uri: - for server in self.server_uri.split(","): - servers.append(Server(server, get_info=ALL, connect_timeout=LDAP_TIMEOUT)) - else: - servers = [Server(self.server_uri, get_info=ALL, connect_timeout=LDAP_TIMEOUT)] - pool = ServerPool(servers, ROUND_ROBIN, active=True, exhaust=True) - self._connection = Connection( - pool, - raise_exceptions=True, - user=self.bind_cn, - password=self.bind_password, - receive_timeout=LDAP_TIMEOUT, - ) + connection = Connection( + self.server, + raise_exceptions=True, + user=self.bind_cn, + password=self.bind_password, + receive_timeout=LDAP_TIMEOUT, + ) - self._connection.bind() - if self.start_tls: - self._connection.start_tls() - return self._connection + connection.bind() + if self.start_tls: + connection.start_tls() + return connection class Meta: From 2e2b491ec7eed06c68162ae767181d9418f08b44 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Fri, 3 Dec 2021 09:41:13 +0100 Subject: [PATCH 35/46] source/ldap: fix hanging unittests Signed-off-by: Jens Langhammer --- authentik/sources/ldap/tests/test_sync.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/authentik/sources/ldap/tests/test_sync.py b/authentik/sources/ldap/tests/test_sync.py index a26f48378..af8e9d71b 100644 --- a/authentik/sources/ldap/tests/test_sync.py +++ b/authentik/sources/ldap/tests/test_sync.py @@ -120,9 +120,9 @@ class LDAPSyncTests(TestCase): self.source.property_mappings_group.set( LDAPPropertyMapping.objects.filter(managed="goauthentik.io/sources/ldap/default-name") ) - self.source.save() connection = PropertyMock(return_value=mock_ad_connection(LDAP_PASSWORD)) with patch("authentik.sources.ldap.models.LDAPSource.connection", connection): + self.source.save() group_sync = GroupLDAPSynchronizer(self.source) group_sync.sync() membership_sync = MembershipLDAPSynchronizer(self.source) @@ -143,9 +143,9 @@ class LDAPSyncTests(TestCase): self.source.property_mappings_group.set( LDAPPropertyMapping.objects.filter(managed="goauthentik.io/sources/ldap/openldap-cn") ) - self.source.save() connection = PropertyMock(return_value=mock_slapd_connection(LDAP_PASSWORD)) with patch("authentik.sources.ldap.models.LDAPSource.connection", connection): + self.source.save() group_sync = GroupLDAPSynchronizer(self.source) group_sync.sync() membership_sync = MembershipLDAPSynchronizer(self.source) @@ -168,9 +168,9 @@ class LDAPSyncTests(TestCase): self.source.property_mappings_group.set( LDAPPropertyMapping.objects.filter(managed="goauthentik.io/sources/ldap/openldap-cn") ) - self.source.save() connection = PropertyMock(return_value=mock_slapd_connection(LDAP_PASSWORD)) with patch("authentik.sources.ldap.models.LDAPSource.connection", connection): + self.source.save() user_sync = UserLDAPSynchronizer(self.source) user_sync.sync() group_sync = GroupLDAPSynchronizer(self.source) From 8ae50814fe8a3d4b46211cd784ee874c5a450130 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Fri, 3 Dec 2021 10:02:57 +0100 Subject: [PATCH 36/46] *: add missing migrations Signed-off-by: Jens Langhammer --- .../0019_alter_eventmatcherpolicy_app.py | 2 +- .../migrations/0006_alter_prompt_type.py | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 authentik/stages/prompt/migrations/0006_alter_prompt_type.py diff --git a/authentik/policies/event_matcher/migrations/0019_alter_eventmatcherpolicy_app.py b/authentik/policies/event_matcher/migrations/0019_alter_eventmatcherpolicy_app.py index b5403e033..fddc5bbab 100644 --- a/authentik/policies/event_matcher/migrations/0019_alter_eventmatcherpolicy_app.py +++ b/authentik/policies/event_matcher/migrations/0019_alter_eventmatcherpolicy_app.py @@ -69,8 +69,8 @@ class Migration(migrations.Migration): ("authentik.stages.user_logout", "authentik Stages.User Logout"), ("authentik.stages.user_write", "authentik Stages.User Write"), ("authentik.tenants", "authentik Tenants"), - ("authentik.core", "authentik Core"), ("authentik.managed", "authentik Managed"), + ("authentik.core", "authentik Core"), ], default="", help_text="Match events created by selected application. When left empty, all applications are matched.", diff --git a/authentik/stages/prompt/migrations/0006_alter_prompt_type.py b/authentik/stages/prompt/migrations/0006_alter_prompt_type.py new file mode 100644 index 000000000..eeeaf522b --- /dev/null +++ b/authentik/stages/prompt/migrations/0006_alter_prompt_type.py @@ -0,0 +1,43 @@ +# Generated by Django 3.2.9 on 2021-12-03 09:00 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("authentik_stages_prompt", "0005_alter_prompt_field_key"), + ] + + operations = [ + migrations.AlterField( + model_name="prompt", + name="type", + field=models.CharField( + choices=[ + ("text", "Text: Simple Text input"), + ( + "text_read_only", + "Text (read-only): Simple Text input, but cannot be edited.", + ), + ( + "username", + "Username: Same as Text input, but checks for and prevents duplicate usernames.", + ), + ("email", "Email: Text field with Email type."), + ( + "password", + "Password: Masked input, password is validated against sources. Policies still have to be applied to this Stage. If two of these are used in the same stage, they are ensured to be identical.", + ), + ("number", "Number"), + ("checkbox", "Checkbox"), + ("date", "Date"), + ("date-time", "Date Time"), + ("separator", "Separator: Static Separator Line"), + ("hidden", "Hidden: Hidden field, can be used to insert data into form."), + ("static", "Static: Static value, displayed as-is."), + ], + max_length=100, + ), + ), + ] From 99c62af89e9e790022d75da96bee73b551887861 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Fri, 3 Dec 2021 10:05:21 +0100 Subject: [PATCH 37/46] ci: add check to ensure no migrations are missing Signed-off-by: Jens Langhammer --- .github/workflows/ci-main.yml | 1 + Makefile | 3 +++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/ci-main.yml b/.github/workflows/ci-main.yml index 7d4a9433f..baf0430c9 100644 --- a/.github/workflows/ci-main.yml +++ b/.github/workflows/ci-main.yml @@ -28,6 +28,7 @@ jobs: - isort - bandit - pyright + - pending-migrations runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 diff --git a/Makefile b/Makefile index 1b9a85854..b2792c949 100644 --- a/Makefile +++ b/Makefile @@ -113,3 +113,6 @@ ci-bandit: ci-pyright: pyright e2e lifecycle + +ci-pending-migrations: + ./manage.py makemigrations --check From f1b9021e3ee52f5d8f7bca151dc990033b78f274 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Fri, 3 Dec 2021 10:09:13 +0100 Subject: [PATCH 38/46] sources/ldap: add optional tls verification certificate closes #1875 Signed-off-by: Jens Langhammer --- authentik/sources/ldap/api.py | 5 +-- .../migrations/0002_auto_20211203_0900.py | 38 ++++++++++++++++++ authentik/sources/ldap/models.py | 27 +++++++++++-- schema.yml | 34 +++++++++------- web/src/locales/en.po | 6 +++ web/src/locales/fr_FR.po | 6 +++ web/src/locales/pseudo-LOCALE.po | 6 +++ web/src/pages/sources/ldap/LDAPSourceForm.ts | 39 +++++++++++++++++++ 8 files changed, 141 insertions(+), 20 deletions(-) create mode 100644 authentik/sources/ldap/migrations/0002_auto_20211203_0900.py diff --git a/authentik/sources/ldap/api.py b/authentik/sources/ldap/api.py index aae8e643a..7b1413c4b 100644 --- a/authentik/sources/ldap/api.py +++ b/authentik/sources/ldap/api.py @@ -43,6 +43,7 @@ class LDAPSourceSerializer(SourceSerializer): model = LDAPSource fields = SourceSerializer.Meta.fields + [ "server_uri", + "peer_certificate", "bind_cn", "bind_password", "start_tls", @@ -73,11 +74,9 @@ class LDAPSourceViewSet(UsedByMixin, ModelViewSet): "name", "slug", "enabled", - "authentication_flow", - "enrollment_flow", - "policy_engine_mode", "server_uri", "bind_cn", + "peer_certificate", "start_tls", "base_dn", "additional_user_dn", diff --git a/authentik/sources/ldap/migrations/0002_auto_20211203_0900.py b/authentik/sources/ldap/migrations/0002_auto_20211203_0900.py new file mode 100644 index 000000000..2161b7cbf --- /dev/null +++ b/authentik/sources/ldap/migrations/0002_auto_20211203_0900.py @@ -0,0 +1,38 @@ +# Generated by Django 3.2.9 on 2021-12-03 09:00 + +import django.db.models.deletion +from django.db import migrations, models + +import authentik.sources.ldap.models + + +class Migration(migrations.Migration): + + dependencies = [ + ("authentik_crypto", "0003_certificatekeypair_managed"), + ("authentik_sources_ldap", "0001_squashed_0012_auto_20210812_1703"), + ] + + operations = [ + migrations.AddField( + model_name="ldapsource", + name="peer_certificate", + field=models.ForeignKey( + default=None, + help_text="Optionally verify the LDAP Server's Certificate against the CA Chain in this keypair.", + null=True, + on_delete=django.db.models.deletion.SET_DEFAULT, + to="authentik_crypto.certificatekeypair", + ), + ), + migrations.AlterField( + model_name="ldapsource", + name="server_uri", + field=models.TextField( + validators=[ + authentik.sources.ldap.models.MultiURLValidator(schemes=["ldap", "ldaps"]) + ], + verbose_name="Server URI", + ), + ), + ] diff --git a/authentik/sources/ldap/models.py b/authentik/sources/ldap/models.py index 1e9535849..ade91978e 100644 --- a/authentik/sources/ldap/models.py +++ b/authentik/sources/ldap/models.py @@ -1,12 +1,14 @@ """authentik LDAP Models""" +from ssl import CERT_REQUIRED from typing import Type from django.db import models from django.utils.translation import gettext_lazy as _ -from ldap3 import ALL, RANDOM, Connection, Server, ServerPool +from ldap3 import ALL, RANDOM, Connection, Server, ServerPool, Tls from rest_framework.serializers import Serializer from authentik.core.models import Group, PropertyMapping, Source +from authentik.crypto.models import CertificateKeyPair from authentik.lib.models import DomainlessURLValidator LDAP_TIMEOUT = 15 @@ -30,6 +32,17 @@ class LDAPSource(Source): validators=[MultiURLValidator(schemes=["ldap", "ldaps"])], verbose_name=_("Server URI"), ) + peer_certificate = models.ForeignKey( + CertificateKeyPair, + on_delete=models.SET_DEFAULT, + default=None, + null=True, + help_text=_( + "Optionally verify the LDAP Server's Certificate " + "against the CA Chain in this keypair." + ), + ) + bind_cn = models.TextField(verbose_name=_("Bind CN"), blank=True) bind_password = models.TextField(blank=True) start_tls = models.BooleanField(default=False, verbose_name=_("Enable Start TLS")) @@ -97,11 +110,19 @@ class LDAPSource(Source): def server(self) -> Server: """Get LDAP Server/ServerPool""" servers = [] + tls = Tls() + if self.peer_certificate: + tls = Tls(ca_certs_data=self.peer_certificate.certificate_data, validate=CERT_REQUIRED) + kwargs = { + "get_info": ALL, + "connect_timeout": LDAP_TIMEOUT, + "tls": tls, + } if "," in self.server_uri: for server in self.server_uri.split(","): - servers.append(Server(server, get_info=ALL, connect_timeout=LDAP_TIMEOUT)) + servers.append(Server(server, **kwargs)) else: - servers = [Server(self.server_uri, get_info=ALL, connect_timeout=LDAP_TIMEOUT)] + servers = [Server(self.server_uri, **kwargs)] return ServerPool(servers, RANDOM, active=True, exhaust=True) @property diff --git a/schema.yml b/schema.yml index 77905dc2b..28dae5da6 100644 --- a/schema.yml +++ b/schema.yml @@ -12058,11 +12058,6 @@ paths: name: additional_user_dn schema: type: string - - in: query - name: authentication_flow - schema: - type: string - format: uuid - in: query name: base_dn schema: @@ -12075,11 +12070,6 @@ paths: name: enabled schema: type: boolean - - in: query - name: enrollment_flow - schema: - type: string - format: uuid - in: query name: group_membership_field schema: @@ -12115,12 +12105,10 @@ paths: schema: type: integer - in: query - name: policy_engine_mode + name: peer_certificate schema: type: string - enum: - - all - - any + format: uuid - in: query name: property_mappings schema: @@ -22461,6 +22449,12 @@ components: server_uri: type: string format: uri + peer_certificate: + type: string + format: uuid + nullable: true + description: Optionally verify the LDAP Server's Certificate against the + CA Chain in this keypair. bind_cn: type: string start_tls: @@ -22558,6 +22552,12 @@ components: type: string minLength: 1 format: uri + peer_certificate: + type: string + format: uuid + nullable: true + description: Optionally verify the LDAP Server's Certificate against the + CA Chain in this keypair. bind_cn: type: string bind_password: @@ -27181,6 +27181,12 @@ components: type: string minLength: 1 format: uri + peer_certificate: + type: string + format: uuid + nullable: true + description: Optionally verify the LDAP Server's Certificate against the + CA Chain in this keypair. bind_cn: type: string bind_password: diff --git a/web/src/locales/en.po b/web/src/locales/en.po index 15bc01096..8a93dad05 100644 --- a/web/src/locales/en.po +++ b/web/src/locales/en.po @@ -2608,6 +2608,7 @@ msgstr "Loading" #: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/ldap/LDAPSourceForm.ts +#: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/oauth/OAuthSourceForm.ts #: src/pages/sources/oauth/OAuthSourceForm.ts #: src/pages/sources/plex/PlexSourceForm.ts @@ -4743,6 +4744,7 @@ msgstr "TLS Authentication Certificate" #~ msgstr "TLS Server name" #: src/pages/outposts/ServiceConnectionDockerForm.ts +#: src/pages/sources/ldap/LDAPSourceForm.ts msgid "TLS Verification Certificate" msgstr "TLS Verification Certificate" @@ -5651,6 +5653,10 @@ msgstr "When a user returns from the email successfully, their account will be a msgid "When a valid username/email has been entered, and this option is enabled, the user's username and avatar will be shown. Otherwise, the text that the user entered will be shown." msgstr "When a valid username/email has been entered, and this option is enabled, the user's username and avatar will be shown. Otherwise, the text that the user entered will be shown." +#: src/pages/sources/ldap/LDAPSourceForm.ts +msgid "When connecting to an LDAP Server with TLS, certificates are not checked by default. Specify a keypair to validate the remote certificate." +msgstr "When connecting to an LDAP Server with TLS, certificates are not checked by default. Specify a keypair to validate the remote certificate." + #: src/pages/stages/email/EmailStageForm.ts msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored." msgstr "When enabled, global Email connection settings will be used and connection settings below will be ignored." diff --git a/web/src/locales/fr_FR.po b/web/src/locales/fr_FR.po index 39c9ccbc5..8ef47c80a 100644 --- a/web/src/locales/fr_FR.po +++ b/web/src/locales/fr_FR.po @@ -2589,6 +2589,7 @@ msgstr "Chargement en cours" #: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/ldap/LDAPSourceForm.ts +#: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/oauth/OAuthSourceForm.ts #: src/pages/sources/oauth/OAuthSourceForm.ts #: src/pages/sources/plex/PlexSourceForm.ts @@ -4699,6 +4700,7 @@ msgstr "Certificat TLS d'authentification" #~ msgstr "Nom TLS du serveur" #: src/pages/outposts/ServiceConnectionDockerForm.ts +#: src/pages/sources/ldap/LDAPSourceForm.ts msgid "TLS Verification Certificate" msgstr "Certificat de vérification TLS" @@ -5594,6 +5596,10 @@ msgstr "Lorsqu'un utilisateur revient de l'e-mail avec succès, son compte sera msgid "When a valid username/email has been entered, and this option is enabled, the user's username and avatar will be shown. Otherwise, the text that the user entered will be shown." msgstr "Lorsqu'un nom d'utilisateur/email valide a été saisi, et si cette option est active, le nom d'utilisateur et l'avatar de l'utilisateur seront affichés. Sinon, le texte que l'utilisateur a saisi sera affiché." +#: src/pages/sources/ldap/LDAPSourceForm.ts +msgid "When connecting to an LDAP Server with TLS, certificates are not checked by default. Specify a keypair to validate the remote certificate." +msgstr "" + #: src/pages/stages/email/EmailStageForm.ts msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored." msgstr "Si activé, les paramètres globaux de connexion courriel seront utilisés et les paramètres de connexion ci-dessous seront ignorés." diff --git a/web/src/locales/pseudo-LOCALE.po b/web/src/locales/pseudo-LOCALE.po index 102f50448..d3d7b7917 100644 --- a/web/src/locales/pseudo-LOCALE.po +++ b/web/src/locales/pseudo-LOCALE.po @@ -2600,6 +2600,7 @@ msgstr "" #: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/ldap/LDAPSourceForm.ts +#: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/oauth/OAuthSourceForm.ts #: src/pages/sources/oauth/OAuthSourceForm.ts #: src/pages/sources/plex/PlexSourceForm.ts @@ -4735,6 +4736,7 @@ msgstr "" #~ msgstr "" #: src/pages/outposts/ServiceConnectionDockerForm.ts +#: src/pages/sources/ldap/LDAPSourceForm.ts msgid "TLS Verification Certificate" msgstr "" @@ -5636,6 +5638,10 @@ msgstr "" msgid "When a valid username/email has been entered, and this option is enabled, the user's username and avatar will be shown. Otherwise, the text that the user entered will be shown." msgstr "" +#: src/pages/sources/ldap/LDAPSourceForm.ts +msgid "When connecting to an LDAP Server with TLS, certificates are not checked by default. Specify a keypair to validate the remote certificate." +msgstr "" + #: src/pages/stages/email/EmailStageForm.ts msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored." msgstr "" diff --git a/web/src/pages/sources/ldap/LDAPSourceForm.ts b/web/src/pages/sources/ldap/LDAPSourceForm.ts index 9c8982711..59729d5ab 100644 --- a/web/src/pages/sources/ldap/LDAPSourceForm.ts +++ b/web/src/pages/sources/ldap/LDAPSourceForm.ts @@ -7,6 +7,7 @@ import { until } from "lit/directives/until.js"; import { CoreApi, + CryptoApi, LDAPSource, LDAPSourceRequest, PropertymappingsApi, @@ -141,6 +142,44 @@ export class LDAPSourceForm extends ModelForm { ${t`To use SSL instead, use 'ldaps://' and disable this option.`}

+ + +

+ ${t`When connecting to an LDAP Server with TLS, certificates are not checked by default. Specify a keypair to validate the remote certificate.`} +

+
Date: Fri, 3 Dec 2021 10:11:44 +0100 Subject: [PATCH 39/46] web: Update Web API Client version (#1876) Signed-off-by: GitHub Co-authored-by: BeryJu --- 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 0a6ecde70..30283ea8b 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -15,7 +15,7 @@ "@babel/preset-env": "^7.16.4", "@babel/preset-typescript": "^7.16.0", "@fortawesome/fontawesome-free": "^5.15.4", - "@goauthentik/api": "^2021.10.4-1638386397", + "@goauthentik/api": "^2021.10.4-1638522576", "@jackfranklin/rollup-plugin-markdown": "^0.3.0", "@lingui/cli": "^3.13.0", "@lingui/core": "^3.13.0", @@ -1708,9 +1708,9 @@ } }, "node_modules/@goauthentik/api": { - "version": "2021.10.4-1638386397", - "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.10.4-1638386397.tgz", - "integrity": "sha512-W5iFNK9bcYdOYg7CVuloPmd2T7Ct+OWFMSWwiYSQcMzt3hj1Ff6g+CBLt2yCgq6zAQGeh5Le8lfk+uQKixc/Fw==" + "version": "2021.10.4-1638522576", + "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.10.4-1638522576.tgz", + "integrity": "sha512-ojnhGFPnEHXPeMULMtRUBoRVB8k0B73l3O5UL8NSipaY2ZC7jSscIQKDZWz7yvvx9NPMV34kKJ9NK8N+/jzfgw==" }, "node_modules/@humanwhocodes/config-array": { "version": "0.6.0", @@ -9895,9 +9895,9 @@ "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==" }, "@goauthentik/api": { - "version": "2021.10.4-1638386397", - "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.10.4-1638386397.tgz", - "integrity": "sha512-W5iFNK9bcYdOYg7CVuloPmd2T7Ct+OWFMSWwiYSQcMzt3hj1Ff6g+CBLt2yCgq6zAQGeh5Le8lfk+uQKixc/Fw==" + "version": "2021.10.4-1638522576", + "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2021.10.4-1638522576.tgz", + "integrity": "sha512-ojnhGFPnEHXPeMULMtRUBoRVB8k0B73l3O5UL8NSipaY2ZC7jSscIQKDZWz7yvvx9NPMV34kKJ9NK8N+/jzfgw==" }, "@humanwhocodes/config-array": { "version": "0.6.0", diff --git a/web/package.json b/web/package.json index 2606a43ae..1198f78d5 100644 --- a/web/package.json +++ b/web/package.json @@ -51,7 +51,7 @@ "@babel/preset-env": "^7.16.4", "@babel/preset-typescript": "^7.16.0", "@fortawesome/fontawesome-free": "^5.15.4", - "@goauthentik/api": "^2021.10.4-1638386397", + "@goauthentik/api": "^2021.10.4-1638522576", "@jackfranklin/rollup-plugin-markdown": "^0.3.0", "@lingui/cli": "^3.13.0", "@lingui/core": "^3.13.0", From caa3c3de32cdd5070672328807b1fabbfa6a87ef Mon Sep 17 00:00:00 2001 From: tigattack <10629864+tigattack@users.noreply.github.com> Date: Fri, 3 Dec 2021 15:50:24 +0000 Subject: [PATCH 40/46] web: Add Christmas icon (#1879) --- web/icons/icon_christmas.png | Bin 0 -> 153509 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 web/icons/icon_christmas.png diff --git a/web/icons/icon_christmas.png b/web/icons/icon_christmas.png new file mode 100644 index 0000000000000000000000000000000000000000..089040dc70765acf899681a4eb0eefc8be6cf4ae GIT binary patch literal 153509 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%0Dn2 zNPaY_XSL6tbWKKow~n@F;7tg_66Vt4%EnoP!K>ekKrB1lL&dneMVy1!??Bu~A{owN zA%lPHVDsk}fOQWWW@w-_mr9OelPfmRg-l3Gz%TA!627bciO7HM8;hkkgEB`Uo*%2IQQ9extRbVMOQ@(%50&2Nk1~&TdOw>J6)gq^ z0*|_vR$ydviUWBhB_m~{Rui*JuGqVGH=X|ko7(G?S+x=6?DN=`A(BV^F*TPaonNoS z=3DGUBQ~qy^n91`uetXhSZj*`oT2D;9Ed~E`!)VBa9ubb7eUx((O{EB)nfz3!cOMP&Z#;t+CNd*GybNKedrT(0Z9a#gedBqr*UJ&a{PTQmnbQAR z&7F>RUh;tOkML~weH%h^+W}dWSuK}oLd^j}&$C>rUoYhj+cMQ3dx5iK+eO7S7f2Lj zOxa~z{jMdG(cLWTZr|u=p1v(%>F|U;^n$=GUs|`uJ~fze`2t>ha9PG0)|Y><%l}Xl z8{$S(VExCU#5`6MT z&W+y#5@UoYus*9M$UeGb2YUhz*S96FXe`5OJ@1Ehvrp+H9}S5n2ji6e2=@NR3n1hf zq3-~zI0-^5$Znb}OA}`v)=6}ruse88T6y#Y4CGb@%PB_eFzzU%&cl}Eq)Cpx6etfk zz1L1emQpR1PZiKET=p2YmbvfY5{3$Ab2o~~k;d2Fuk6rsd~uwA^`mp^Wyg1F#?#+* z-REs{O3atRNhM4fZ;EhbrJaxD(ST`f+}ZGUtx^gKuf~2J5+A4vlG6`t@TEqUbost% zFfo5Nlg+VdwTFjJ)qQXmhGp@@akp0Z2=skeiWY31kX^a@45L2`fv1#^F>`E+vkX_K z$MadhC47A5iXs-C4M(hpKnRmZ8VwWCz&$5U8U5{20r{k{PQ5!u7%@gY%O*uk#Aun7 zMNPbTsAdxSMSNZG^g_ja2oHxx&2zYX@-D4$Kjbv++r^MSOyrV4bxBnBU^Lkbo&DYH z1o164tA3J6K%X|}qM+P-Ys8M^H~aY3qcVyB(a{{F{SB)u@n=JsF4?C-@?k4b@YA-f zVfZBZMZMFX^hN$Bbo-5Guanaqm}xB{g5PCu=Km&=zWKu_v7r39Ks{f!cX@u-#0b*c z#qZfw%s{Q%8=T~NAJKF3>uvXUF+61DTY#;ntcWNXOOZ!4H@Dx2N4WXl{kD!YdYy0qt+DEbk_0U zG{hq6d5@4vus_y3_)pu_h_rEWI(L)$pNs_oj5uYerebx_LCw3D;s4>!4zda||4s{2K4o9oLmISqt`o z5p^tL;b2Conq#ev^u4=jq*!@K{>otTN(=lk$ z5R-S>F2f)iUL!G?eDf-W{)ePG>h0Lf7Me-j+gbHUzO;P$6*4sUi~{PJLR8gBt>|cz zbpJ+{T?iyhmkZZ}f%Sn!;{C;P*O1+IuuYBu?pVp`32Z&FMiU-s|eV zyZ-qWEKPl8b@-8(*w&ax_Yy(qMacT;zn`_?lltP|prT*yE_Zf~m0WW`9$u5&v#;-YH`ql5q|wqusQ zQs+&_*Cmwqq}JP5s0;lIlR#LwZYIE1l?u%C1rBQ1yC^@P=5_;F_vZ?pnF!3t{0;Y=o=l;WsZKK8lE(cMtQo;G52K#I#iGV_eYwEw#~{!?AMW=WXf9GBD#@Eu-ly7u zRDzC;oKO4RY=zJ+lN)#@qr;KZDt|y4oE9wyJsC2ApfLi;E;<)$v*OB`28=}bA!Xs1 zjEr-Ii*%PI9u4Qjou=_q@^!5F?mtJnO!ZtcbZ)zQatCZ~PIYg5JX)M|x`F*+p82)5 zrAHvEtr!J$9jO38YYH9Vc1#uHRoP$;bc%k{4lEr?S_8QA34i5@isYxFd1iKJL)yx-ENAR8gXwN zY@i^_k@)VwA-rn%56&9>?U8@(7N^A%jhe1eqCpnQ2RjM}Kd?w5(%3;hDycvi9dj-y^v?V+b#9tFfuH1X=YL6$cx9SBsfuU=I9wZ%sva#iJXgfsofHx!Zi;kjlcGv%5#BPp;L{T zYHHvslxGh^4Uy3OtC|pg%h!rQUz-N$hwsNvoEhU>6seHbs@`#)Hn^P)g`Os(k`pKB zQ%XEb>~<)TaK8^)?zAkpq=!%W=u+0WQZO2L=;c@|lRP0=(*c+bqQI!Ko^sIg`uT){$HZIRvY$UOs--1G}?>Vr7lDrONR~ErPK1SV5lvLGi!;45qvrd$a4@0i zu(fd9$9+%st(JzU;t2&uHTwYHE6o5Nx+)8+I4-KTv_=eZy0GQ|sT8v67(Pn3lzAFP zW!4pD#p-UgOjGL#di>wU_78}7t{icu&wZxO=ejY>n3)L_%#_!ALlmdLYWU!lLToSr z+j+eDG|3*36fG7$$f}Lclc!|KAgq{=Td%NE-Kp%&*A~MSxLE!RfAh_Lf>@&awcTp9F%`}!38Yl@)jh+N5b&=gX?lbVHDo$6~x;1sgar>Oev=tJLDMY9$ z1`(^-1|AFwu<($V$R8KY8T)Q1X4A~nCNl^NCT-+w$O6$6C~me+Z-ao)w0 zCeck45_4;`YhOhZ2v85HHS2eRv^MG}Qm~j=P?MT^&1>oJJ5BK0gYoE`QyWPOX{IFD z@vf%L9LO;D94+)C2?{}f&I`~YgFk2kVZI8PXvuo&x>SaRuL^uDu-_M; zDe&e#Nxp<0|4&G)xK!7T6NR3p23#+<_)}$F<;mxtDs^(3{vTO?6&B~VtPR7BySux) z6Wk#SdA`2t5(LGz+y>Fo4rOG$p^VsIqzKEF2vq(!( z;m9n2My`v&I#4M+EPmE2)7AkIA8D>ySSk6gTe?K&GXaW7C0P(+7UX@(*=amew8g>u zYR;2uEWvK4I3tJvgw<_^-;|K1O!xb%nlyJkgEZ5YQW;$Z zte4wn%2pI6*9VzwCS3G|gD3ia55ILC)3S^nHk!t-!KRueyuBLbn<$J=mGf=h3VpZZ z=qb5rGF-MdUdwc4VLb$7aInBrPZ!T zK}Qjb9G{uR-JqA&gTnR$1dOwKewS>v*L!$*jV0PN-@R}nanbf#iOc?3@qI&n@uUSh z;@SSXj~?>>D|sG#`V;HbQ!e9vP7w<3x=TdY{zR4sr@23W?cDfIbcf(?_WQQet-72x z%p)Q>g}&CJh3RFK9PTu5*o>x+hX7nu&c<@2yRCM09Z5t@FvA)O!C*$|SQ#K%CzAdp z6Pu>uGv`3u@fS|fNIB^=;_w3N$-8uok93TCg%W*>$&Ev3=zhoRMcg;1)7UMYRlNcm z4=TXo;S;qs!7P>VhP#7INw!({BQwKeuiiq6uBgo(T*=3e1=}Y|lj~rT!R4?T-0{(q ztp~%qI%Fn`WZ8I770q2UMPMHsgi4_s;0V}S#=uVc=Vw-qC!1c8kV-gvSq zn}nuco3o3v6%D=;h;C(BEc+R?7PZ8l(owD8l023y@xyQm$V~XWXk~axeZ@f29n{0J zi|rj@y{}?nm+!ZVP(@>R|3E3LXnE{m|EH1#l@@bqmQ{aSDs*C`fFs<5M-<8oRoDj*3(Y{m`KW+cK(DOF8wkg;89u?5iQE zc@|Z^nz2J`!wX6(I>u-IpN1Uiu3z^ZIgR-o2)91$%xZ$*=?Y70U^OU{R8xcm=+hz` z9I`g2Bk8ZX^&VGpK?BQJcyoRV6yco9Q_&L2IYi`Iaf$|5e10jKH*%^!O)oaMY8$Qyfklc3DXZ7fYBW+mP+?wK7E?BtR- zq;L&-DoD2d-(e#)9X1a11Qd-V9)P>^10+q~V`%Zv^_jjq9;V8b1e~|Ns{HPIweaN` zSidDBigxqI^;inviNr+@OF~Zt{B#DR-a2zcB@7+wW6WYgsxca(W6&Pu5k^-LaC$@T zbQW9?gx|fBAR$&nCl|U@8|s*oCXXE*O?-Oy`PuaFpl`6pW#Hn%wyo!6 z43-c*Yh2Z;v{+q5h{4ga`8Sy0Y$rr znRh83rt)%$VRLl6Iiy?t6|4pSJhVNxa);k5Qr-j(}sdAJ*kf-bNIPQ}J z_F5g*<%n74rd%B%+NyehpjSo2>Uvfs zuMuK%QWVe+#Z`Ruo>|GGHc%6D_NZ5-7wo|54cK4)S;&zuK9uv8D#w!$Cp_d1*Mf3psk5TH1dqqES%tYe|KiqOGq-Ka;g z*&P{;cybf+(vunSAmSu3JYj(A-oXkw0E8@*&zS(t?4)2d0c)9OA@7gkKHkN=M6LZY zVtd7`I8y1Byld(4Uj!p{22|nK1++`ow6Yemh1lYvhG!%IF%Gd9q^?7ACII0ynlz!| za@L)9$k5HcY%G)nvGES6r{A$lB|}MEMY`ejWRrZ}<#r}f?YQ8Y@x%pw4g-KbY6#Fv zD9#6uHW5m@-+^k6m=P0HmQp0^^34Okztfq?ZTV6a`e_+v0j7^F#d`HYw&)G8HD~`~ z5rSrCAQ$+^9`$iSXhQQvdxA4c4JMFRQT#}p>?($=J5jXxlU?`iU+ z7rDpo>}nyMYQlLY3GchQj2Vq!c?!hK_Zf=Wx6xcSA9P$+l|EShLWWie``skWhe`7# zNB@rnL=sj`8fLk^ICLsm#(?*?C|gy`PbbDR_w_scsAaI|$reFMC}h#f{^G#K{nOEp zeoNn2 z;+AoO_Q!xh^zI$z%-5W7oj2kHhJ8DqGQrM=P>lK7Ts-Es;)7Tu-hIpwXY{LzdGcsB#Q5~gFdqX>EVy$qywDDCy1Q*K8B5q zO1V~I9_7V-`w+hZ4;z-udr`$T&CGft%iVJ5J&a+9}~1*{iPE6?ZZFboebjky>nw?un~N;x8z{ zhiKFrn+0#gJjb@YH5FrEh5Qw`1>FpdW5?bf_GEMBq%ae7M#7|_>rQ7X$asVeh*uxp zM!z?PNuODf>kgT*az0#l-P}>{S*SVDks->pI)HxET{nI=a8j7cOZ`LqS?=25M&9(C zV;CLLePk*TFUKjPSFIl7{hX%lT)9fek6*&H9Yzo69C*lS2U>kkV<3+lA+_y=sJJ&x zr!80XP8v9GBV{ZX>N1VX;ouYB`J6cQ2*`De{b0kv2wr6e1GcClm_Bv|V*AgCAbSUU zzYGnA)@;?6ktFh1ws&_>y3~|IRZ}^3nC1QJuCL{Ve#qsbONDYuak8)%QgS+`ZP>uOU6>+RVoXcOTZ1~&M`l~fl{F57WNtRfg-BNS~$ zCiy*@f+KD{E!ps0DlQYRphnh7ZT`&7!>1EL0q4@DQfkl8LO||Shbf#|0j!10Pu^L6 z3!PDX03)EsDeSyW>`+?d%t8~-2ge5FG%kK8tB_aCBs^57icqgCpb(6{! zKA$Uxiw78R6K{@A4*)glRT{=~YJ)IBoCWixYk#x)pA{C>?QR;|8vr$zAyNYC&N-4D z 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 literal 0 HcmV?d00001 From 8db68410c6924c485cee748ac2e5ea9b4acf3ffe Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Fri, 3 Dec 2021 11:55:09 +0100 Subject: [PATCH 41/46] website/docs: re-organise core concepts Signed-off-by: Jens Langhammer --- website/docs/{ => core}/applications.md | 1 + website/docs/{ => core}/tenants.md | 1 + website/docs/{ => core}/terminology.md | 1 + website/sidebars.js | 14 ++++---------- 4 files changed, 7 insertions(+), 10 deletions(-) rename website/docs/{ => core}/applications.md (98%) rename website/docs/{ => core}/tenants.md (98%) rename website/docs/{ => core}/terminology.md (99%) diff --git a/website/docs/applications.md b/website/docs/core/applications.md similarity index 98% rename from website/docs/applications.md rename to website/docs/core/applications.md index 7ec5ed07f..ab6ffec2e 100644 --- a/website/docs/applications.md +++ b/website/docs/core/applications.md @@ -1,5 +1,6 @@ --- title: Applications +slug: /applications --- Applications in authentik are the counterpart of providers. They exist in a 1-to-1 relationship, each application needs a provider and every provider can be used with one application. diff --git a/website/docs/tenants.md b/website/docs/core/tenants.md similarity index 98% rename from website/docs/tenants.md rename to website/docs/core/tenants.md index 5ed91b73d..210366733 100644 --- a/website/docs/tenants.md +++ b/website/docs/core/tenants.md @@ -1,5 +1,6 @@ --- title: Tenants +slug: /tenants --- authentik support soft multi-tenancy. This means that you can configure several options depending on domain, but all the objects like applications, providers, etc, are still global. This can be handy to use the same authentik instance, but branded differently for different domains. diff --git a/website/docs/terminology.md b/website/docs/core/terminology.md similarity index 99% rename from website/docs/terminology.md rename to website/docs/core/terminology.md index 1b6ea1e42..b8569b8a6 100644 --- a/website/docs/terminology.md +++ b/website/docs/core/terminology.md @@ -1,6 +1,7 @@ --- id: terminology title: Terminology +slug: /terminology --- ![](/img/authentik_objects.svg) diff --git a/website/sidebars.js b/website/sidebars.js index 610b70438..1fe80b9d7 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -4,10 +4,6 @@ module.exports = { type: "doc", id: "index", }, - { - type: "doc", - id: "terminology", - }, { type: "category", label: "Installation", @@ -23,8 +19,10 @@ module.exports = { ], }, { - type: "doc", - id: "applications", + type: "category", + label: "Core Concepts", + collapsed: false, + items: ["core/terminology", "core/applications", "core/tenants"], }, { type: "category", @@ -121,10 +119,6 @@ module.exports = { label: "Users & Groups", items: ["user-group/user", "user-group/group"], }, - { - type: "doc", - id: "tenants", - }, { type: "category", label: "Maintenance", From 572f6d4ea0aed7074b0150489b08b11ec87cd1da Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Fri, 3 Dec 2021 18:27:06 +0100 Subject: [PATCH 42/46] crypto: add certificate discovery to automatically import certificates from lets encrypt Signed-off-by: Jens Langhammer #1835 --- authentik/crypto/api.py | 3 +- authentik/crypto/apps.py | 1 + authentik/crypto/settings.py | 10 +++ authentik/crypto/tasks.py | 67 +++++++++++++++++++ authentik/crypto/tests.py | 33 +++++++++ authentik/lib/default.yml | 1 + docker-compose.yml | 1 + lifecycle/ak | 2 +- web/src/locales/en.po | 8 +++ web/src/locales/fr_FR.po | 8 +++ web/src/locales/pseudo-LOCALE.po | 8 +++ .../crypto/CertificateKeyPairListPage.ts | 7 +- website/docs/core/certificates.md | 57 ++++++++++++++++ website/sidebars.js | 7 +- 14 files changed, 209 insertions(+), 4 deletions(-) create mode 100644 authentik/crypto/settings.py create mode 100644 authentik/crypto/tasks.py create mode 100644 website/docs/core/certificates.md diff --git a/authentik/crypto/api.py b/authentik/crypto/api.py index 4eb02dddc..fc62285fa 100644 --- a/authentik/crypto/api.py +++ b/authentik/crypto/api.py @@ -20,6 +20,7 @@ from authentik.api.decorators import permission_required from authentik.core.api.used_by import UsedByMixin from authentik.core.api.utils import PassiveSerializer from authentik.crypto.builder import CertificateBuilder +from authentik.crypto.managed import MANAGED_KEY from authentik.crypto.models import CertificateKeyPair from authentik.events.models import Event, EventAction @@ -141,7 +142,7 @@ class CertificateKeyPairFilter(FilterSet): class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet): """CertificateKeyPair Viewset""" - queryset = CertificateKeyPair.objects.exclude(managed__isnull=False) + queryset = CertificateKeyPair.objects.exclude(managed=MANAGED_KEY) serializer_class = CertificateKeyPairSerializer filterset_class = CertificateKeyPairFilter ordering = ["name"] diff --git a/authentik/crypto/apps.py b/authentik/crypto/apps.py index 8f84f0839..17da6d2cc 100644 --- a/authentik/crypto/apps.py +++ b/authentik/crypto/apps.py @@ -13,3 +13,4 @@ class AuthentikCryptoConfig(AppConfig): def ready(self): import_module("authentik.crypto.managed") + import_module("authentik.crypto.tasks") diff --git a/authentik/crypto/settings.py b/authentik/crypto/settings.py new file mode 100644 index 000000000..598576d48 --- /dev/null +++ b/authentik/crypto/settings.py @@ -0,0 +1,10 @@ +"""Crypto task Settings""" +from celery.schedules import crontab + +CELERY_BEAT_SCHEDULE = { + "crypto_certificate_discovery": { + "task": "authentik.crypto.tasks.certificate_discovery", + "schedule": crontab(minute="*/5"), + "options": {"queue": "authentik_scheduled"}, + }, +} diff --git a/authentik/crypto/tasks.py b/authentik/crypto/tasks.py new file mode 100644 index 000000000..06d6b02ee --- /dev/null +++ b/authentik/crypto/tasks.py @@ -0,0 +1,67 @@ +"""Crypto tasks""" +from glob import glob +from pathlib import Path + +from django.utils.translation import gettext_lazy as _ +from structlog.stdlib import get_logger + +from authentik.crypto.models import CertificateKeyPair +from authentik.events.monitored_tasks import PrefilledMonitoredTask, TaskResult, TaskResultStatus +from authentik.lib.config import CONFIG +from authentik.root.celery import CELERY_APP + +LOGGER = get_logger() + +MANAGED_DISCOVERED = "goauthentik.io/crypto/discovered/%s" + + +@CELERY_APP.task(bind=True, base=PrefilledMonitoredTask) +def certificate_discovery(self: PrefilledMonitoredTask): + """Discover and update certificates form the filesystem""" + certs = {} + private_keys = {} + discovered = 0 + for file in glob(CONFIG.y("cert_discovery_dir") + "/**", recursive=True): + path = Path(file) + if not path.exists(): + continue + if path.is_dir(): + continue + # Support certbot's directory structure + if path.name in ["fullchain.pem", "privkey.pem"]: + cert_name = path.parent.name + else: + cert_name = path.name.replace(path.suffix, "") + try: + with open(path, "r+", encoding="utf-8") as _file: + body = _file.read() + if "BEGIN RSA PRIVATE KEY" in body: + private_keys[cert_name] = body + else: + certs[cert_name] = body + except OSError as exc: + LOGGER.warning("Failed to open file", exc=exc, file=path) + discovered += 1 + for name, cert_data in certs.items(): + cert = CertificateKeyPair.objects.filter(managed=MANAGED_DISCOVERED % name).first() + if not cert: + cert = CertificateKeyPair( + name=name, + managed=MANAGED_DISCOVERED % name, + ) + dirty = False + if cert.certificate_data != cert_data: + cert.certificate_data = cert_data + dirty = True + if name in private_keys: + if cert.key_data == private_keys[name]: + cert.key_data = private_keys[name] + dirty = True + if dirty: + cert.save() + self.set_status( + TaskResult( + TaskResultStatus.SUCCESSFUL, + messages=[_("Successfully imported %(count)d files." % {"count": discovered})], + ) + ) diff --git a/authentik/crypto/tests.py b/authentik/crypto/tests.py index f621b0f0d..59a1d1094 100644 --- a/authentik/crypto/tests.py +++ b/authentik/crypto/tests.py @@ -1,5 +1,7 @@ """Crypto tests""" import datetime +from os import makedirs, mkdir +from tempfile import TemporaryDirectory from django.urls import reverse from rest_framework.test import APITestCase @@ -9,6 +11,8 @@ from authentik.core.tests.utils import create_test_admin_user, create_test_cert, from authentik.crypto.api import CertificateKeyPairSerializer from authentik.crypto.builder import CertificateBuilder from authentik.crypto.models import CertificateKeyPair +from authentik.crypto.tasks import MANAGED_DISCOVERED, certificate_discovery +from authentik.lib.config import CONFIG from authentik.lib.generators import generate_key from authentik.providers.oauth2.models import OAuth2Provider @@ -163,3 +167,32 @@ class TestCrypto(APITestCase): } ], ) + + def test_discovery(self): + """Test certificate discovery""" + builder = CertificateBuilder() + builder.common_name = "test-cert" + with self.assertRaises(ValueError): + builder.save() + builder.build( + subject_alt_names=[], + validity_days=3, + ) + with TemporaryDirectory() as temp_dir: + with open(f"{temp_dir}/foo.pem", "w+", encoding="utf-8") as _cert: + _cert.write(builder.certificate) + with open(f"{temp_dir}/foo.key", "w+", encoding="utf-8") as _key: + _key.write(builder.private_key) + makedirs(f"{temp_dir}/foo.bar", exist_ok=True) + with open(f"{temp_dir}/foo.bar/fullchain.pem", "w+", encoding="utf-8") as _cert: + _cert.write(builder.certificate) + with open(f"{temp_dir}/foo.bar/privkey.pem", "w+", encoding="utf-8") as _key: + _key.write(builder.private_key) + with CONFIG.patch("cert_discovery_dir", temp_dir): + certificate_discovery() + self.assertTrue( + CertificateKeyPair.objects.filter(managed=MANAGED_DISCOVERED % "foo").exists() + ) + self.assertTrue( + CertificateKeyPair.objects.filter(managed=MANAGED_DISCOVERED % "foo.bar").exists() + ) diff --git a/authentik/lib/default.yml b/authentik/lib/default.yml index 08b462746..28549d7dc 100644 --- a/authentik/lib/default.yml +++ b/authentik/lib/default.yml @@ -83,3 +83,4 @@ default_user_change_email: true default_user_change_username: true gdpr_compliance: true +cert_discovery_dir: /certs diff --git a/docker-compose.yml b/docker-compose.yml index 495249111..23110b672 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -55,6 +55,7 @@ services: volumes: - ./backups:/backups - ./media:/media + - ./certs:/certs - /var/run/docker.sock:/var/run/docker.sock - ./custom-templates:/templates - geoip:/geoip diff --git a/lifecycle/ak b/lifecycle/ak index d1d3f5025..accd86db8 100755 --- a/lifecycle/ak +++ b/lifecycle/ak @@ -28,7 +28,7 @@ function check_if_root { GROUP="authentik:${GROUP_NAME}" fi # Fix permissions of backups and media - chown -R authentik:authentik /media /backups + chown -R authentik:authentik /media /backups /certs chpst -u authentik:$GROUP env HOME=/authentik $1 } diff --git a/web/src/locales/en.po b/web/src/locales/en.po index 8a93dad05..ad6dff11a 100644 --- a/web/src/locales/en.po +++ b/web/src/locales/en.po @@ -2705,6 +2705,14 @@ msgstr "MFA Devices" msgid "Make sure to keep these tokens in a safe place." msgstr "Make sure to keep these tokens in a safe place." +#: src/pages/crypto/CertificateKeyPairListPage.ts +msgid "Managed by authentik" +msgstr "Managed by authentik" + +#: src/pages/crypto/CertificateKeyPairListPage.ts +msgid "Managed by authentik (Discovered)" +msgstr "Managed by authentik (Discovered)" + #: src/pages/stages/user_write/UserWriteStageForm.ts msgid "Mark newly created users as inactive." msgstr "Mark newly created users as inactive." diff --git a/web/src/locales/fr_FR.po b/web/src/locales/fr_FR.po index 8ef47c80a..da51ee1c8 100644 --- a/web/src/locales/fr_FR.po +++ b/web/src/locales/fr_FR.po @@ -2686,6 +2686,14 @@ msgstr "" msgid "Make sure to keep these tokens in a safe place." msgstr "" +#: src/pages/crypto/CertificateKeyPairListPage.ts +msgid "Managed by authentik" +msgstr "" + +#: src/pages/crypto/CertificateKeyPairListPage.ts +msgid "Managed by authentik (Discovered)" +msgstr "" + #: src/pages/stages/user_write/UserWriteStageForm.ts msgid "Mark newly created users as inactive." msgstr "Marquer les utilisateurs nouvellements créés comme inactifs." diff --git a/web/src/locales/pseudo-LOCALE.po b/web/src/locales/pseudo-LOCALE.po index d3d7b7917..0c42260db 100644 --- a/web/src/locales/pseudo-LOCALE.po +++ b/web/src/locales/pseudo-LOCALE.po @@ -2697,6 +2697,14 @@ msgstr "" msgid "Make sure to keep these tokens in a safe place." msgstr "" +#: src/pages/crypto/CertificateKeyPairListPage.ts +msgid "Managed by authentik" +msgstr "" + +#: src/pages/crypto/CertificateKeyPairListPage.ts +msgid "Managed by authentik (Discovered)" +msgstr "" + #: src/pages/stages/user_write/UserWriteStageForm.ts msgid "Mark newly created users as inactive." msgstr "" diff --git a/web/src/pages/crypto/CertificateKeyPairListPage.ts b/web/src/pages/crypto/CertificateKeyPairListPage.ts index 844626a4c..c773d30dc 100644 --- a/web/src/pages/crypto/CertificateKeyPairListPage.ts +++ b/web/src/pages/crypto/CertificateKeyPairListPage.ts @@ -91,8 +91,13 @@ export class CertificateKeyPairListPage extends TablePage { } row(item: CertificateKeyPair): TemplateResult[] { + let managedSubText = t`Managed by authentik`; + if (item.managed && item.managed.startsWith("goauthentik.io/crypto/discovered")) { + managedSubText = t`Managed by authentik (Discovered)`; + } return [ - html`${item.name}`, + html`
${item.name}
+ ${item.managed ? html`${managedSubText}` : html``}`, html` ${item.privateKeyAvailable ? t`Yes` : t`No`} `, diff --git a/website/docs/core/certificates.md b/website/docs/core/certificates.md new file mode 100644 index 000000000..41b828d6b --- /dev/null +++ b/website/docs/core/certificates.md @@ -0,0 +1,57 @@ +--- +title: Certificates +--- + +Certificates in authentik are used for the following use cases: + +- Signing and verifying SAML Requests and Responses +- Signing JSON Web Tokens for OAuth and OIDC +- Connecting to remote docker hosts using the Docker integration +- Verifying LDAP Servers' certificates +- Encrypting outposts's endpoints + +## Default certificate + +Every authentik install generates a self-signed certificate on the first start. The certificate is called *authentik Self-signed Certificate* and is valid for 1 year. + +This certificate is generated to be used as a default for all OAuth2/OIDC providers, as these don't require the certificate to be configured on both sides (the signature of a JWT is validated using the [JWKS](https://auth0.com/docs/security/tokens/json-web-tokens/json-web-key-sets) URL). + +This certificate can also be used for SAML Providers/Sources, just keep in mind that the certificate is only valid for a year. Some SAML applications require the certificate to be valid, so they might need to be rotated regularly. + +For SAML use-cases, you can generate a Certificate thats valid for longer than 1 year, on your own risk. + +## External certificates + +To use externally managed certificates, for example generated with certbot or HashiCorp Vault, you can use the discovery feature. + +The docker-compose installation maps a `certs` directory to `/certs`, you can simply use this as an output directory for certbot. + +For Kubernetes, you can map custom secrets/volumes under `/certs`. + +You can also bind mount single files into the folder, as long as they fall under this naming schema. + +- Files in the root directory will be imported based on their filename. + + `/foo.pem` Will be imported as the keypair `foo`. Based on its content its either imported as certificate or private key. + + Currently, only RSA Keys are supported, so if the file contains `BEGIN RSA PRIVATE KEY` it will imported as private key. + + Otherwise it will be imported as certificate. + +- If the file is called `fullchain.pem` or `privkey.pem` (the output naming of certbot), they will get the name of the parent folder. +- Files can be in any arbitrary file structure, and can have extension. + +``` +certs/ +├── baz +│   └── bar.baz +│   ├── fullchain.pem +│   └── privkey.key +├── foo.bar +│   ├── fullchain.pem +│   └── privkey.key +├── foo.key +└── foo.pem +``` + +Files are checked every 5 minutes, and will trigger an Outpost refresh if the files differ. diff --git a/website/sidebars.js b/website/sidebars.js index 1fe80b9d7..7d6b9fd0d 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -22,7 +22,12 @@ module.exports = { type: "category", label: "Core Concepts", collapsed: false, - items: ["core/terminology", "core/applications", "core/tenants"], + items: [ + "core/terminology", + "core/applications", + "core/tenants", + "core/certificates", + ], }, { type: "category", From 8ddb62ed0f981ffba0b78f71b9f2d9d872966dc0 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Fri, 3 Dec 2021 18:37:40 +0100 Subject: [PATCH 43/46] sources/plex: fix plex token being included in event log Signed-off-by: Jens Langhammer --- authentik/sources/plex/tasks.py | 5 +++-- website/docs/core/certificates.md | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/authentik/sources/plex/tasks.py b/authentik/sources/plex/tasks.py index fa86f29e1..59fc4594e 100644 --- a/authentik/sources/plex/tasks.py +++ b/authentik/sources/plex/tasks.py @@ -29,14 +29,15 @@ def check_plex_token(self: MonitoredTask, source_slug: int): auth.get_user_info() self.set_status(TaskResult(TaskResultStatus.SUCCESSFUL, ["Plex token is valid."])) except RequestException as exc: + error = exception_to_string(exc).replace(source.plex_token, "$PLEX_TOKEN") self.set_status( TaskResult( TaskResultStatus.ERROR, - ["Plex token is invalid/an error occurred:", exception_to_string(exc)], + ["Plex token is invalid/an error occurred:", error], ) ) Event.new( EventAction.CONFIGURATION_ERROR, - message=f"Plex token invalid, please re-authenticate source.\n{str(exc)}", + message=f"Plex token invalid, please re-authenticate source.\n{error}", source=source, ).save() diff --git a/website/docs/core/certificates.md b/website/docs/core/certificates.md index 41b828d6b..c8c87024c 100644 --- a/website/docs/core/certificates.md +++ b/website/docs/core/certificates.md @@ -18,7 +18,7 @@ This certificate is generated to be used as a default for all OAuth2/OIDC provid This certificate can also be used for SAML Providers/Sources, just keep in mind that the certificate is only valid for a year. Some SAML applications require the certificate to be valid, so they might need to be rotated regularly. -For SAML use-cases, you can generate a Certificate thats valid for longer than 1 year, on your own risk. +For SAML use-cases, you can generate a Certificate that's valid for longer than 1 year, on your own risk. ## External certificates From 426cef998fc5cebbfbec3adfa71f84840cd860d4 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Fri, 3 Dec 2021 18:39:42 +0100 Subject: [PATCH 44/46] sources/ldap: make task names more consistent Signed-off-by: Jens Langhammer --- authentik/crypto/tests.py | 5 +++-- authentik/sources/ldap/tasks.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/authentik/crypto/tests.py b/authentik/crypto/tests.py index 59a1d1094..112083698 100644 --- a/authentik/crypto/tests.py +++ b/authentik/crypto/tests.py @@ -1,6 +1,6 @@ """Crypto tests""" import datetime -from os import makedirs, mkdir +from os import makedirs from tempfile import TemporaryDirectory from django.urls import reverse @@ -189,7 +189,8 @@ class TestCrypto(APITestCase): with open(f"{temp_dir}/foo.bar/privkey.pem", "w+", encoding="utf-8") as _key: _key.write(builder.private_key) with CONFIG.patch("cert_discovery_dir", temp_dir): - certificate_discovery() + # pyright: reportGeneralTypeIssues=false + certificate_discovery() # pylint: disable=no-value-for-parameter self.assertTrue( CertificateKeyPair.objects.filter(managed=MANAGED_DISCOVERED % "foo").exists() ) diff --git a/authentik/sources/ldap/tasks.py b/authentik/sources/ldap/tasks.py index b431c4a98..d83786e2f 100644 --- a/authentik/sources/ldap/tasks.py +++ b/authentik/sources/ldap/tasks.py @@ -39,7 +39,7 @@ def ldap_sync(self: MonitoredTask, source_pk: str, sync_class: str): # to set the state with return sync = path_to_class(sync_class) - self.set_uid(f"{slugify(source.name)}-{sync.__name__}") + self.set_uid(f"{slugify(source.name)}_{sync.__name__.replace('LDAPSynchronizer', '').lower()}") try: sync_inst = sync(source) count = sync_inst.sync() From 3f2ce3446845bbcfe6efed21309d30c7c3aef010 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Fri, 3 Dec 2021 18:54:04 +0100 Subject: [PATCH 45/46] web: update icons Signed-off-by: Jens Langhammer --- web/icons/icon_centeed.png | Bin 18918 -> 0 bytes web/icons/icon_christmas.png | Bin 153509 -> 0 bytes web/icons/icon_discord.png | Bin 0 -> 9364 bytes web/icons/icon_discord_christmas.png | Bin 0 -> 11728 bytes 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 web/icons/icon_centeed.png delete mode 100644 web/icons/icon_christmas.png create mode 100644 web/icons/icon_discord.png create mode 100644 web/icons/icon_discord_christmas.png diff --git a/web/icons/icon_centeed.png b/web/icons/icon_centeed.png deleted file mode 100644 index 37c2662e90241bb8ca180bdf9ac5577a23a31b3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18918 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 bT>d#bHF@W4JUp$0|A^@~n|-+!#B2Wxl_eH5 diff --git a/web/icons/icon_christmas.png b/web/icons/icon_christmas.png deleted file mode 100644 index 089040dc70765acf899681a4eb0eefc8be6cf4ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 153509 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%0Dn2 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 z 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 diff --git a/web/icons/icon_discord.png b/web/icons/icon_discord.png new file mode 100644 index 0000000000000000000000000000000000000000..d2a58af6a52fc8e4853a98a194132dffa033df80 GIT binary patch literal 9364 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 Ny0W%Xu7c%X{|5n0`P~2j literal 0 HcmV?d00001 diff --git a/web/icons/icon_discord_christmas.png b/web/icons/icon_discord_christmas.png new file mode 100644 index 0000000000000000000000000000000000000000..a43a8280c5636fcb159450ae9e0508f5c7717e34 GIT binary patch literal 11728 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 Ksn-&Q{{IJ_y@iqh literal 0 HcmV?d00001 From e44632f9a0c8365db92b9a10a4e377b0f4f9b281 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sat, 4 Dec 2021 19:54:58 +0100 Subject: [PATCH 46/46] web/admin: fix wrong description for reputation policy closes #1877 Signed-off-by: Jens Langhammer --- web/src/locales/en.po | 26 ++++++++++++++++--- web/src/locales/fr_FR.po | 19 +++++++++++--- web/src/locales/pseudo-LOCALE.po | 17 ++++++++++-- .../reputation/ReputationPolicyForm.ts | 8 ++++-- 4 files changed, 59 insertions(+), 11 deletions(-) diff --git a/web/src/locales/en.po b/web/src/locales/en.po index ad6dff11a..f76436c1d 100644 --- a/web/src/locales/en.po +++ b/web/src/locales/en.po @@ -2387,6 +2387,14 @@ msgstr "Internal host" msgid "Internal host SSL Validation" msgstr "Internal host SSL Validation" +#: src/pages/policies/reputation/ReputationPolicyForm.ts +msgid "" +"Invalid login attempts will decrease the score for the client's IP, and the\n" +"username they are attempting to login as, by one." +msgstr "" +"Invalid login attempts will decrease the score for the client's IP, and the\n" +"username they are attempting to login as, by one." + #: src/pages/flows/StageBindingForm.ts msgid "Invalid response action" msgstr "Invalid response action" @@ -4844,14 +4852,24 @@ msgstr "The external URL you'll authenticate at. Can be the same domain as authe msgid "The following objects use {objName}" msgstr "The following objects use {objName}" +#: src/pages/policies/reputation/ReputationPolicyForm.ts +#~ msgid "" +#~ "The policy passes when the reputation score is above the threshold, and\n" +#~ "doesn't pass when either or both of the selected options are equal or less than the\n" +#~ "threshold." +#~ msgstr "" +#~ "The policy passes when the reputation score is above the threshold, and\n" +#~ "doesn't pass when either or both of the selected options are equal or less than the\n" +#~ "threshold." + #: src/pages/policies/reputation/ReputationPolicyForm.ts msgid "" -"The policy passes when the reputation score is above the threshold, and\n" -"doesn't pass when either or both of the selected options are equal or less than the\n" +"The policy passes when the reputation score is below the threshold, and\n" +"doesn't pass when either or both of the selected options are equal or above the\n" "threshold." msgstr "" -"The policy passes when the reputation score is above the threshold, and\n" -"doesn't pass when either or both of the selected options are equal or less than the\n" +"The policy passes when the reputation score is below the threshold, and\n" +"doesn't pass when either or both of the selected options are equal or above the\n" "threshold." #: src/pages/policies/dummy/DummyPolicyForm.ts diff --git a/web/src/locales/fr_FR.po b/web/src/locales/fr_FR.po index da51ee1c8..caccfeeab 100644 --- a/web/src/locales/fr_FR.po +++ b/web/src/locales/fr_FR.po @@ -2370,6 +2370,12 @@ msgstr "Hôte interne" msgid "Internal host SSL Validation" msgstr "Validation SSL de l'hôte interne" +#: src/pages/policies/reputation/ReputationPolicyForm.ts +msgid "" +"Invalid login attempts will decrease the score for the client's IP, and the\n" +"username they are attempting to login as, by one." +msgstr "" + #: src/pages/flows/StageBindingForm.ts msgid "Invalid response action" msgstr "Action de réponse invalide" @@ -4799,12 +4805,19 @@ msgstr "L'URL externe sur laquelle vous vous authentifierez. Cela peut être le msgid "The following objects use {objName}" msgstr "Les objets suivants utilisent {objName}" +#: src/pages/policies/reputation/ReputationPolicyForm.ts +#~ msgid "" +#~ "The policy passes when the reputation score is above the threshold, and\n" +#~ "doesn't pass when either or both of the selected options are equal or less than the\n" +#~ "threshold." +#~ msgstr "La politique est réussie si la note de réputation est au-dessus du seuil, et échoue si au moins l'une des options sélectionnées sont inférieures ou égales au seuil." + #: src/pages/policies/reputation/ReputationPolicyForm.ts msgid "" -"The policy passes when the reputation score is above the threshold, and\n" -"doesn't pass when either or both of the selected options are equal or less than the\n" +"The policy passes when the reputation score is below the threshold, and\n" +"doesn't pass when either or both of the selected options are equal or above the\n" "threshold." -msgstr "La politique est réussie si la note de réputation est au-dessus du seuil, et échoue si au moins l'une des options sélectionnées sont inférieures ou égales au seuil." +msgstr "" #: src/pages/policies/dummy/DummyPolicyForm.ts msgid "The policy takes a random time to execute. This controls the minimum time it will take." diff --git a/web/src/locales/pseudo-LOCALE.po b/web/src/locales/pseudo-LOCALE.po index 0c42260db..20cb14f2f 100644 --- a/web/src/locales/pseudo-LOCALE.po +++ b/web/src/locales/pseudo-LOCALE.po @@ -2379,6 +2379,12 @@ msgstr "" msgid "Internal host SSL Validation" msgstr "" +#: src/pages/policies/reputation/ReputationPolicyForm.ts +msgid "" +"Invalid login attempts will decrease the score for the client's IP, and the\n" +"username they are attempting to login as, by one." +msgstr "" + #: src/pages/flows/StageBindingForm.ts msgid "Invalid response action" msgstr "" @@ -4836,10 +4842,17 @@ msgstr "" msgid "The following objects use {objName}" msgstr "" +#: src/pages/policies/reputation/ReputationPolicyForm.ts +#~ msgid "" +#~ "The policy passes when the reputation score is above the threshold, and\n" +#~ "doesn't pass when either or both of the selected options are equal or less than the\n" +#~ "threshold." +#~ msgstr "" + #: src/pages/policies/reputation/ReputationPolicyForm.ts msgid "" -"The policy passes when the reputation score is above the threshold, and\n" -"doesn't pass when either or both of the selected options are equal or less than the\n" +"The policy passes when the reputation score is below the threshold, and\n" +"doesn't pass when either or both of the selected options are equal or above the\n" "threshold." msgstr "" diff --git a/web/src/pages/policies/reputation/ReputationPolicyForm.ts b/web/src/pages/policies/reputation/ReputationPolicyForm.ts index e48904039..a4f4fd126 100644 --- a/web/src/pages/policies/reputation/ReputationPolicyForm.ts +++ b/web/src/pages/policies/reputation/ReputationPolicyForm.ts @@ -47,8 +47,12 @@ export class ReputationPolicyForm extends ModelForm { ${t`Allows/denys requests based on the users and/or the IPs reputation.`}
- ${t`The policy passes when the reputation score is above the threshold, and - doesn't pass when either or both of the selected options are equal or less than the + ${t`Invalid login attempts will decrease the score for the client's IP, and the + username they are attempting to login as, by one.`} +
+
+ ${t`The policy passes when the reputation score is below the threshold, and + doesn't pass when either or both of the selected options are equal or above the threshold.`}