Просмотр исходного кода

Merge pull request #1143 from rafalp/remove-global-state-from-users-bans

Remove global state from users bans
Rafał Pitoń 6 лет назад
Родитель
Сommit
44b648ef7f

+ 1 - 1
misago/threads/api/postendpoints/edits.py

@@ -74,7 +74,7 @@ def revert_post_endpoint(request, post):
     add_acl(request.user, post)
 
     if post.poster:
-        make_users_status_aware(request.user, [post.poster])
+        make_users_status_aware(request, [post.poster])
 
     return Response(PostSerializer(post, context={'user': request.user}).data)
 

+ 2 - 2
misago/threads/api/threadposts.py

@@ -111,7 +111,7 @@ class ViewSet(viewsets.ViewSet):
             post.is_new = True
             post.poster.posts = user_posts + 1
 
-            make_users_status_aware(request.user, [post.poster])
+            make_users_status_aware(request, [post.poster])
 
             return Response(PostSerializer(post, context={'user': request.user}).data)
         else:
@@ -141,7 +141,7 @@ class ViewSet(viewsets.ViewSet):
             post.edits = post_edits + 1
 
             if post.poster:
-                make_users_status_aware(request.user, [post.poster])
+                make_users_status_aware(request, [post.poster])
 
             return Response(PostSerializer(post, context={'user': request.user}).data)
         else:

+ 1 - 1
misago/threads/viewmodels/posts.py

@@ -38,7 +38,7 @@ class ViewModel(object):
             if post.poster:
                 posters.append(post.poster)
 
-        make_users_status_aware(request.user, posters)
+        make_users_status_aware(request, posters)
 
         if thread.category.acl['can_see_posts_likes']:
             add_likes_to_posts(request.user, posts)

+ 1 - 1
misago/users/api/auth.py

@@ -191,7 +191,7 @@ def change_forgotten_password(request, pk, token):
 
         if user.requires_activation:
             raise PasswordChangeFailed(expired_message)
