Browse Source

fix #639 and some extra cleanups

Rafał Pitoń 8 years ago
parent
commit
f0eb0deca3

+ 50 - 2
misago/templates/misago/admin/users/edit.html

@@ -33,14 +33,62 @@ class="form-horizontal"
     {% form_row form.username label_class field_class %}
     {% form_row form.username label_class field_class %}
 
 
     {% if 'rank' in form.fields %}
     {% if 'rank' in form.fields %}
-    {% form_row form.rank label_class field_class %}
+      {% form_row form.rank label_class field_class %}
     {% endif %}
     {% endif %}
 
 
     {% form_row form.title label_class field_class %}
     {% form_row form.title label_class field_class %}
     {% form_row form.roles label_class field_class %}
     {% form_row form.roles label_class field_class %}
 
 
     {% if 'staff_level' in form.fields %}
     {% if 'staff_level' in form.fields %}
-    {% form_row form.staff_level label_class field_class %}
+      {% form_row form.staff_level label_class field_class %}
+    {% endif %}
+
+  </fieldset>
+  <fieldset>
+    <legend>{% trans "Administrator status" %}</legend>
+
+    {% if 'is_staff' in form.fields %}
+      {% form_row form.is_staff label_class field_class %}
+      {% form_row form.is_superuser label_class field_class %}
+    {% else %}
+      <div id="div_id_is_staff" class="form-group">
+        <label for="id_is_staff_0" class="control-label {{ label_class }}">
+          {% trans "Is administrator" %}:
+        </label>
+        <div class="{{ field_class }}">
+          <p class="form-control-static">
+            {% if target.is_staff %}
+              <strong class="text-primary">{% trans "Yes" %}</strong>
+            {% else %}
+              <strong class="text-muted">{% trans "No" %}</strong>
+            {% endif %}
+          </p>
+          <p id="hint_id_is_staff" class="help-block">
+            {% trans "Designates whether the user can log into admin sites. If Django admin site is enabled, this user will need additional permissions assigned within it to admin Django modules." %}
+          </p>
+        </div>
+      </div>
+      <div id="div_id_is_superuser" class="form-group">
+        <label for="id_is_superuser_0" class="control-label {{ label_class }}">
+          {% trans "Is superuser" %}:
+        </label>
+        <div class="{{ field_class }}">
+          <p class="form-control-static">
+            {% if target.is_superuser %}
+              <strong class="text-primary">{% trans "Yes" %}</strong>
+            {% else %}
+              <strong class="text-muted">{% trans "No" %}</strong>
+            {% endif %}
+          </p>
+          <p id="hint_id_is_superuser" class="help-block">
+            {% trans "Only administrators can access admin sites. In addition to admin site access, superadmins can also change other members admin levels." %}
+          </p>
+        </div>
+      </div>
+      <p class="text-center">
+        <strong>{% trans "Note" %}:</strong>
+        {% trans "Only superusers can change other users administrator status." %}
+      </p>
     {% endif %}
     {% endif %}
 
 
   </fieldset>
   </fieldset>

+ 11 - 11
misago/users/forms/admin.py

@@ -204,21 +204,21 @@ def StaffFlagUserFormFactory(FormType, instance, add_staff_field):
     FormType = UserFormFactory(FormType, instance)
     FormType = UserFormFactory(FormType, instance)
 
 
     if add_staff_field:
     if add_staff_field:
-        staff_levels = (
-            (0, _("No access")),
-            (1, _("Administrator")),
-            (2, _("Superadmin")),
-        )
-
         staff_fields = {
         staff_fields = {
-            'staff_level': forms.TypedChoiceField(
-                label=_("Admin level"),
+            'is_staff': forms.YesNoSwitch(
+                label=_("Is administrator"),
+                help_text=_("Designates whether the user can log into admin sites. "
+                            "If Django admin site is enabled, this user will need "
+                            "additional permissions assigned within it to admin "
+                            "Django modules."),
+                initial=instance.is_staff
+            ),
+            'is_superuser': forms.YesNoSwitch(
+                label=_("Is superuser"),
                 help_text=_("Only administrators can access admin sites. "
                 help_text=_("Only administrators can access admin sites. "
                             "In addition to admin site access, superadmins "
                             "In addition to admin site access, superadmins "
                             "can also change other members admin levels."),
                             "can also change other members admin levels."),
-                coerce=int,
-                choices=staff_levels,
-                initial=instance.staff_level
+                initial=instance.is_superuser
             ),
             ),
         }
         }
 
 

+ 111 - 6
misago/users/tests/test_useradmin_views.py

@@ -16,6 +16,8 @@ from ..models import Ban, Rank
 
 
 
 
 class UserAdminViewsTests(AdminTestCase):
 class UserAdminViewsTests(AdminTestCase):
+    AJAX_HEADER = {'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'}
+
     def test_link_registered(self):
     def test_link_registered(self):
         """admin index view contains users link"""
         """admin index view contains users link"""
         response = self.client.get(reverse('misago:admin:index'))
         response = self.client.get(reverse('misago:admin:index'))
