diff --git a/.vscode/settings.json b/.vscode/settings.json index eac30921c..aaf7de88b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,15 +20,20 @@ "todo-tree.tree.showCountsInTree": true, "todo-tree.tree.showBadges": true, "python.formatting.provider": "black", - "yaml.customTags": [ - "!Find sequence", - "!KeyOf scalar" - ], + "yaml.customTags": ["!Find sequence", "!KeyOf scalar"], "typescript.preferences.importModuleSpecifier": "non-relative", "typescript.preferences.importModuleSpecifierEnding": "index", "typescript.tsdk": "./web/node_modules/typescript/lib", "typescript.enablePromptUseWorkspaceTsdk": true, "yaml.schemas": { "./blueprints/schema.json": "blueprints/**/*.yaml" - } + }, + "gitlens.autolinks": [ + { + "alphanumeric": true, + "prefix": "#", + "url": "https://github.com/goauthentik/authentik/issues/", + "ignoreCase": false + } + ] } diff --git a/authentik/events/models.py b/authentik/events/models.py index f067a7ba2..9977c3381 100644 --- a/authentik/events/models.py +++ b/authentik/events/models.py @@ -1,6 +1,7 @@ """authentik events models""" import time from collections import Counter +from copy import deepcopy from datetime import timedelta from inspect import currentframe from smtplib import SMTPException @@ -210,7 +211,7 @@ class Event(SerializerModel, ExpiringModel): current = currentframe() parent = current.f_back app = parent.f_globals["__name__"] - cleaned_kwargs = cleanse_dict(sanitize_dict(kwargs)) + cleaned_kwargs = cleanse_dict(sanitize_dict(deepcopy(kwargs))) event = Event(action=action, app=app, context=cleaned_kwargs) return event diff --git a/authentik/policies/expression/tests.py b/authentik/policies/expression/tests.py index fac8338d0..b94df250d 100644 --- a/authentik/policies/expression/tests.py +++ b/authentik/policies/expression/tests.py @@ -1,13 +1,17 @@ """evaluator tests""" -from django.test import TestCase +from django.test import RequestFactory, TestCase from guardian.shortcuts import get_anonymous_user from rest_framework.serializers import ValidationError from rest_framework.test import APITestCase +from authentik.core.models import Application +from authentik.lib.generators import generate_id from authentik.policies.exceptions import PolicyException from authentik.policies.expression.api import ExpressionPolicySerializer from authentik.policies.expression.evaluator import PolicyEvaluator from authentik.policies.expression.models import ExpressionPolicy +from authentik.policies.models import PolicyBinding +from authentik.policies.process import PolicyProcess from authentik.policies.types import PolicyRequest @@ -15,7 +19,15 @@ class TestEvaluator(TestCase): """Evaluator tests""" def setUp(self): + factory = RequestFactory() + self.http_request = factory.get("/") + self.obj = Application.objects.create( + name=generate_id(), + slug=generate_id(), + ) self.request = PolicyRequest(user=get_anonymous_user()) + self.request.obj = self.obj + self.request.http_request = self.http_request def test_full(self): """Test full with Policy instance""" @@ -63,6 +75,41 @@ class TestEvaluator(TestCase): with self.assertRaises(ValidationError): evaluator.validate(template) + def test_execution_logging(self): + """test execution_logging""" + expr = ExpressionPolicy.objects.create( + name=generate_id(), + execution_logging=True, + expression="ak_message(request.http_request.path)\nreturn True", + ) + evaluator = PolicyEvaluator("test") + evaluator.set_policy_request(self.request) + proc = PolicyProcess(PolicyBinding(policy=expr), request=self.request, connection=None) + res = proc.profiling_wrapper() + self.assertEqual(res.messages, ("/",)) + + def test_call_policy(self): + """test ak_call_policy""" + expr = ExpressionPolicy.objects.create( + name=generate_id(), + execution_logging=True, + expression="ak_message(request.http_request.path)\nreturn True", + ) + tmpl = ( + """ + ak_message(request.http_request.path) + res = ak_call_policy('%s') + ak_message(request.http_request.path) + for msg in res.messages: + ak_message(msg) + """ + % expr.name + ) + evaluator = PolicyEvaluator("test") + evaluator.set_policy_request(self.request) + res = evaluator.evaluate(tmpl) + self.assertEqual(res.messages, ("/", "/", "/")) + class TestExpressionPolicyAPI(APITestCase): """Test expression policy's API""" diff --git a/authentik/policies/process.py b/authentik/policies/process.py index 296c5bc9e..c28ff50bf 100644 --- a/authentik/policies/process.py +++ b/authentik/policies/process.py @@ -56,8 +56,6 @@ class PolicyProcess(PROCESS_CLASS): def create_event(self, action: str, message: str, **kwargs): """Create event with common values from `self.request` and `self.binding`.""" - # Keep a reference to http_request even if its None, because cleanse_dict will remove it - http_request = self.request.http_request event = Event.new( action=action, message=message, @@ -67,8 +65,8 @@ class PolicyProcess(PROCESS_CLASS): **kwargs, ) event.set_user(self.request.user) - if http_request: - event.from_http(http_request) + if self.request.http_request: + event.from_http(self.request.http_request) else: event.save()