-        if get_user_ban(user):
+        if get_user_ban(user, request.cache_versions):
             raise PasswordChangeFailed(expired_message)
     except PasswordChangeFailed as e:
         return Response(

+ 2 - 2
misago/users/api/users.py

@@ -85,7 +85,7 @@ class UserViewSet(viewsets.GenericViewSet):
         profile = self.get_user(request, pk)
 
         add_acl(request.user, profile)
-        profile.status = get_user_status(request.user, profile)
+        profile.status = get_user_status(request, profile)
 
         serializer = UserProfileSerializer(profile, context={'user': request.user})
         profile_json = serializer.data
@@ -199,7 +199,7 @@ class UserViewSet(viewsets.GenericViewSet):
         profile = self.get_user(request, pk)
         allow_see_ban_details(request.user, profile)
 
-        ban = get_user_ban(profile)
+        ban = get_user_ban(profile, request.cache_versions)
         if ban:
             return Response(BanDetailsSerializer(ban).data)
         else:

+ 1 - 1
misago/users/apps.py

@@ -80,7 +80,7 @@ class MisagoUsersConfig(AppConfig):
             if request.user.is_authenticated:
                 if request.user.acl_cache['can_see_ban_details']:
                     from .bans import get_user_ban
-                    return bool(get_user_ban(profile))
+                    return bool(get_user_ban(profile, request.cache_versions))
                 else:
                     return False
             else:

+ 8 - 11
misago/users/bans.py

@@ -9,13 +9,10 @@ from datetime import timedelta
 from django.utils import timezone
 from django.utils.dateparse import parse_datetime
 
-from misago.core import cachebuster
-
+from .constants import BANS_CACHE
 from .models import Ban, BanCache
 
-
 CACHE_SESSION_KEY = 'misago_ip_check'
-VERSION_KEY = 'misago_bans'
 
 
 def get_username_ban(username, registration_only=False):
@@ -39,7 +36,7 @@ def get_ip_ban(ip, registration_only=False):
         return None
 
 
-def get_user_ban(user):
+def get_user_ban(user, cache_versions):
     """
     This function checks if user is banned
 
@@ -49,11 +46,11 @@ def get_user_ban(user):
     """
     try:
         ban_cache = user.ban_cache
-        if not ban_cache.is_valid:
+        if not ban_cache.is_valid(cache_versions):
             _set_user_ban_cache(user)
     except BanCache.DoesNotExist:
         user.ban_cache = BanCache(user=user)
-        user.ban_cache = _set_user_ban_cache(user)
+        user.ban_cache = _set_user_ban_cache(user, cache_versions)
 
     if user.ban_cache.ban:
         return user.ban_cache
@@ -61,9 +58,9 @@ def get_user_ban(user):
         return None
 
 
-def _set_user_ban_cache(user):
+def _set_user_ban_cache(user, cache_versions):
     ban_cache = user.ban_cache
-    ban_cache.bans_version = cachebuster.get_version(VERSION_KEY)
+    ban_cache.cache_version = cache_versions[BANS_CACHE]
 
     try:
         user_ban = Ban.objects.get_ban(
@@ -103,7 +100,7 @@ def get_request_ip_ban(request):
     found_ban = get_ip_ban(request.user_ip)
 
     ban_cache = request.session[CACHE_SESSION_KEY] = {
-        'version': cachebuster.get_version(VERSION_KEY),
+        'version': request.cache_versions[BANS_CACHE],
         'ip': request.user_ip,
     }
 
@@ -128,7 +125,7 @@ def _get_session_bancache(request):
         ban_cache = _hydrate_session_cache(ban_cache)
         if ban_cache['ip'] != request.user_ip:
             return None
-        if not cachebuster.is_valid(VERSION_KEY, ban_cache['version']):
+        if ban_cache['version'] != request.cache_versions[BANS_CACHE]:
             return None
         if ban_cache.get('expires_on'):
             if ban_cache['expires_on'] < timezone.today():

+ 1 - 1
misago/users/constants.py

@@ -1 +1 @@
-BANS_CACHEBUSTER = 'misago_bans'
+BANS_CACHE = "bans"

+ 5 - 1
misago/users/forms/auth.py

@@ -31,7 +31,7 @@ class MisagoAuthMixin(object):
 
     def confirm_user_not_banned(self, user):
         if not user.is_staff:
-            self.user_ban = get_user_ban(user)
+            self.user_ban = get_user_ban(user, self.request.cache_versions)
             if self.user_ban:
                 raise ValidationError('', code='banned')
 
@@ -62,6 +62,10 @@ class AuthenticationForm(MisagoAuthMixin, BaseAuthenticationForm):
         widget=forms.PasswordInput,
     )
 
+    def __init__(self, *args, request=None, **kwargs):
+        self.request = request
+        super().__init__(*args, **kwargs)
+
     def clean(self):
         username = self.cleaned_data.get('username')
         password = self.cleaned_data.get('password')

+ 5 - 3
misago/users/management/commands/invalidatebans.py

@@ -1,7 +1,9 @@
 from django.core.management.base import BaseCommand
 from django.utils import timezone
 
-from misago.core import cachebuster
+from misago.cache.versions import get_cache_versions
+
+from misago.users.constants import BANS_CACHE
 from misago.users.models import Ban, BanCache
 
 
@@ -28,8 +30,8 @@ class Command(BaseCommand):
         expired_count = queryset.count()
         queryset.delete()
 
-        bans_version = cachebuster.get_version('misago_bans')
-        queryset = BanCache.objects.filter(bans_version__lt=bans_version)
+        cache_versions = get_cache_versions()
+        queryset = BanCache.objects.exclude(cache_version=cache_versions[BANS_CACHE])
 
         expired_count += queryset.count()
         queryset.delete()

+ 4 - 1
misago/users/middleware.py

@@ -20,7 +20,10 @@ class UserMiddleware(MiddlewareMixin):
         if request.user.is_anonymous:
             request.user = AnonymousUser()
         elif not request.user.is_staff:
-            if get_request_ip_ban(request) or get_user_ban(request.user):
+            if (
+                get_request_ip_ban(request) or
+                get_user_ban(request.user, request.cache_versions)
+            ):
                 logout(request)
                 request.user = AnonymousUser()
 

+ 1 - 9
misago/users/migrations/0003_bans_version_tracker.py

@@ -1,11 +1,6 @@
 from django.db import migrations
 
 
-def register_bans_version_tracker(apps, schema_editor):
-    from misago.core.migrationutils import cachebuster_register_cache
-    cachebuster_register_cache(apps, "misago_bans")
-
-
 class Migration(migrations.Migration):
     """Migration superseded by 0016"""
 
@@ -14,7 +9,4 @@ class Migration(migrations.Migration):
         ('misago_core', '0001_initial'),
     ]
 
