Browse Source

Users lists tests

Rafał Pitoń 10 years ago
parent
commit
1ce6e22724

+ 6 - 0
misago/acl/migrations/0003_default_roles.py

@@ -28,6 +28,8 @@ def create_default_roles(apps, schema_editor):
 
             # profiles perms
             'misago.users.permissions.profiles': {
+                'can_browse_users_list': 1,
+                'can_see_users_online_list': 0,
                 'can_search_users': 1,
                 'can_follow_users': 1,
                 'can_be_blocked': 1,
@@ -59,6 +61,8 @@ def create_default_roles(apps, schema_editor):
 
             # profiles perms
             'misago.users.permissions.profiles': {
+                'can_browse_users_list': 1,
+                'can_see_users_online_list': 0,
                 'can_search_users': 1,
                 'can_see_users_name_history': 0,
                 'can_see_users_emails': 0,
@@ -88,6 +92,8 @@ def create_default_roles(apps, schema_editor):
 
             # profiles perms
             'misago.users.permissions.profiles': {
+                'can_browse_users_list': 1,
+                'can_see_users_online_list': 1,
                 'can_search_users': 1,
                 'can_be_blocked': 0,
                 'can_see_users_name_history': 1,

+ 2 - 0
misago/templates/misago/navbar.html

@@ -29,11 +29,13 @@
             <span class="fa fa-search fa-fw"></span>
           </a>
         </li>
+        {% if user.acl.can_browse_users_list %}
         <li>
           <a href="{% url 'misago:users' %}" class="tooltip-bottom" title="{% trans "Users" %}">
             <span class="fa fa-users fa-fw"></span>
           </a>
         </li>
+        {% endif %}
       </ul>
 
     </div><!-- /.navbar-collapse -->

+ 4 - 1
misago/users/apps.py

@@ -35,10 +35,13 @@ class MisagoUsersConfig(AppConfig):
                         icon='fa fa-ticket')
 
     def register_default_users_list_pages(self):
+        def can_see_online_list(request):
+            return request.user.acl['can_see_users_online_list']
         users_list.add_page(link='misago:users_active_posters',
                             name=_('Active posters'))
         users_list.add_page(link='misago:users_online',
-                            name=_('Online'))
+                            name=_('Online'),
+                            visible_if=can_see_online_list)
 
     def register_default_user_profile_pages(self):
         def posts_badge(request, profile):

+ 28 - 1
misago/users/permissions/profiles.py

@@ -13,6 +13,11 @@ from misago.users.permissions.decorators import authenticated_only
 """
 Admin Permissions Form
 """
+CAN_BROWSE_USERS_LIST = forms.YesNoSwitch(
+    label=_("Can browse users list"),
+    initial=1)
+CAN_SEE_USERS_ONLINE_LIST = forms.YesNoSwitch(
+    label=_("Can see users online list"))
 CAN_SEARCH_USERS = forms.YesNoSwitch(
     label=_("Can search user profiles"),
     initial=1)
@@ -26,12 +31,18 @@ CAN_SEE_BAN_DETAILS = forms.YesNoSwitch(
 
 class LimitedPermissionsForm(forms.Form):
     legend = _("User profiles")
+
+    can_browse_users_list = CAN_BROWSE_USERS_LIST
+    can_see_users_online_list = CAN_SEE_USERS_ONLINE_LIST
+    can_search_users = CAN_SEARCH_USERS
     can_search_users = CAN_SEARCH_USERS
     can_see_users_name_history = CAN_SEE_USER_NAME_HISTORY
     can_see_ban_details = CAN_SEE_BAN_DETAILS
 
 
 class PermissionsForm(LimitedPermissionsForm):
+    can_browse_users_list = CAN_BROWSE_USERS_LIST
+    can_see_users_online_list = CAN_SEE_USERS_ONLINE_LIST
     can_search_users = CAN_SEARCH_USERS
     can_follow_users = forms.YesNoSwitch(
         label=_("Can follow other users"),
@@ -64,8 +75,10 @@ ACL Builder
 """
 def build_acl(acl, roles, key_name):
     new_acl = {
+        'can_browse_users_list': 0,
+        'can_see_users_online_list': 0,
         'can_search_users': 0,
-        'can_follow_users': 1,
+        'can_follow_users': 0,
         'can_be_blocked': 1,
         'can_see_users_name_history': 0,
         'can_see_ban_details': 0,
@@ -77,6 +90,8 @@ def build_acl(acl, roles, key_name):
 
     return algebra.sum_acls(
             new_acl, roles=roles, key=key_name,
+            can_browse_users_list=algebra.greater,
+            can_see_users_online_list=algebra.greater,
             can_search_users=algebra.greater,
             can_follow_users=algebra.greater,
             can_be_blocked=algebra.lower,
@@ -114,6 +129,18 @@ def add_acl_to_target(user, target):
 """
 ACL tests
 """
+def allow_browse_users_list(user):
+    if not user.acl['can_browse_users_list']:
+        raise PermissionDenied(_("You can't browse users list."))
+can_browse_users_list = return_boolean(allow_browse_users_list)
+
+
+def allow_see_users_online_list(user):
+    if not user.acl['can_see_users_online_list']:
+        raise PermissionDenied(_("You can't browse users online list."))
+can_see_users_online_list = return_boolean(allow_see_users_online_list)
+
+
 @authenticated_only
 def allow_follow_user(user, target):
     if not user.acl['can_follow_users']:

+ 101 - 0
misago/users/tests/test_lists_views.py

@@ -0,0 +1,101 @@
+from django.contrib.auth import get_user_model
+from django.core.urlresolvers import reverse
+
+from misago.acl.testutils import override_acl
+from misago.admin.testutils import AdminTestCase
+
+from misago.users.models import Ban, Rank
+
+
+class UsersListTestCase(AdminTestCase):
+    def setUp(self):
+        super(UsersListTestCase, self).setUp()
+        override_acl(self.test_admin, {
+            'misago.users.permissions.profiles': {
+                'can_browse_users_list': 1
+            }
+        })
+
+
+class UsersListLanderTests(UsersListTestCase):
+    def test_lander_no_permission(self):
+        """lander returns 403 if user has no permission"""
+        override_acl(self.test_admin, {
+            'misago.users.permissions.profiles': {
+                'can_browse_users_list': 0
+            }
+        })
+
+        response = self.client.get(reverse('misago:users'))
+        self.assertEqual(response.status_code, 403)
+
+    def test_lander_redirect(self):
+        """lander returns redirect to valid page if user has permission"""
+        response = self.client.get(reverse('misago:users'))
+        self.assertEqual(response.status_code, 302)
+        self.assertTrue(response['location'].endswith(
+                         reverse('misago:users_active_posters')))
+
+
+class ActivePostersTests(UsersListTestCase):
+    def test_active_posters_list(self):
+        """active posters page has no showstoppers"""
+        view_link = reverse('misago:users_active_posters')
+
+        response = self.client.get(view_link)
+        self.assertEqual(response.status_code, 200)
+
+        # Create 200 test users and see if errors appeared
+        User = get_user_model()
+        for i in xrange(200):
+            User.objects.create_user('Bob%s' % i, 'm%s@te.com' % i, 'Pass.123',
+                                     posts=12345)
+
+        response = self.client.get(view_link)
+        self.assertEqual(response.status_code, 200)
+
+        for page in xrange(2, 6):
+            response = self.client.get(reverse('misago:users_active_posters',
+                                               kwargs={'page': page}))
+        self.assertEqual(response.status_code, 200)
+
+
+class OnlineUsersTests(UsersListTestCase):
+    def test_no_permission(self):
+        """online list returns 403 if user has no permission"""
+        override_acl(self.test_admin, {
+            'misago.users.permissions.profiles': {
+                'can_browse_users_list': 1,
+                'can_see_users_online_list': 0,
+            }
+        })
+
+        response = self.client.get(reverse('misago:users_online'))
+        self.assertEqual(response.status_code, 403)
+
+    def test_with_permission(self):
+        """online list returns 200 if user has permission"""
+        override_acl(self.test_admin, {
+            'misago.users.permissions.profiles': {
+                'can_browse_users_list': 1,
+                'can_see_users_online_list': 1,
+            }
+        })
+
+        response = self.client.get(reverse('misago:users_online'))
+        self.assertEqual(response.status_code, 200)
+
+
+class UsersRankTests(UsersListTestCase):
+    def test_ranks(self):
+        """ranks lists are handled correctly"""
+        for rank in Rank.objects.iterator():
+            rank_link = reverse('misago:users_rank',
+                                kwargs={'rank_slug': rank.slug})
+            response = self.client.get(rank_link)
+
+            if rank.is_tab:
+                self.assertEqual(response.status_code, 200)
+            else:
+                self.assertEqual(response.status_code, 404)
+

+ 22 - 5
misago/users/views/lists.py

@@ -7,14 +7,11 @@ from misago.core.shortcuts import get_object_or_404, paginate
 
 from misago.users.models import Rank
 from misago.users.online import get_online_queryset
+from misago.users.permissions.profiles import (allow_browse_users_list,
+                                               allow_see_users_online_list)
 from misago.users.sites import users_list
 
 
-def lander(request):
-    default = users_list.get_default_link()
-    return redirect(default)
-
-
 def render(request, template, context):
     context['pages'] = users_list.get_pages(request)
 
@@ -38,12 +35,30 @@ def render(request, template, context):
     return django_render(request, template, context)
 
 
+def allow_see_list(permission=None):
+    def permission_decorator(f):
+        def decorator(request, *args, **kwargs):
+            allow_browse_users_list(request.user)
+            if permission:
+                permission(request.user)
+            return f(request, *args, **kwargs)
+        return decorator
+    return permission_decorator
+
+
+@allow_see_list()
+def lander(request):
+    default = users_list.get_default_link()
+    return redirect(default)
+
+
 def list_view(request, template, queryset, page, context=None):
     context = context or {}
     context['users'] = paginate(queryset, page, 6 * 3, 5)
     return render(request, template, context)
 
 
+@allow_see_list()
 def active_posters(request, page=0):
     tracked_period = settings.MISAGO_RANKING_LENGTH
     User = get_user_model()
@@ -55,6 +70,7 @@ def active_posters(request, page=0):
     })
 
 
+@allow_see_list(allow_see_users_online_list)
 def online(request, page=0):
     queryset = get_online_queryset(request.user).order_by('user__slug')
 
@@ -62,6 +78,7 @@ def online(request, page=0):
     return list_view(request, template, queryset, page)
 
 
+@allow_see_list()
 def rank(request, rank_slug, page=0):
     rank = get_object_or_404(Rank.objects.filter(is_tab=True), slug=rank_slug)
     queryset = rank.user_set.order_by('slug')