Skip to content

Commit

Permalink
Don't initialise anonymous user on DB where it's not migrated
Browse files Browse the repository at this point in the history
If the post-migrate signal is fired on a database which doesn't have the user model, skip the logic implemented `get_init_anonymous_user()`. This might be the case when a database router is used to have session somewhere else.

Fixes #650
  • Loading branch information
browniebroke authored and brianmay committed Nov 27, 2019
1 parent 5d49d22 commit 16e8713
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
5 changes: 3 additions & 2 deletions guardian/management/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import django
from django.contrib.auth import get_user_model
from django.db.models import signals
from django.utils.module_loading import import_string

from django.db import router
from guardian.conf import settings as guardian_settings


Expand All @@ -26,6 +25,8 @@ def create_anonymous_user(sender, **kwargs):
Creates anonymous User instance with id and username from settings.
"""
User = get_user_model()
if not router.allow_migrate_model(kwargs['using'], User):
return
try:
lookup = {User.USERNAME_FIELD: guardian_settings.ANONYMOUS_USER_NAME}
User.objects.using(kwargs['using']).get(**lookup)
Expand Down
37 changes: 37 additions & 0 deletions guardian/testapp/tests/test_management.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from copy import deepcopy

from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.sessions.models import Session
from django.test import TestCase, override_settings

import mock
Expand All @@ -7,6 +11,26 @@


mocked_get_init_anon = mock.Mock()
multi_db_dict = {
'default': deepcopy(settings.DATABASES['default']),
'session': deepcopy(settings.DATABASES['default']),
}


class SessionRouter:
@staticmethod
def db_for_write(model, **kwargs):
if model == Session:
return 'session'
else:
return None

@staticmethod
def allow_migrate(db, app_label, **kwargs):
if db == 'session':
return app_label == 'sessions'
else:
return None


class TestGetAnonymousUser(TestCase):
Expand Down Expand Up @@ -45,3 +69,16 @@ def test_get_anonymous_user(self):
anon = get_anonymous_user()
self.assertFalse(anon.has_usable_password())
self.assertEqual(anon.get_username(), "AnonymousUser")

@mock.patch('guardian.management.guardian_settings')
@override_settings(
DATABASE_ROUTERS=[SessionRouter()],
DATABASES=multi_db_dict
)
def test_non_migrated_db(self, guardian_settings):
mocked_get_init_anon.reset_mock()
guardian_settings.GET_INIT_ANONYMOUS_USER = 'guardian.testapp.tests.test_management.mocked_get_init_anon'

create_anonymous_user('sender', using='session')

mocked_get_init_anon.assert_not_called()

0 comments on commit 16e8713

Please sign in to comment.