-    operations = [
-        # FIXME: remove this operation
-        migrations.RunPython(register_bans_version_tracker),
-    ]
+    operations = []

+ 32 - 0
misago/users/migrations/0017_move_bans_to_cache_version.py

@@ -0,0 +1,32 @@
+# Generated by Django 1.11.16 on 2018-11-29 20:28
+from django.db import migrations, models
+
+from misago.users.constants import BANS_CACHE
+
+
+def populate_cache_version(apps, _):
+    BanCache = apps.get_model("misago_users", "BanCache")
+    BanCache.objects.all().delete()
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('misago_users', '0016_cache_version'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='bancache',
+            name='bans_version',
+        ),
+        migrations.RunPython(
+            populate_cache_version,
+            migrations.RunPython.noop,
+        ),
+        migrations.AddField(
+            model_name='bancache',
+            name='cache_version',
+            field=models.CharField(max_length=8),
+        ),
+    ]

+ 8 - 9
misago/users/models/ban.py

@@ -5,8 +5,8 @@ from django.db import IntegrityError, models
 from django.utils import timezone
 from django.utils.translation import gettext_lazy as _
 
-from misago.core import cachebuster
-from misago.users.constants import BANS_CACHEBUSTER
+from misago.cache.versions import invalidate_cache
+from misago.users.constants import BANS_CACHE
 
 
 class BansManager(models.Manager):
@@ -29,7 +29,7 @@ class BansManager(models.Manager):
         )
 
     def invalidate_cache(self):
-        cachebuster.invalidate(BANS_CACHEBUSTER)
+        invalidate_cache(BANS_CACHE)
 
     def get_ban(self, username=None, email=None, ip=None, registration_only=False):
         checks = []
@@ -131,7 +131,7 @@ class BanCache(models.Model):
         blank=True,
         on_delete=models.SET_NULL,
     )
-    bans_version = models.PositiveIntegerField(default=0)
+    cache_version = models.CharField(max_length=8)
     user_message = models.TextField(null=True, blank=True)
     staff_message = models.TextField(null=True, blank=True)
     expires_on = models.DateTimeField(null=True, blank=True)
@@ -157,9 +157,8 @@ class BanCache(models.Model):
     def is_banned(self):
         return bool(self.ban)
 
-    @property
-    def is_valid(self):
-        version_is_valid = cachebuster.is_valid(BANS_CACHEBUSTER, self.bans_version)
-        expired = self.expires_on and self.expires_on < timezone.now()
+    def is_valid(self, cache_versions):
+        is_versioned = self.cache_version == cache_versions[BANS_CACHE]
+        is_expired = self.expires_on and self.expires_on < timezone.now()
 
-        return version_is_valid and not expired
+        return is_versioned and not is_expired

+ 24 - 23
misago/users/online/utils.py

