Repository: django-hijack/django-hijack

Issue:
Using HijackUserAdminMixin on Classes with optional ForeignKeys to User may lead to error 500
When using `HijackUserAdminMixin` on a Class that only has an optional ForeignKey (`null=True` allowed) to User, any instance that does not have a User set will lead to an error (500):
```'NoneType' object has no attribute 'is_active'```

We can fix this by returning False in our permission check functions if hijacked is None. I'll open a PR for this.
Using HijackUserAdminMixin on Classes with optional ForeignKeys to User may lead to error 500
When using `HijackUserAdminMixin` on a Class that only has an optional ForeignKey (`null=True` allowed) to User, any instance that does not have a User set will lead to an error (500):
```'NoneType' object has no attribute 'is_active'```

We can fix this by returning False in our permission check functions if hijacked is None. I'll open a PR for this.


Discussion:

Resolving patch:
diff --git a/hijack/permissions.py b/hijack/permissions.py
--- a/hijack/permissions.py
+++ b/hijack/permissions.py
@@ -1,5 +1,7 @@
 def superusers_only(*, hijacker, hijacked):
     """Superusers may hijack any other user."""
+    if not hijacked:
+        return False
     return hijacked.is_active and hijacker.is_superuser
 
 
@@ -10,7 +12,7 @@ def superusers_and_staff(*, hijacker, hijacked):
     A superuser may hijack any other user.
     A staff member may hijack any user, except another staff member or superuser.
     """
-    if not hijacked.is_active:
+    if not hijacked or not hijacked.is_active:
         return False
 
     if hijacker.is_superuser:


Test patch:
diff --git a/hijack/tests/test_permissions.py b/hijack/tests/test_permissions.py
--- a/hijack/tests/test_permissions.py
+++ b/hijack/tests/test_permissions.py
@@ -12,14 +12,17 @@
 @pytest.mark.parametrize(
     "hijacker, hijacked, has_perm",
     [
+        (superuser, None, False),
         (superuser, superuser, True),
         (superuser, staff_member, True),
         (superuser, regular_user, True),
         (superuser, inactive_user, False),
+        (staff_member, None, False),
         (staff_member, regular_user, False),
         (staff_member, staff_member, False),
         (staff_member, superuser, False),
         (staff_member, inactive_user, False),
+        (regular_user, None, False),
         (regular_user, superuser, False),
         (regular_user, staff_member, False),
         (regular_user, regular_user, False),
@@ -33,14 +36,17 @@ def test_superusers_only(hijacker, hijacked, has_perm):
 @pytest.mark.parametrize(
     "hijacker, hijacked, has_perm",
     [
+        (superuser, None, False),
         (superuser, superuser, True),
         (superuser, staff_member, True),
         (superuser, regular_user, True),
         (superuser, inactive_user, False),
+        (staff_member, None, False),
         (staff_member, regular_user, True),
         (staff_member, staff_member, False),
         (staff_member, superuser, False),
         (staff_member, inactive_user, False),
+        (regular_user, None, False),
         (regular_user, superuser, False),
         (regular_user, staff_member, False),
         (regular_user, regular_user, False),