@@ -215,7 +217,110 @@ class UserAdminViewsTests(AdminTestCase):
         User.objects.get_by_username('Bawww')
         User.objects.get_by_username('Bawww')
         User.objects.get_by_email('reg@stered.com')
         User.objects.get_by_email('reg@stered.com')
 
 
-    ajax_header = {'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'}
+    def test_edit_make_admin(self):
+        """edit user view allows super admin to make other user admin"""
+        User = get_user_model()
+        test_user = User.objects.create_user('Bob', 'bob@test.com', 'pass123')
+        test_link = reverse('misago:admin:users:accounts:edit',
+                            kwargs={'pk': test_user.pk})
+
+        response = self.client.get(test_link)
+        self.assertContains(response, 'id="id_is_staff_1"')
+        self.assertContains(response, 'id="id_is_superuser_1"')
+
+        response = self.client.post(test_link, data={
+            'username': 'Bawww',
+            'rank': six.text_type(test_user.rank_id),
+            'roles': six.text_type(test_user.roles.all()[0].pk),
+            'email': 'reg@stered.com',
+            'new_password': 'pass123',
+            'is_staff': '1',
+            'is_superuser': '0',
+            'signature': 'Hello world!',
+            'is_signature_locked': '1',
+            'is_hiding_presence': '0',
+            'limits_private_thread_invites_to': '0',
+            'signature_lock_staff_message': 'Staff message',
+            'signature_lock_user_message': 'User message',
+            'subscribe_to_started_threads': '2',
+            'subscribe_to_replied_threads': '2',
+        })
+        self.assertEqual(response.status_code, 302)
+
+        updated_user = User.objects.get(pk=test_user.pk)
+        self.assertTrue(updated_user.is_staff)
+        self.assertFalse(updated_user.is_superuser)
+
+    def test_edit_make_superadmin_admin(self):
+        """edit user view allows super admin to make other user super admin"""
+        User = get_user_model()
+        test_user = User.objects.create_user('Bob', 'bob@test.com', 'pass123')
+        test_link = reverse('misago:admin:users:accounts:edit',
+                            kwargs={'pk': test_user.pk})
+
+        response = self.client.get(test_link)
+        self.assertContains(response, 'id="id_is_staff_1"')
+        self.assertContains(response, 'id="id_is_superuser_1"')
+
+        response = self.client.post(test_link, data={
+            'username': 'Bawww',
+            'rank': six.text_type(test_user.rank_id),
+            'roles': six.text_type(test_user.roles.all()[0].pk),
+            'email': 'reg@stered.com',
+            'new_password': 'pass123',
+            'is_staff': '0',
+            'is_superuser': '1',
+            'signature': 'Hello world!',
+            'is_signature_locked': '1',
+            'is_hiding_presence': '0',
+            'limits_private_thread_invites_to': '0',
+            'signature_lock_staff_message': 'Staff message',
+            'signature_lock_user_message': 'User message',
+            'subscribe_to_started_threads': '2',
+            'subscribe_to_replied_threads': '2',
+        })
+        self.assertEqual(response.status_code, 302)
+
+        updated_user = User.objects.get(pk=test_user.pk)
+        self.assertFalse(updated_user.is_staff)
+        self.assertTrue(updated_user.is_superuser)
+
+    def test_edit_cant_make_admin(self):
+        """edit user view forbids admins from making other admins"""
+        self.user.is_superuser = False
+        self.user.save()
+
+        User = get_user_model()
+        test_user = User.objects.create_user('Bob', 'bob@test.com', 'pass123')
+        test_link = reverse('misago:admin:users:accounts:edit',
+                            kwargs={'pk': test_user.pk})
+
+        response = self.client.get(test_link)
+        self.assertNotContains(response, 'id="id_is_staff_1"')
+        self.assertNotContains(response, 'id="id_is_superuser_1"')
+
+        response = self.client.post(test_link, data={
+            'username': 'Bawww',
+            'rank': six.text_type(test_user.rank_id),
+            'roles': six.text_type(test_user.roles.all()[0].pk),
+            'email': 'reg@stered.com',
+            'new_password': 'pass123',
+            'is_staff': '1',
+            'is_superuser': '1',
+            'signature': 'Hello world!',
+            'is_signature_locked': '1',
+            'is_hiding_presence': '0',
+            'limits_private_thread_invites_to': '0',
+            'signature_lock_staff_message': 'Staff message',
+            'signature_lock_user_message': 'User message',
+            'subscribe_to_started_threads': '2',
+            'subscribe_to_replied_threads': '2',
+        })
+        self.assertEqual(response.status_code, 302)
+
+        updated_user = User.objects.get(pk=test_user.pk)
+        self.assertFalse(updated_user.is_staff)
+        self.assertFalse(updated_user.is_superuser)
 
 
     def test_delete_threads_view(self):
     def test_delete_threads_view(self):
         """delete user threads view deletes threads"""
         """delete user threads view deletes threads"""