@@ -9,7 +9,27 @@ from misago.users.models import BanCache, Online
 ACTIVITY_CUTOFF = timedelta(minutes=2)
 
 
-def get_user_status(viewer, user):
+
+def make_users_status_aware(request, users, fetch_state=False):
+    users_dict = {}
+    for user in users:
+        users_dict[user.pk] = user
+
+    if fetch_state:
+        # Fill ban cache on users
+        for ban_cache in BanCache.objects.filter(user__in=users_dict.keys()):
+            users_dict[ban_cache.user_id].ban_cache = ban_cache
+
+        # Fill user online trackers
+        for online_tracker in Online.objects.filter(user__in=users_dict.keys()):
+            users_dict[online_tracker.user_id].online_tracker = online_tracker
+
+    # Fill user states
+    for user in users:
+        user.status = get_user_status(request, user)
+
+
+def get_user_status(request, user):
     user_status = {
         'is_banned': False,
         'is_hidden': user.is_hiding_presence,
@@ -21,14 +41,14 @@ def get_user_status(viewer, user):
         'last_click': user.last_login or user.joined_on,
     }
 
-    user_ban = get_user_ban(user)
+    user_ban = get_user_ban(user, request.cache_versions)
     if user_ban:
         user_status['is_banned'] = True
         user_status['banned_until'] = user_ban.expires_on
 
     try:
         online_tracker = user.online_tracker
-        is_hidden = user.is_hiding_presence and not viewer.acl_cache['can_see_hidden_users']
+        is_hidden = user.is_hiding_presence and not request.user.acl_cache['can_see_hidden_users']
 
         if online_tracker and not is_hidden:
             if online_tracker.last_click >= timezone.now() - ACTIVITY_CUTOFF:
@@ -38,7 +58,7 @@ def get_user_status(viewer, user):
         pass
 
     if user_status['is_hidden']:
-        if viewer.acl_cache['can_see_hidden_users']:
+        if request.user.acl_cache['can_see_hidden_users']:
             user_status['is_hidden'] = False
             if user_status['is_online']:
                 user_status['is_online_hidden'] = True
@@ -55,22 +75,3 @@ def get_user_status(viewer, user):
             user_status['is_offline'] = True
 
     return user_status
-
-
-def make_users_status_aware(viewer, users, fetch_state=False):
-    users_dict = {}
-    for user in users:
-        users_dict[user.pk] = user
-
-    if fetch_state:
-        # Fill ban cache on users
-        for ban_cache in BanCache.objects.filter(user__in=users_dict.keys()):
-            users_dict[ban_cache.user_id].ban_cache = ban_cache
-
-        # Fill user online trackers
-        for online_tracker in Online.objects.filter(user__in=users_dict.keys()):
-            users_dict[online_tracker.user_id].online_tracker = online_tracker
-
-    # Fill user states
-    for user in users:
-        user.status = get_user_status(viewer, user)

+ 1 - 1
misago/users/social/pipeline.py

@@ -47,7 +47,7 @@ def validate_user_not_banned(strategy, details, backend, user=None, *args, **kwa
     if not user or user.is_staff:
         return None
 
-    user_ban = get_user_ban(user)
+    user_ban = get_user_ban(user, strategy.request.cache_versions)
     if user_ban:
         raise SocialAuthBanned(backend, user_ban)
 

+ 19 - 13
misago/users/tests/test_bans.py

@@ -4,8 +4,11 @@ from django.contrib.auth import get_user_model
 from django.test import TestCase
 from django.utils import timezone
 
+from misago.cache.versions import get_cache_versions_from_db
+
 from misago.users.bans import (
     ban_ip, ban_user, get_email_ban, get_ip_ban, get_request_ip_ban, get_user_ban, get_username_ban)
+from misago.users.constants import BANS_CACHE
 from misago.users.models import Ban
 
 
@@ -40,13 +43,13 @@ class GetBanTests(TestCase):
         )
         self.assertEqual(get_username_ban('admiral').pk, valid_ban.pk)
 
