Fix #923 - add allow_admin to user_has_privilege decorator
authorJessica Tallon <jessica@megworld.co.uk>
Fri, 25 Jul 2014 17:58:57 +0000 (18:58 +0100)
committerJessica Tallon <jessica@megworld.co.uk>
Tue, 29 Jul 2014 19:29:02 +0000 (20:29 +0100)
mediagoblin/db/models.py
mediagoblin/decorators.py
mediagoblin/templates/mediagoblin/base.html
mediagoblin/templates/mediagoblin/moderation/user.html
mediagoblin/tests/test_modelmethods.py

index c2d101ac0abb273883f439c3095d65d92e82de8d..c6424e71f129d26644b371c9c506b7fbc0c8a396 100644 (file)
@@ -106,25 +106,26 @@ class User(Base, UserMixin):
         super(User, self).delete(**kwargs)
         _log.info('Deleted user "{0}" account'.format(self.username))
 
-    def has_privilege(self,*priv_names):
+    def has_privilege(self, privilege, allow_admin=True):
         """
         This method checks to make sure a user has all the correct privileges
         to access a piece of content.
 
-        :param  priv_names      A variable number of unicode objects which rep-
-                                -resent the different privileges which may give
-                                the user access to this content. If you pass
-                                multiple arguments, the user will be granted
-                                access if they have ANY of the privileges
-                                passed.
+        :param  privilege       A unicode object which represent the different
+                                privileges which may give the user access to
+                                content.
+
+        :param  allow_admin     If this is set to True the then if the user is
+                                an admin, then this will always return True
+                                even if the user hasn't been given the
+                                privilege. (defaults to True)
         """
-        if len(priv_names) == 1:
-            priv = Privilege.query.filter(
-                Privilege.privilege_name==priv_names[0]).one()
-            return (priv in self.all_privileges)
-        elif len(priv_names) > 1:
-            return self.has_privilege(priv_names[0]) or \
-                self.has_privilege(*priv_names[1:])
+        priv = Privilege.query.filter_by(privilege_name=privilege).one()
+        if priv in self.all_privileges:
+            return True
+        elif allow_admin and self.has_privilege(u'admin', allow_admin=False):
+            return True
+
         return False
 
     def is_banned(self):
index 90edf96bdb001304e88347e2155d483675c22061..5bf60048bf5196d09a1fff49a956eba1f0f4e586 100644 (file)
@@ -74,7 +74,7 @@ def require_active_login(controller):
     return new_controller_func
 
 
-def user_has_privilege(privilege_name):
+def user_has_privilege(privilege_name, allow_admin=True):
     """
     Requires that a user have a particular privilege in order to access a page.
     In order to require that a user have multiple privileges, use this
@@ -85,14 +85,17 @@ def user_has_privilege(privilege_name):
                                         the privilege object. This object is
                                         the name of the privilege, as assigned
                                         in the Privilege.privilege_name column
+
+        :param allow_admin          If this is true then if the user is an admin
+                                    it will allow the user even if the user doesn't
+                                    have the privilage given in privilage_name.
     """
 
     def user_has_privilege_decorator(controller):
         @wraps(controller)
         @require_active_login
         def wrapper(request, *args, **kwargs):
-            user_id = request.user.id
-            if not request.user.has_privilege(privilege_name):
+            if not request.user.has_privilege(privilege_name, allow_admin):
                 raise Forbidden()
 
             return controller(request, *args, **kwargs)
@@ -369,7 +372,8 @@ def require_admin_or_moderator_login(controller):
     @wraps(controller)
     def new_controller_func(request, *args, **kwargs):
         if request.user and \
-            not request.user.has_privilege(u'admin',u'moderator'):
+            not (request.user.has_privilege(u'admin')
+                or request.user.has_privilege(u'moderator')):
 
             raise Forbidden()
         elif not request.user:
index 63a2a6ff0bc0b33489ee01af3461d282a2339ca5..13cfb47ba66586a5afd6fd5e76ab12791fa67fd3 100644 (file)
@@ -72,8 +72,8 @@
             </div>
             <div class="header_right">
               {%- if request.user %}
-                {% if request.user and 
-                      request.user.has_privilege('active') and 
+                {% if request.user and
+                      request.user.has_privilege('active') and
                       not request.user.is_banned() %}
 
                   {% set notification_count = get_notification_count(request.user.id) %}
                   {%- trans %}Create new collection{% endtrans -%}
                 </a>
                 {% template_hook("header_dropdown_buttons") %}
-                {% if request.user.has_privilege('admin','moderator') %}
+                {% if request.user.has_privilege('moderator') %}
                   <p>
                     <span class="dropdown_title">{% trans %}Moderation powers:{% endtrans %}</span>
                     <a href="{{ request.urlgen('mediagoblin.moderation.media_panel') }}">
index 37e7eee9521321b2ca7fcdef67155bceffc245b3..594f845d1b9a218073100eec01359cab1cc04665 100644 (file)
         {% for privilege in privileges %}
           <tr>
             <td>{{ privilege.privilege_name }}</td>
-            {% if privilege in user.all_privileges  %}
+            {% if user.has_privilege(privilege.privilege_name) %}
               <td class="user_with_privilege">
                 {% trans %}Yes{% endtrans %}{% else %}
               <td class="user_without_privilege">
             </td>
             {% if request.user.has_privilege('admin') %}
               <td>
-                {% if privilege in user.all_privileges  %}
+                {% if user.has_privilege(privilege.privilege_name) %}
                 <input type=submit id="{{ privilege.privilege_name }}"
                        class="submit_button button_action"
                        value =" -" />
index ca436c764645f45917d769f70be1691cbfdde7a8..32d5dce08a70170294ac5f7eec5c2e691028789a 100644 (file)
@@ -179,20 +179,17 @@ class TestUserHasPrivilege:
         self._setup()
 
         # then test out the user.has_privilege method for one privilege
-        assert not self.natalie_user.has_privilege(u'commenter')
-        assert self.aeva_user.has_privilege(u'active')
+        assert not self.aeva_user.has_privilege(u'admin')
+        assert self.natalie_user.has_privilege(u'active')
 
-
-    def test_user_has_privileges_multiple(self, test_app):
+    def test_allow_admin(self, test_app):
         self._setup()
 
-        # when multiple args are passed to has_privilege,  the method returns
-        # True if the user has ANY of the privileges
-        assert self.natalie_user.has_privilege(u'admin',u'commenter')
-        assert self.aeva_user.has_privilege(u'moderator',u'active')
-        assert not self.natalie_user.has_privilege(u'commenter',u'uploader')
-
+        # This should work because she is an admin.
+        assert self.natalie_user.has_privilege(u'commenter')
 
+        # Test that we can look this out ignoring that she's an admin
+        assert not self.natalie_user.has_privilege(u'commenter', allow_admin=False)
 
 def test_media_data_init(test_app):
     Session.rollback()