core: fix PropertyMapping's globals not matching Expression policy

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-06-21 15:54:43 +02:00
parent 70ccc63702
commit 831b32c279
5 changed files with 31 additions and 22 deletions

View File

@ -3,23 +3,33 @@ from traceback import format_tb
from typing import Optional
from django.http import HttpRequest
from guardian.utils import get_anonymous_user
from authentik.core.models import User
from authentik.core.models import PropertyMapping, User
from authentik.events.models import Event, EventAction
from authentik.lib.expression.evaluator import BaseEvaluator
from authentik.policies.types import PolicyRequest
class PropertyMappingEvaluator(BaseEvaluator):
"""Custom Evalautor that adds some different context variables."""
def set_context(
self, user: Optional[User], request: Optional[HttpRequest], **kwargs
self,
user: Optional[User],
request: Optional[HttpRequest],
mapping: PropertyMapping,
**kwargs,
):
"""Update context with context from PropertyMapping's evaluate"""
req = PolicyRequest(user=get_anonymous_user())
req.obj = mapping
if user:
req.user = user
self._context["user"] = user
if request:
self._context["request"] = request
req.http_request = request
self._context["request"] = req
self._context.update(**kwargs)
def handle_error(self, exc: Exception, expression_source: str):
@ -30,9 +40,8 @@ class PropertyMappingEvaluator(BaseEvaluator):
expression=expression_source,
message=error_string,
)
if "user" in self._context:
event.set_user(self._context["user"])
if "request" in self._context:
event.from_http(self._context["request"])
req: PolicyRequest = self._context["request"]
event.from_http(req.http_request, req.user)
return
event.save()

View File

@ -461,7 +461,7 @@ class PropertyMapping(SerializerModel, ManagedModel):
from authentik.core.expression import PropertyMappingEvaluator
evaluator = PropertyMappingEvaluator()
evaluator.set_context(user, request, **kwargs)
evaluator.set_context(user, request, self, **kwargs)
try:
return evaluator.evaluate(self.expression)
except (ValueError, SyntaxError) as exc:

View File

@ -9,7 +9,7 @@ return {}
"""
SCOPE_EMAIL_EXPRESSION = """
return {
"email": user.email,
"email": request.user.email,
"email_verified": True
}
"""
@ -17,14 +17,14 @@ SCOPE_PROFILE_EXPRESSION = """
return {
# Because authentik only saves the user's full name, and has no concept of first and last names,
# the full name is used as given name.
# You can override this behaviour in custom mappings, i.e. `user.name.split(" ")`
"name": user.name,
"given_name": user.name,
# You can override this behaviour in custom mappings, i.e. `request.user.name.split(" ")`
"name": request.user.name,
"given_name": request.user.name,
"family_name": "",
"preferred_username": user.username,
"nickname": user.username,
"preferred_username": request.user.username,
"nickname": request.user.username,
# groups is not part of the official userinfo schema, but is a quasi-standard
"groups": [group.name for group in user.ak_groups.all()],
"groups": [group.name for group in request.user.ak_groups.all()],
}
"""

View File

@ -8,7 +8,7 @@ SCOPE_AK_PROXY_EXPRESSION = """
# which are used for example for the HTTP-Basic Authentication mapping.
return {
"ak_proxy": {
"user_attributes": user.group_attributes()
"user_attributes": request.user.group_attributes()
}
}"""

View File

@ -3,7 +3,7 @@ from authentik.managed.manager import EnsureExists, ObjectManager
from authentik.providers.saml.models import SAMLPropertyMapping
GROUP_EXPRESSION = """
for group in user.ak_groups.all():
for group in request.user.ak_groups.all():
yield group.name
"""
@ -18,7 +18,7 @@ class SAMLProviderManager(ObjectManager):
"goauthentik.io/providers/saml/upn",
name="authentik default SAML Mapping: UPN",
saml_name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn",
expression="return user.attributes.get('upn', user.email)",
expression="return request.user.attributes.get('upn', request.user.email)",
friendly_name="",
),
EnsureExists(
@ -26,7 +26,7 @@ class SAMLProviderManager(ObjectManager):
"goauthentik.io/providers/saml/name",
name="authentik default SAML Mapping: Name",
saml_name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
expression="return user.name",
expression="return request.user.name",
friendly_name="",
),
EnsureExists(
@ -34,7 +34,7 @@ class SAMLProviderManager(ObjectManager):
"goauthentik.io/providers/saml/email",
name="authentik default SAML Mapping: Email",
saml_name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
expression="return user.email",
expression="return request.user.email",
friendly_name="",
),
EnsureExists(
@ -42,7 +42,7 @@ class SAMLProviderManager(ObjectManager):
"goauthentik.io/providers/saml/username",
name="authentik default SAML Mapping: Username",
saml_name="http://schemas.goauthentik.io/2021/02/saml/username",
expression="return user.username",
expression="return request.user.username",
friendly_name="",
),
EnsureExists(
@ -50,7 +50,7 @@ class SAMLProviderManager(ObjectManager):
"goauthentik.io/providers/saml/uid",
name="authentik default SAML Mapping: User ID",
saml_name="http://schemas.goauthentik.io/2021/02/saml/uid",
expression="return user.pk",
expression="return request.user.pk",
friendly_name="",
),
EnsureExists(
@ -68,7 +68,7 @@ class SAMLProviderManager(ObjectManager):
saml_name=(
"http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"
),
expression="return user.username",
expression="return request.user.username",
friendly_name="",
),
]