-        regitration_ban = Ban.objects.create(
+        registration_ban = Ban.objects.create(
             banned_value='bob*',
             expires_on=timezone.now() + timedelta(days=7),
             registration_only=True,
         )
         self.assertIsNone(get_username_ban('boberson'))
-        self.assertEqual(get_username_ban('boberson', True).pk, regitration_ban.pk)
+        self.assertEqual(get_username_ban('boberson', True).pk, registration_ban.pk)
 
     def test_get_email_ban(self):
         """get_email_ban returns valid ban"""
@@ -77,14 +80,14 @@ class GetBanTests(TestCase):
         )
         self.assertEqual(get_email_ban('banned@mail.ru').pk, valid_ban.pk)
 
-        regitration_ban = Ban.objects.create(
+        registration_ban = Ban.objects.create(
             banned_value='*.ua',
             check_type=Ban.EMAIL,
             expires_on=timezone.now() + timedelta(days=7),
             registration_only=True,
         )
         self.assertIsNone(get_email_ban('banned@mail.ua'))
-        self.assertEqual(get_email_ban('banned@mail.ua', True).pk, regitration_ban.pk)
+        self.assertEqual(get_email_ban('banned@mail.ua', True).pk, registration_ban.pk)
 
     def test_get_ip_ban(self):
         """get_ip_ban returns valid ban"""
@@ -115,14 +118,14 @@ class GetBanTests(TestCase):
         )
         self.assertEqual(get_ip_ban('125.0.0.1').pk, valid_ban.pk)
 
-        regitration_ban = Ban.objects.create(
+        registration_ban = Ban.objects.create(
             banned_value='188.*',
             check_type=Ban.IP,
             expires_on=timezone.now() + timedelta(days=7),
             registration_only=True,
         )
         self.assertIsNone(get_ip_ban('188.12.12.41'))
-        self.assertEqual(get_ip_ban('188.12.12.41', True).pk, regitration_ban.pk)
+        self.assertEqual(get_ip_ban('188.12.12.41', True).pk, registration_ban.pk)
 
 
 class UserBansTests(TestCase):
@@ -131,7 +134,7 @@ class UserBansTests(TestCase):
 
     def test_no_ban(self):
         """user is not caught by ban"""
-        self.assertIsNone(get_user_ban(self.user))
+        self.assertIsNone(get_user_ban(self.user, get_cache_versions_from_db()))
         self.assertFalse(self.user.ban_cache.is_banned)
 
     def test_permanent_ban(self):
@@ -142,7 +145,7 @@ class UserBansTests(TestCase):
             staff_message='Staff reason',
         )
 
-        user_ban = get_user_ban(self.user)
+        user_ban = get_user_ban(self.user, get_cache_versions_from_db())
         self.assertIsNotNone(user_ban)
         self.assertEqual(user_ban.user_message, 'User reason')
         self.assertEqual(user_ban.staff_message, 'Staff reason')
@@ -157,7 +160,7 @@ class UserBansTests(TestCase):
             expires_on=timezone.now() + timedelta(days=7),
         )
 
-        user_ban = get_user_ban(self.user)
+        user_ban = get_user_ban(self.user, get_cache_versions_from_db())
         self.assertIsNotNone(user_ban)
         self.assertEqual(user_ban.user_message, 'User reason')
         self.assertEqual(user_ban.staff_message, 'Staff reason')
@@ -170,7 +173,7 @@ class UserBansTests(TestCase):
             expires_on=timezone.now() - timedelta(days=7),
         )
 
-        self.assertIsNone(get_user_ban(self.user))
+        self.assertIsNone(get_user_ban(self.user, get_cache_versions_from_db()))
         self.assertFalse(self.user.ban_cache.is_banned)
 
     def test_expired_non_flagged_ban(self):