@@ -227,14 +332,14 @@ class UserAdminViewsTests(AdminTestCase):
         category = Category.objects.all_categories()[:1][0]
         category = Category.objects.all_categories()[:1][0]
         [post_thread(category, poster=test_user) for i in range(10)]
         [post_thread(category, poster=test_user) for i in range(10)]
 
 
-        response = self.client.post(test_link, **self.ajax_header)
+        response = self.client.post(test_link, **self.AJAX_HEADER)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
 
 
         response_dict = json.loads(smart_str(response.content))
         response_dict = json.loads(smart_str(response.content))
         self.assertEqual(response_dict['deleted_count'], 10)
         self.assertEqual(response_dict['deleted_count'], 10)
         self.assertFalse(response_dict['is_completed'])
         self.assertFalse(response_dict['is_completed'])
 
 
-        response = self.client.post(test_link, **self.ajax_header)
+        response = self.client.post(test_link, **self.AJAX_HEADER)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
 
 
         response_dict = json.loads(smart_str(response.content))
         response_dict = json.loads(smart_str(response.content))
@@ -252,14 +357,14 @@ class UserAdminViewsTests(AdminTestCase):
         thread = post_thread(category)
         thread = post_thread(category)
         [reply_thread(thread, poster=test_user) for i in range(10)]
         [reply_thread(thread, poster=test_user) for i in range(10)]
 
 
-        response = self.client.post(test_link, **self.ajax_header)
+        response = self.client.post(test_link, **self.AJAX_HEADER)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
 
 
         response_dict = json.loads(smart_str(response.content))
         response_dict = json.loads(smart_str(response.content))
         self.assertEqual(response_dict['deleted_count'], 10)
         self.assertEqual(response_dict['deleted_count'], 10)
         self.assertFalse(response_dict['is_completed'])
         self.assertFalse(response_dict['is_completed'])
 
 
-        response = self.client.post(test_link, **self.ajax_header)
+        response = self.client.post(test_link, **self.AJAX_HEADER)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
 
 
         response_dict = json.loads(smart_str(response.content))
         response_dict = json.loads(smart_str(response.content))
@@ -273,7 +378,7 @@ class UserAdminViewsTests(AdminTestCase):
         test_link = reverse('misago:admin:users:accounts:delete-account',
         test_link = reverse('misago:admin:users:accounts:delete-account',
                             kwargs={'pk': test_user.pk})
                             kwargs={'pk': test_user.pk})
 
 
-        response = self.client.post(test_link, **self.ajax_header)
+        response = self.client.post(test_link, **self.AJAX_HEADER)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
 
 
         response_dict = json.loads(smart_str(response.content))
         response_dict = json.loads(smart_str(response.content))

+ 9 - 10
misago/users/views/admin/users.py

@@ -98,12 +98,11 @@ class UsersList(UserAdmin, generic.ListView):
             queryset = User.objects.filter(pk__in=activated_users_pks)
             queryset = User.objects.filter(pk__in=activated_users_pks)
             queryset.update(requires_activation=ACTIVATION_REQUIRED_NONE)
             queryset.update(requires_activation=ACTIVATION_REQUIRED_NONE)
 
 
-            mail_subject = _("Your account on %(forum_name)s "
-                             "forums has been activated")
-            subject_formats = {'forum_name': settings.forum_name}
-            mail_subject = mail_subject % subject_formats
+            subject = _("Your account on %(forum_name)s forums has been activated")
+            mail_subject = subject % {
+                'forum_name': settings.forum_name
+            }
 
 
-            mail_subject = mail_subject
             mail_users(request, inactive_users, mail_subject,
             mail_users(request, inactive_users, mail_subject,
                        'misago/emails/activation/by_admin')
                        'misago/emails/activation/by_admin')
 
 
@@ -264,10 +263,9 @@ class EditUser(UserAdmin, generic.ModelFormView):
 
 
     def handle_form(self, form, request, target):
     def handle_form(self, form, request, target):
         target.username = target.old_username
         target.username = target.old_username
-
         if target.username != form.cleaned_data.get('username'):
         if target.username != form.cleaned_data.get('username'):
-            target.set_username(form.cleaned_data.get('username'),
-                                changed_by=request.user)
+            target.set_username(
+                form.cleaned_data.get('username'), changed_by=request.user)
 
 
         if form.cleaned_data.get('new_password'):
         if form.cleaned_data.get('new_password'):
             target.set_password(form.cleaned_data['new_password'])
             target.set_password(form.cleaned_data['new_password'])
@@ -285,8 +283,9 @@ class EditUser(UserAdmin, generic.ModelFormView):
             if not target.old_is_avatar_locked:
             if not target.old_is_avatar_locked:
                 set_dynamic_avatar(target)
                 set_dynamic_avatar(target)
 
 
-        if 'staff_level' in form.cleaned_data:
-            target.staff_level = form.cleaned_data['staff_level']
+        if 'is_staff' in form.fields and 'is_superuser' in form.fields:
+            target.is_staff = form.cleaned_data.get('is_staff')
+            target.is_superuser = form.cleaned_data.get('is_superuser')
 
 
         target.rank = form.cleaned_data.get('rank')
         target.rank = form.cleaned_data.get('rank')