move more

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens Langhammer
2025-05-10 17:11:01 +02:00
parent ca0a4cb34f
commit e28968c896
11 changed files with 91 additions and 89 deletions

View File

@ -62,6 +62,7 @@ from authentik.core.api.utils import (
ModelSerializer, ModelSerializer,
PassiveSerializer, PassiveSerializer,
) )
from authentik.core.avatars import get_avatar
from authentik.core.middleware import ( from authentik.core.middleware import (
SESSION_KEY_IMPERSONATE_ORIGINAL_USER, SESSION_KEY_IMPERSONATE_ORIGINAL_USER,
SESSION_KEY_IMPERSONATE_USER, SESSION_KEY_IMPERSONATE_USER,
@ -81,7 +82,6 @@ from authentik.flows.exceptions import FlowNonApplicableException
from authentik.flows.models import FlowToken from authentik.flows.models import FlowToken
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlanner from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlanner
from authentik.flows.views.executor import QS_KEY_TOKEN from authentik.flows.views.executor import QS_KEY_TOKEN
from authentik.lib.avatars import get_avatar
from authentik.rbac.decorators import permission_required from authentik.rbac.decorators import permission_required
from authentik.rbac.models import get_permission_choices from authentik.rbac.models import get_permission_choices
from authentik.stages.email.models import EmailStage from authentik.stages.email.models import EmailStage

View File

@ -27,10 +27,10 @@ from structlog.stdlib import get_logger
from authentik.blueprints.models import ManagedModel from authentik.blueprints.models import ManagedModel
from authentik.common.expression.exceptions import ControlFlowException from authentik.common.expression.exceptions import ControlFlowException
from authentik.core.avatars import get_avatar
from authentik.core.expression.exceptions import PropertyMappingExpressionException from authentik.core.expression.exceptions import PropertyMappingExpressionException
from authentik.core.types import UILoginButton, UserSettingSerializer from authentik.core.types import UILoginButton, UserSettingSerializer
from authentik.crypto.generators import generate_id from authentik.crypto.generators import generate_id
from authentik.lib.avatars import get_avatar
from authentik.lib.merge import MERGE_LIST_UNIQUE from authentik.lib.merge import MERGE_LIST_UNIQUE
from authentik.lib.models import ( from authentik.lib.models import (
CreatedUpdatedModel, CreatedUpdatedModel,

View File

@ -14,6 +14,7 @@ from rest_framework.request import Request
from sentry_sdk import start_span from sentry_sdk import start_span
from structlog.stdlib import BoundLogger, get_logger from structlog.stdlib import BoundLogger, get_logger
from authentik.core.avatars import DEFAULT_AVATAR, get_avatar
from authentik.core.models import Application, User from authentik.core.models import Application, User
from authentik.flows.challenge import ( from authentik.flows.challenge import (
AccessDeniedChallenge, AccessDeniedChallenge,
@ -28,7 +29,6 @@ from authentik.flows.challenge import (
from authentik.flows.exceptions import StageInvalidException from authentik.flows.exceptions import StageInvalidException
from authentik.flows.models import InvalidResponseAction from authentik.flows.models import InvalidResponseAction
from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, PLAN_CONTEXT_PENDING_USER from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, PLAN_CONTEXT_PENDING_USER
from authentik.lib.avatars import DEFAULT_AVATAR, get_avatar
from authentik.lib.utils.reflection import class_to_path from authentik.lib.utils.reflection import class_to_path
if TYPE_CHECKING: if TYPE_CHECKING:

View File

@ -1,82 +0,0 @@
"""Test HTTP Helpers"""
from django.test import RequestFactory, TestCase
from authentik.core.models import Token, TokenIntents, UserTypes
from authentik.core.tests.utils import create_test_admin_user
from authentik.lib.views import bad_request_message
from authentik.root.middleware import ClientIPMiddleware
class TestHTTP(TestCase):
"""Test HTTP Helpers"""
def setUp(self) -> None:
self.user = create_test_admin_user()
self.factory = RequestFactory()
def test_bad_request_message(self):
"""test bad_request_message"""
request = self.factory.get("/")
self.assertEqual(bad_request_message(request, "foo").status_code, 400)
def test_normal(self):
"""Test normal request"""
request = self.factory.get("/")
self.assertEqual(ClientIPMiddleware.get_client_ip(request), "127.0.0.1")
def test_forward_for(self):
"""Test x-forwarded-for request"""
request = self.factory.get("/", HTTP_X_FORWARDED_FOR="127.0.0.2")
self.assertEqual(ClientIPMiddleware.get_client_ip(request), "127.0.0.2")
def test_forward_for_invalid(self):
"""Test invalid forward for"""
request = self.factory.get("/", HTTP_X_FORWARDED_FOR="foobar")
self.assertEqual(ClientIPMiddleware.get_client_ip(request), ClientIPMiddleware.default_ip)
def test_fake_outpost(self):
"""Test faked IP which is overridden by an outpost"""
token = Token.objects.create(
identifier="test", user=self.user, intent=TokenIntents.INTENT_API
)
# Invalid, non-existent token
request = self.factory.get(
"/",
**{
ClientIPMiddleware.outpost_remote_ip_header: "1.2.3.4",
ClientIPMiddleware.outpost_token_header: "abc",
},
)
self.assertEqual(ClientIPMiddleware.get_client_ip(request), "127.0.0.1")
# Invalid, user doesn't have permissions
request = self.factory.get(
"/",
**{
ClientIPMiddleware.outpost_remote_ip_header: "1.2.3.4",
ClientIPMiddleware.outpost_token_header: token.key,
},
)
self.assertEqual(ClientIPMiddleware.get_client_ip(request), "127.0.0.1")
# Invalid, not a real IP
self.user.type = UserTypes.INTERNAL_SERVICE_ACCOUNT
self.user.save()
request = self.factory.get(
"/",
**{
ClientIPMiddleware.outpost_remote_ip_header: "foobar",
ClientIPMiddleware.outpost_token_header: token.key,
},
)
self.assertEqual(ClientIPMiddleware.get_client_ip(request), "127.0.0.1")
# Valid
self.user.type = UserTypes.INTERNAL_SERVICE_ACCOUNT
self.user.save()
request = self.factory.get(
"/",
**{
ClientIPMiddleware.outpost_remote_ip_header: "1.2.3.4",
ClientIPMiddleware.outpost_token_header: token.key,
},
)
self.assertEqual(ClientIPMiddleware.get_client_ip(request), "1.2.3.4")

View File

@ -2,7 +2,8 @@
from django.test import TestCase from django.test import TestCase
from authentik.common.exceptions import NotReportedException, before_send from authentik.common.exceptions import NotReportedException
from authentik.root.sentry import before_send
class TestSentry(TestCase): class TestSentry(TestCase):

View File

@ -0,0 +1,19 @@
"""Test HTTP Helpers"""
from django.test import RequestFactory, TestCase
from authentik.core.tests.utils import create_test_admin_user
from authentik.lib.views import bad_request_message
class TestViews(TestCase):
"""Test Views Helpers"""
def setUp(self) -> None:
self.user = create_test_admin_user()
self.factory = RequestFactory()
def test_bad_request_message(self):
"""test bad_request_message"""
request = self.factory.get("/")
self.assertEqual(bad_request_message(request, "foo").status_code, 400)

View File

@ -30,7 +30,7 @@ from tenant_schemas_celery.app import CeleryApp as TenantAwareCeleryApp
from authentik import get_full_version from authentik import get_full_version
from authentik.lib.utils.errors import exception_to_string from authentik.lib.utils.errors import exception_to_string
from authentik.root.sentry import before_send from authentik.root.sentry import should_ignore_exception
# set the default Django settings module for the 'celery' program. # set the default Django settings module for the 'celery' program.
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "authentik.root.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "authentik.root.settings")
@ -83,7 +83,7 @@ def task_error_hook(task_id: str, exception: Exception, traceback, *args, **kwar
LOGGER.warning("Task failure", task_id=task_id.replace("-", ""), exc=exception) LOGGER.warning("Task failure", task_id=task_id.replace("-", ""), exc=exception)
CTX_TASK_ID.set(...) CTX_TASK_ID.set(...)
if before_send({}, {"exc_info": (None, exception, None)}) is not None: if not should_ignore_exception(exception):
Event.new( Event.new(
EventAction.SYSTEM_EXCEPTION, message=exception_to_string(exception), task_id=task_id EventAction.SYSTEM_EXCEPTION, message=exception_to_string(exception), task_id=task_id
).save() ).save()

View File

@ -7,6 +7,9 @@ from tempfile import gettempdir
from django.test import TestCase from django.test import TestCase
from django.urls import reverse from django.urls import reverse
from authentik.core.models import Token, TokenIntents, UserTypes
from authentik.root.middleware import ClientIPMiddleware
class TestRoot(TestCase): class TestRoot(TestCase):
"""Test root application""" """Test root application"""
@ -39,3 +42,64 @@ class TestRoot(TestCase):
def test_monitoring_ready(self): def test_monitoring_ready(self):
"""Test ReadyView""" """Test ReadyView"""
self.assertEqual(self.client.get(reverse("health-ready")).status_code, 200) self.assertEqual(self.client.get(reverse("health-ready")).status_code, 200)
def test_normal(self):
"""Test normal request"""
request = self.factory.get("/")
self.assertEqual(ClientIPMiddleware.get_client_ip(request), "127.0.0.1")
def test_forward_for(self):
"""Test x-forwarded-for request"""
request = self.factory.get("/", HTTP_X_FORWARDED_FOR="127.0.0.2")
self.assertEqual(ClientIPMiddleware.get_client_ip(request), "127.0.0.2")
def test_forward_for_invalid(self):
"""Test invalid forward for"""
request = self.factory.get("/", HTTP_X_FORWARDED_FOR="foobar")
self.assertEqual(ClientIPMiddleware.get_client_ip(request), ClientIPMiddleware.default_ip)
def test_fake_outpost(self):
"""Test faked IP which is overridden by an outpost"""
token = Token.objects.create(
identifier="test", user=self.user, intent=TokenIntents.INTENT_API
)
# Invalid, non-existent token
request = self.factory.get(
"/",
**{
ClientIPMiddleware.outpost_remote_ip_header: "1.2.3.4",
ClientIPMiddleware.outpost_token_header: "abc",
},
)
self.assertEqual(ClientIPMiddleware.get_client_ip(request), "127.0.0.1")
# Invalid, user doesn't have permissions
request = self.factory.get(
"/",
**{
ClientIPMiddleware.outpost_remote_ip_header: "1.2.3.4",
ClientIPMiddleware.outpost_token_header: token.key,
},
)
self.assertEqual(ClientIPMiddleware.get_client_ip(request), "127.0.0.1")
# Invalid, not a real IP
self.user.type = UserTypes.INTERNAL_SERVICE_ACCOUNT
self.user.save()
request = self.factory.get(
"/",
**{
ClientIPMiddleware.outpost_remote_ip_header: "foobar",
ClientIPMiddleware.outpost_token_header: token.key,
},
)
self.assertEqual(ClientIPMiddleware.get_client_ip(request), "127.0.0.1")
# Valid
self.user.type = UserTypes.INTERNAL_SERVICE_ACCOUNT
self.user.save()
request = self.factory.get(
"/",
**{
ClientIPMiddleware.outpost_remote_ip_header: "1.2.3.4",
ClientIPMiddleware.outpost_token_header: token.key,
},
)
self.assertEqual(ClientIPMiddleware.get_client_ip(request), "1.2.3.4")

View File

@ -15,6 +15,7 @@ from rest_framework.serializers import ValidationError
from sentry_sdk import start_span from sentry_sdk import start_span
from authentik.core.api.utils import PassiveSerializer from authentik.core.api.utils import PassiveSerializer
from authentik.core.avatars import DEFAULT_AVATAR
from authentik.core.models import Application, Source, User from authentik.core.models import Application, Source, User
from authentik.events.utils import sanitize_item from authentik.events.utils import sanitize_item
from authentik.flows.challenge import ( from authentik.flows.challenge import (
@ -26,7 +27,6 @@ from authentik.flows.models import FlowDesignation
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
from authentik.flows.stage import PLAN_CONTEXT_PENDING_USER_IDENTIFIER, ChallengeStageView from authentik.flows.stage import PLAN_CONTEXT_PENDING_USER_IDENTIFIER, ChallengeStageView
from authentik.flows.views.executor import SESSION_KEY_APPLICATION_PRE, SESSION_KEY_GET from authentik.flows.views.executor import SESSION_KEY_APPLICATION_PRE, SESSION_KEY_GET
from authentik.lib.avatars import DEFAULT_AVATAR
from authentik.lib.utils.reflection import all_subclasses from authentik.lib.utils.reflection import all_subclasses
from authentik.lib.utils.urls import reverse_with_qs from authentik.lib.utils.urls import reverse_with_qs
from authentik.root.middleware import ClientIPMiddleware from authentik.root.middleware import ClientIPMiddleware