@@ -181,7 +184,7 @@ class UserBansTests(TestCase):
         )
         Ban.objects.update(is_checked=True)
 
-        self.assertIsNone(get_user_ban(self.user))
+        self.assertIsNone(get_user_ban(self.user, get_cache_versions_from_db()))
         self.assertFalse(self.user.ban_cache.is_banned)
 
 
@@ -189,6 +192,9 @@ class MockRequest(object):
     def __init__(self):
         self.user_ip = '127.0.0.1'
         self.session = {}
+        self.cache_versions = {
+            BANS_CACHE: "abcdefgh"
+        }
 
 
 class RequestIPBansTests(TestCase):
@@ -255,7 +261,7 @@ class BanUserTests(TestCase):
         self.assertEqual(ban.user_message, 'User reason')
         self.assertEqual(ban.staff_message, 'Staff reason')
 
-        db_ban = get_user_ban(user)
+        db_ban = get_user_ban(user, get_cache_versions_from_db())
         self.assertEqual(ban.pk, db_ban.ban_id)
 
 
@@ -267,4 +273,4 @@ class BanIpTests(TestCase):
         self.assertEqual(ban.staff_message, 'Staff reason')
 
         db_ban = get_ip_ban('127.0.0.1')
-        self.assertEqual(ban.pk, db_ban.pk)
+        self.assertEqual(ban.pk, db_ban.pk)

+ 4 - 2
misago/users/tests/test_invalidatebans.py

@@ -6,6 +6,8 @@ from django.core.management import call_command
 from django.test import TestCase
 from django.utils import timezone
 
+from misago.cache.versions import get_cache_versions
+
 from misago.users import bans
 from misago.users.management.commands import invalidatebans
 from misago.users.models import Ban, BanCache
@@ -41,7 +43,7 @@ class InvalidateBansTests(TestCase):
 
         # ban user
         Ban.objects.create(banned_value="bob")
-        user_ban = bans.get_user_ban(user)
+        user_ban = bans.get_user_ban(user, get_cache_versions())
 
         self.assertIsNotNone(user_ban)
         self.assertEqual(Ban.objects.filter(is_checked=True).count(), 1)
@@ -74,4 +76,4 @@ class InvalidateBansTests(TestCase):
 
         # see if user is banned anymore
         user = UserModel.objects.get(id=user.id)
-        self.assertIsNone(bans.get_user_ban(user))
+        self.assertIsNone(bans.get_user_ban(user, get_cache_versions()))

+ 8 - 3
misago/users/tests/test_online_utils.py

@@ -1,3 +1,5 @@
+from unittest.mock import Mock
+
 from django.contrib.auth import get_user_model
 
 from misago.acl.testutils import override_acl
@@ -18,7 +20,8 @@ class GetUserStatusTests(AuthenticatedUserTestCase):
         self.other_user.is_hiding_presence = True
         self.other_user.save()
 
-        get_user_status(self.user, self.other_user)
+        request = Mock(user=self.user, cache_versions={"bans": "abcdfghi"})
+        get_user_status(request, self.other_user)
 
     def test_user_visible_hidden_presence(self):
         """get_user_status has no showstopper forvisible  hidden user"""
@@ -29,8 +32,10 @@ class GetUserStatusTests(AuthenticatedUserTestCase):
             'can_see_hidden_users': True,
         })
 
-        get_user_status(self.user, self.other_user)
+        request = Mock(user=self.user, cache_versions={"bans": "abcdfghi"})
+        get_user_status(request, self.other_user)
 
     def test_user_not_hiding_presence(self):
         """get_user_status has no showstoppers for non-hidden user"""
-        get_user_status(self.user, self.other_user)
+        request = Mock(user=self.user, cache_versions={"bans": "abcdfghi"})
+        get_user_status(request, self.other_user)

+ 2 - 0
misago/users/tests/test_social_pipeline.py

