Skip to content

Commit 494510d

Browse files
✅ [#18] Add tests for the system check
1 parent ca33888 commit 494510d

2 files changed

Lines changed: 103 additions & 6 deletions

File tree

maykin_common/checks.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,11 @@ def check_privilege_escalation_prevention_enabled(
5656
"""
5757
Test that the user account privilege escalation protections are enabled.
5858
"""
59-
run_check = (
60-
app_configs is None
61-
or any(c.name in ("maykin_common", "django.contrib.admin") for c in app_configs)
62-
and apps.is_installed("django.contrib.admin")
59+
app_check_requested = app_configs is None or any(
60+
c.name in ("maykin_common", "django.contrib.admin") for c in app_configs
6361
)
64-
if not run_check:
62+
admin_installed = apps.is_installed("django.contrib.admin")
63+
if not (app_check_requested and admin_installed):
6564
return []
6665

6766
# look up which admin class is used for the user model

tests/base/test_checks.py

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
1+
from collections.abc import Sequence
12
from pathlib import Path
23

4+
from django.apps import AppConfig, apps
5+
from django.contrib import admin
6+
from django.contrib.auth.admin import UserAdmin
7+
from django.contrib.auth.models import User
38
from django.core.checks import Warning
49

5-
from maykin_common.checks import check_missing_init_files
10+
import pytest
11+
12+
from maykin_common.checks import (
13+
check_missing_init_files,
14+
check_privilege_escalation_prevention_enabled,
15+
)
616

717

818
def test_check_missing_init_files(settings):
@@ -18,3 +28,91 @@ def test_check_missing_init_files(settings):
1828
id="maykin.W001",
1929
)
2030
]
31+
32+
33+
@pytest.fixture
34+
def unregister_user_model():
35+
_original = type(admin.site.get_model_admin(User))
36+
admin.site.unregister(User)
37+
yield
38+
# pyright complains about invariance here:
39+
# Type parameter "_ModelT@ModelAdmin" is invariant, but "User" is not the same
40+
# as "Model"
41+
admin.site.register(User, _original) # pyright: ignore[reportArgumentType]
42+
43+
44+
@pytest.fixture
45+
def revert_useradmin_patch(unregister_user_model):
46+
"""
47+
Restore the default, unpatched user admin.
48+
"""
49+
admin.site.register(User, UserAdmin)
50+
yield
51+
admin.site.unregister(User)
52+
53+
54+
@pytest.mark.parametrize(
55+
"app_configs",
56+
[
57+
None,
58+
[
59+
apps.get_app_config("maykin_common"),
60+
apps.get_app_config("admin"),
61+
apps.get_app_config("testapp"),
62+
],
63+
],
64+
)
65+
def test_privilege_escalation_check_skipped_if_admin_not_installed(
66+
revert_useradmin_patch,
67+
app_configs: Sequence[AppConfig] | None,
68+
settings,
69+
):
70+
UPDATED_APPS = [*settings.INSTALLED_APPS]
71+
UPDATED_APPS.remove("django.contrib.admin")
72+
settings.INSTALLED_APPS = UPDATED_APPS
73+
assert not apps.is_installed("django.contrib.admin")
74+
75+
errors = check_privilege_escalation_prevention_enabled(app_configs)
76+
77+
assert errors == []
78+
79+
80+
def test_privilege_escalation_check_skipped_if_not_requested(
81+
revert_useradmin_patch,
82+
):
83+
errors = check_privilege_escalation_prevention_enabled(
84+
[apps.get_app_config("testapp")]
85+
)
86+
87+
assert errors == []
88+
89+
90+
def test_privilege_escalation_check_warns_if_admin_not_patched(
91+
revert_useradmin_patch,
92+
):
93+
errors = check_privilege_escalation_prevention_enabled(None)
94+
95+
expected_warning = Warning(
96+
"Your UserAdmin does not use the 'PreventPrivilegeEscalationMixin' "
97+
"protections.",
98+
hint=(
99+
"Use a custom UserAdmin that includes 'maykin_common.accounts.admin."
100+
"PreventPrivilegeEscalationMixin'."
101+
),
102+
id="maykin.W002",
103+
)
104+
assert expected_warning in errors
105+
106+
107+
def test_privilege_escalation_check_does_not_warn_if_admin_is_patched():
108+
errors = check_privilege_escalation_prevention_enabled(None)
109+
110+
assert errors == []
111+
112+
113+
def test_privilege_escalation_check_does_not_warn_for_unregistered_user_model(
114+
unregister_user_model,
115+
):
116+
errors = check_privilege_escalation_prevention_enabled(None)
117+
118+
assert errors == []

0 commit comments

Comments
 (0)