From 0b8678f7eeabfe73f90148c151b6da8e568fff83 Mon Sep 17 00:00:00 2001 From: Jens L Date: Thu, 8 Feb 2024 22:48:55 +0100 Subject: [PATCH] core: use correct .evaluate implementation for testing PropertyMappings (#8459) * core: use correct .evaluate implementation for testing PropertyMappings Signed-off-by: Jens Langhammer * only dispatch refresh if modal is allowed to close Signed-off-by: Jens Langhammer * sigh...bump max allowed node memory Signed-off-by: Jens Langhammer --------- Signed-off-by: Jens Langhammer --- authentik/core/api/propertymappings.py | 6 +++++- authentik/enterprise/providers/rac/models.py | 14 +++++++++----- web/package.json | 8 ++++---- .../property-mappings/PropertyMappingTestForm.ts | 10 ++++++---- web/src/elements/forms/ModalForm.ts | 12 ++++++------ 5 files changed, 30 insertions(+), 20 deletions(-) diff --git a/authentik/core/api/propertymappings.py b/authentik/core/api/propertymappings.py index 8382e0ac02..55f6b3f704 100644 --- a/authentik/core/api/propertymappings.py +++ b/authentik/core/api/propertymappings.py @@ -118,7 +118,11 @@ class PropertyMappingViewSet( @action(detail=True, pagination_class=None, filter_backends=[], methods=["POST"]) def test(self, request: Request, pk: str) -> Response: """Test Property Mapping""" - mapping: PropertyMapping = self.get_object() + _mapping: PropertyMapping = self.get_object() + # Use `get_subclass` to get correct class and correct `.evaluate` implementation + mapping = PropertyMapping.objects.get_subclass(pk=_mapping.pk) + # FIXME: when we separate policy mappings between ones for sources + # and ones for providers, we need to make the user field optional for the source mapping test_params = PolicyTestSerializer(data=request.data) if not test_params.is_valid(): return Response(test_params.errors, status=400) diff --git a/authentik/enterprise/providers/rac/models.py b/authentik/enterprise/providers/rac/models.py index d1645efc5a..d354617739 100644 --- a/authentik/enterprise/providers/rac/models.py +++ b/authentik/enterprise/providers/rac/models.py @@ -1,17 +1,18 @@ """RAC Models""" -from typing import Optional +from typing import Any, Optional from uuid import uuid4 from deepmerge import always_merger from django.db import models from django.db.models import QuerySet +from django.http import HttpRequest from django.utils.translation import gettext as _ from rest_framework.serializers import Serializer from structlog.stdlib import get_logger from authentik.core.exceptions import PropertyMappingExpressionException -from authentik.core.models import ExpiringModel, PropertyMapping, Provider, default_token_key +from authentik.core.models import ExpiringModel, PropertyMapping, Provider, User, default_token_key from authentik.events.models import Event, EventAction from authentik.lib.models import SerializerModel from authentik.lib.utils.time import timedelta_string_validator @@ -107,6 +108,12 @@ class RACPropertyMapping(PropertyMapping): static_settings = models.JSONField(default=dict) + def evaluate(self, user: Optional[User], request: Optional[HttpRequest], **kwargs) -> Any: + """Evaluate `self.expression` using `**kwargs` as Context.""" + if len(self.static_settings) > 0: + return self.static_settings + return super().evaluate(user, request, **kwargs) + @property def component(self) -> str: return "ak-property-mapping-rac-form" @@ -155,9 +162,6 @@ class ConnectionToken(ExpiringModel): def mapping_evaluator(mappings: QuerySet): for mapping in mappings: mapping: RACPropertyMapping - if len(mapping.static_settings) > 0: - always_merger.merge(settings, mapping.static_settings) - continue try: mapping_settings = mapping.evaluate( self.session.user, None, endpoint=self.endpoint, provider=self.provider diff --git a/web/package.json b/web/package.json index 7326b73e64..92c7b2d1fd 100644 --- a/web/package.json +++ b/web/package.json @@ -8,9 +8,9 @@ "build-locales": "run-s build-locales:build", "build-locales:build": "lit-localize build", "build-locales:repair": "prettier --write ./src/locale-codes.ts", - "rollup:build": "cross-env NODE_OPTIONS='--max_old_space_size=4096' rollup -c ./rollup.config.mjs", - "rollup:build-proxy": "cross-env NODE_OPTIONS='--max_old_space_size=4096' rollup -c ./rollup.proxy.mjs", - "rollup:watch": "cross-env NODE_OPTIONS='--max_old_space_size=4096' rollup -c -w", + "rollup:build": "cross-env NODE_OPTIONS='--max_old_space_size=8192' rollup -c ./rollup.config.mjs", + "rollup:build-proxy": "cross-env NODE_OPTIONS='--max_old_space_size=8192' rollup -c ./rollup.proxy.mjs", + "rollup:watch": "cross-env NODE_OPTIONS='--max_old_space_size=8192' rollup -c -w", "build": "run-s build-locales rollup:build", "build-proxy": "run-s build-locales rollup:build-proxy", "watch": "run-s build-locales rollup:watch", @@ -28,7 +28,7 @@ "tsc:execute": "tsc --noEmit -p .", "tsc": "run-s build-locales tsc:execute", "storybook": "storybook dev -p 6006", - "storybook:build": "cross-env NODE_OPTIONS='--max_old_space_size=4096' storybook build", + "storybook:build": "cross-env NODE_OPTIONS='--max_old_space_size=8192' storybook build", "storybook:build-import-map": "run-s storybook:build-import-map-script storybook:run-import-map-script", "storybook:build-import-map-script": "cd scripts && tsc --esModuleInterop --module es2020 --target es2020 --moduleResolution 'node' build-storybook-import-maps.ts && mv build-storybook-import-maps.js build-storybook-import-maps.mjs", "storybook:run-import-map-script": "node scripts/build-storybook-import-maps.mjs" diff --git a/web/src/admin/property-mappings/PropertyMappingTestForm.ts b/web/src/admin/property-mappings/PropertyMappingTestForm.ts index e81af9a0c8..e3e010ef73 100644 --- a/web/src/admin/property-mappings/PropertyMappingTestForm.ts +++ b/web/src/admin/property-mappings/PropertyMappingTestForm.ts @@ -84,12 +84,14 @@ export class PolicyTestForm extends Form { user: this.request?.user || 0, context: { ldap: { - name: "test-user", - objectSid: "S-1-5-21-2611707862-2219215769-354220275-1137", - objectClass: "person", displayName: "authentik test user", - sAMAccountName: "sAMAccountName", distinguishedName: "cn=user,ou=users,dc=goauthentik,dc=io", + givenName: "test", + name: "test-user", + objectClass: "person", + objectSid: "S-1-5-21-2611707862-2219215769-354220275-1137", + sAMAccountName: "sAMAccountName", + sn: "user", }, }, }; diff --git a/web/src/elements/forms/ModalForm.ts b/web/src/elements/forms/ModalForm.ts index 1930b7d752..6f058ce33d 100644 --- a/web/src/elements/forms/ModalForm.ts +++ b/web/src/elements/forms/ModalForm.ts @@ -36,15 +36,15 @@ export class ModalForm extends ModalButton { if (this.closeAfterSuccessfulSubmit) { this.open = false; form?.resetForm(); + this.dispatchEvent( + new CustomEvent(EVENT_REFRESH, { + bubbles: true, + composed: true, + }), + ); } this.loading = false; this.locked = false; - this.dispatchEvent( - new CustomEvent(EVENT_REFRESH, { - bubbles: true, - composed: true, - }), - ); }) .catch((exc) => { this.loading = false;