@@ -9,6 +9,7 @@ from social_django.utils import load_strategy
 from misago.core.exceptions import SocialAuthFailed, SocialAuthBanned
 from misago.legal.models import Agreement
 
+from misago.users.constants import BANS_CACHE
 from misago.users.models import AnonymousUser, Ban, BanCache
 from misago.users.social.pipeline import (
     associate_by_email, create_user, create_user_with_form, get_username, require_activation,
@@ -27,6 +28,7 @@ def create_request(user_ip='0.0.0.0', data=None):
     else:
         request = factory.post('/', data=json.dumps(data), content_type='application/json')
     request.include_frontend_context = True
+    request.cache_versions = {BANS_CACHE: "abcdefgh"}
     request.frontend_context = {}
     request.session = {}
     request.user = AnonymousUser()

+ 1 - 1
misago/users/viewmodels/activeposters.py

@@ -7,7 +7,7 @@ from misago.users.serializers import UserCardSerializer
 class ActivePosters(object):
     def __init__(self, request):
         ranking = get_active_posters_ranking()
-        make_users_status_aware(request.user, ranking['users'], fetch_state=True)
+        make_users_status_aware(request, ranking['users'], fetch_state=True)
 
         self.count = ranking['users_count']
         self.tracked_period = settings.MISAGO_RANKING_LENGTH

+ 1 - 1
misago/users/viewmodels/followers.py

@@ -21,7 +21,7 @@ class Followers(object):
                 raise Http404()
 
         list_page = paginate(queryset, page, settings.MISAGO_USERS_PER_PAGE, 4)
-        make_users_status_aware(request.user, list_page.object_list)
+        make_users_status_aware(request, list_page.object_list)
 
         self.users = list_page.object_list
         self.paginator = pagination_dict(list_page)

+ 1 - 1
misago/users/viewmodels/rankusers.py

@@ -16,7 +16,7 @@ class RankUsers(object):
             queryset = queryset.filter(is_active=True)
 
         list_page = paginate(queryset, page, settings.MISAGO_USERS_PER_PAGE, 4)
-        make_users_status_aware(request.user, list_page.object_list)
+        make_users_status_aware(request, list_page.object_list)
 
         self.users = list_page.object_list
         self.paginator = pagination_dict(list_page)

+ 1 - 1
misago/users/views/activation.py

@@ -53,7 +53,7 @@ def activate_by_token(request, pk, token):
             )
             raise ActivationError(message % {'user': inactive_user.username})
 
-        ban = get_user_ban(inactive_user)
+        ban = get_user_ban(inactive_user, request.cache_versions)
         if ban:
             raise Banned(ban)
     except ActivationStopped as e:

+ 1 - 1
misago/users/views/forgottenpassword.py

@@ -42,7 +42,7 @@ def reset_password_form(request, pk, token):
             message = _("%(user)s, your link is invalid. Please try again or request new link.")
             raise ResetError(message % {'user': requesting_user.username})
 
-        ban = get_user_ban(requesting_user)
+        ban = get_user_ban(requesting_user, request.cache_versions)
         if ban:
             raise Banned(ban)
     except ResetError as e:

+ 2 - 2
misago/users/views/profile.py

@@ -27,7 +27,7 @@ class ProfileView(View):
         if not active_section:
             raise Http404()
 
-        profile.status = get_user_status(request.user, profile)
+        profile.status = get_user_status(request, profile)
         context_data = self.get_context_data(request, profile)
 
         self.complete_frontend_context(request, profile, sections)
@@ -184,7 +184,7 @@ class UserBanView(ProfileView):
     template_name = 'misago/profile/ban_details.html'
 
     def get_context_data(self, request, profile):
-        ban = get_user_ban(profile)
+        ban = get_user_ban(profile, request.cache_versions)
 
         request.frontend_context['PROFILE_BAN'] = BanDetailsSerializer(ban).data