You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by jo...@apache.org on 2013/10/03 19:14:08 UTC

[03/50] git commit: [#6392] ticket:432 Use ACE/ACL machinery instead of app_config attr

[#6392] ticket:432 Use ACE/ACL machinery instead of app_config attr


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/991f8bc2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/991f8bc2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/991f8bc2

Branch: refs/heads/cj/6422
Commit: 991f8bc2156ebd76132d72d84cf13caa4571621d
Parents: 9442d72
Author: Igor Bondarenko <je...@gmail.com>
Authored: Wed Sep 11 14:46:41 2013 +0300
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 24 17:36:24 2013 +0000

----------------------------------------------------------------------
 Allura/allura/app.py                            | 35 ++++++++++----------
 .../templates/admin_widgets/card_field.html     | 21 +++++-------
 .../ext/admin/templates/widgets/block_list.html | 24 ++++++++++++--
 .../ext/admin/templates/widgets/block_user.html | 26 ++++++++++++---
 Allura/allura/lib/security.py                   |  7 ++--
 Allura/allura/model/project.py                  |  1 -
 Allura/allura/model/types.py                    | 21 ++++++++++--
 .../allura/templates/app_admin_permissions.html |  3 +-
 Allura/allura/tests/functional/test_admin.py    |  2 +-
 9 files changed, 93 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/991f8bc2/Allura/allura/app.py
----------------------------------------------------------------------
diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index 029da32..8218d53 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -18,6 +18,7 @@
 import logging
 from urllib import basejoin
 from cStringIO import StringIO
+from collections import defaultdict
 
 from tg import expose, redirect, flash
 from tg.decorators import without_trailing_slash
@@ -583,21 +584,23 @@ class DefaultAdminController(BaseController):
         permanent_redirect('permissions')
 
     @expose()
-    def block_user(self, user_name, perm, reason=''):
-        user = model.User.by_username(user_name)
+    def block_user(self, username, perm, reason=None):
+        user = model.User.by_username(username)
         if not user:
-            flash('User "%s" not found' % user_name, 'error')
+            flash('User "%s" not found' % username, 'error')
             return redirect(request.referer)
 
-        if perm not in self.app.config.block_user:
-            self.app.config.block_user[perm] = dict()
-        if user._id not in self.app.config.block_user[perm]:
-            self.app.config.block_user[perm][str(user._id)] = reason
+        ace = model.ACE.deny(user.project_role()._id, perm, reason)
+        if ace not in self.app.acl:
+            self.app.acl.append(ace)
         return redirect(request.referer)
 
     @expose()
-    def unblock_user(self, user_id='', perm=''):
-        del self.app.config.block_user[perm][user_id]
+    def unblock_user(self, user_id, perm):
+        user = model.User.query.get(_id=ObjectId(user_id))
+        ace = model.ACE.deny(user.project_role()._id, perm)
+        if ace in self.app.acl:
+            self.app.acl.remove(ace)
         return redirect(request.referer)
 
     @expose('jinja:allura:templates/app_admin_permissions.html')
@@ -611,15 +614,7 @@ class DefaultAdminController(BaseController):
         c.block_user = BlockUser()
         c.block_list = BlockList()
         permissions = dict((p, []) for p in self.app.permissions)
-        block_list = {}
-
-        for perm, users in self.app.config.block_user.items():
-            users_id = [ObjectId(_id) for _id in users.keys()]
-            block_list[perm] = dict()
-            for user in model.User.query.find(dict(_id={'$in': users_id})):
-                block_list[perm][str(user._id)] = [user.username, users[str(user._id)]]
-
-
+        block_list = defaultdict(list)
         for ace in self.app.config.acl:
             if ace.access == model.ACE.ALLOW:
                 try:
@@ -627,6 +622,10 @@ class DefaultAdminController(BaseController):
                 except KeyError:
                     # old, unknown permission
                     pass
+            elif ace.access == model.ACE.DENY:
+                role = model.ProjectRole.query.get(_id=ace.role_id)
+                if role.name is None and role.user:
+                    block_list[ace.permission].append((role.user, getattr(ace, 'reason', None)))
         return dict(
             app=self.app,
             allow_config=has_access(c.project, 'admin')(),

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/991f8bc2/Allura/allura/ext/admin/templates/admin_widgets/card_field.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/admin_widgets/card_field.html b/Allura/allura/ext/admin/templates/admin_widgets/card_field.html
index fa958af..964ea65 100644
--- a/Allura/allura/ext/admin/templates/admin_widgets/card_field.html
+++ b/Allura/allura/ext/admin/templates/admin_widgets/card_field.html
@@ -72,22 +72,17 @@
         </a>
     </li>
 
-    {%if (name in block_list) and (block_list[name])%}
-        <li>
-        <a href="#" class="block-list">
-            Block list
+    {% if block_list.get(name) %}
+      <li>
+        <a href="#" class="block-list">Block List</a>
         <div class="block-list grid-13" style="display: none">
           <ul>
-          {%for user_id in block_list[name].keys()%}
-            <li>
-                <input type="checkbox" name="user_id" value="{{user_id}}">{{block_list[name][user_id][0]}} ({{block_list[name][user_id][1]}})
-
-            </li>
-          {%endfor%}
+          {% for u, reason in block_list[name] %}
+            <li><input type="checkbox" name="user_id" value="{{ u._id }}">{{ u.username }} {{ '(' + reason + ')' if reason else '' }}</li>
+          {% endfor %}
           </ul>
         </div>
-        </a>
-        </li>
-    {%endif%}
+      </li>
+    {% endif %}
   </ul>
 </div>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/991f8bc2/Allura/allura/ext/admin/templates/widgets/block_list.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/widgets/block_list.html b/Allura/allura/ext/admin/templates/widgets/block_list.html
index 9f3e7f3..85ff03a 100644
--- a/Allura/allura/ext/admin/templates/widgets/block_list.html
+++ b/Allura/allura/ext/admin/templates/widgets/block_list.html
@@ -1,9 +1,27 @@
+{#-
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+-#}
 <h1>Block list</h1>
-<form action="unblock_user">
+<form action="unblock_user" method="POST">
 <div class="model-block-list"></div>
 <input type="hidden" class="block_user_role" name="perm" value="">
 <div class="grid-13">&nbsp;</div>
 <hr>
-<div class="grid-13"><div class="grid-13">&nbsp;</div>
+<div class="grid-13">&nbsp;</div>
 <input type="submit" value="Delete">
-</form>
\ No newline at end of file
+</form>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/991f8bc2/Allura/allura/ext/admin/templates/widgets/block_user.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/widgets/block_user.html b/Allura/allura/ext/admin/templates/widgets/block_user.html
index d6ea3a6..9f087c3 100644
--- a/Allura/allura/ext/admin/templates/widgets/block_user.html
+++ b/Allura/allura/ext/admin/templates/widgets/block_user.html
@@ -1,13 +1,31 @@
+{#-
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+-#}
 <h1>Block User</h1>
-<form action="block_user">
+<form action="block_user" method="POST">
     <label class="grid-13">User Name</label>
-    <input type="text" id="block_user" name="user_name" class="grid-13">
+    <input type="text" id="block_user" name="username" class="grid-13">
     <label class="grid-13">Reason</label>
     <textarea class="grid-13" name="reason"></textarea>
     <input type="hidden" class="block_user_role" name="perm" value="">
     <div class="grid-13">&nbsp;</div>
     <hr>
-    <div class="grid-13"><div class="grid-13">&nbsp;</div>
+    <div class="grid-13">&nbsp;</div>
     <input type="submit" value="Save">
-    <a href="#" class="close">Cancel</a></div>
+    <a href="#" class="close">Cancel</a>
 </form>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/991f8bc2/Allura/allura/lib/security.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/security.py b/Allura/allura/lib/security.py
index fd20542..c992cef 100644
--- a/Allura/allura/lib/security.py
+++ b/Allura/allura/lib/security.py
@@ -290,10 +290,11 @@ def has_access(obj, permission, user=None, project=None):
                     project = getattr(obj, 'project', None) or c.project
                     project = project.root_project
             roles = cred.user_roles(user_id=user._id, project_id=project._id).reaching_ids
-        chainable_roles = []
-        block_user = getattr(obj, 'block_user', dict())
-        if (permission in block_user) and (str(user._id) in block_user[permission]):
+        user_role = user.project_role(project=project)
+        deny_user = M.ACE.deny(user_role._id, permission)
+        if deny_user in obj.acl:
             return False
+        chainable_roles = []
         for rid in roles:
             for ace in obj.acl:
                 if M.ACE.match(ace, rid, permission):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/991f8bc2/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 88b9d5a..ec39157 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -942,7 +942,6 @@ class AppConfig(MappedClass):
     tool_data = FieldProperty({str:{str:None}}) # entry point: prefs dict
 
     acl = FieldProperty(ACL())
-    block_user = FieldProperty({str: {str: str}})
 
     def get_tool_data(self, tool, key, default=None):
         return self.tool_data.get(tool, {}).get(key, default)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/991f8bc2/Allura/allura/model/types.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/types.py b/Allura/allura/model/types.py
index 0dd8150..fa7b332 100644
--- a/Allura/allura/model/types.py
+++ b/Allura/allura/model/types.py
@@ -43,11 +43,14 @@ class ACE(S.Object):
             permission=permission)
 
     @classmethod
-    def deny(cls, role_id, permission):
-        return Object(
+    def deny(cls, role_id, permission, reason=None):
+        ace = Object(
             access=cls.DENY,
             role_id=role_id,
             permission=permission)
+        if reason:
+            ace.reason = reason
+        return ace
 
     @classmethod
     def match(cls, ace, role_id, permission):
@@ -61,4 +64,18 @@ class ACL(S.Array):
         super(ACL, self).__init__(
             field_type=ACE(permissions), **kwargs)
 
+        def __contains__(self, ace):
+            """Test membership of ace in acl ignoring ace.reason field.
+
+            e.g. `ace in acl` test should evaluate to True with following vars:
+
+            ace = M.ACE.deny(role_id, 'read')
+            acl = [{role_id=ObjectId(...), permission='read', access='DENY', reason='Spammer'}]
+            """
+            def clear_reason(ace):
+                return Object(access=ace.access, role_id=ace.role_id, permission=ace.permission)
+
+            ace = Object(access=ace.access, role_id=ace.role_id, permission=ace.permission)
+            return ace in map(clear_reason, self)
+
 DENY_ALL = ACE.deny(EVERYONE, ALL_PERMISSIONS)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/991f8bc2/Allura/allura/templates/app_admin_permissions.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/app_admin_permissions.html b/Allura/allura/templates/app_admin_permissions.html
index 6a7bd61..69000f8 100644
--- a/Allura/allura/templates/app_admin_permissions.html
+++ b/Allura/allura/templates/app_admin_permissions.html
@@ -72,7 +72,7 @@
       $('input.block_user_role').val(role);
   });
   $('a.block-list').click(function(){
-      var userlist = $(this).find('div.block-list').clone();
+      var userlist = $(this).siblings('div.block-list').clone();
       var deck =  $(this).closest('ul.deck');
       var role = deck.find('li.tcenter h3').text();
       $('input.block_user_role').val(role);
@@ -80,4 +80,3 @@
   });
 </script>
 {% endblock %}
-

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/991f8bc2/Allura/allura/tests/functional/test_admin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_admin.py b/Allura/allura/tests/functional/test_admin.py
index 24cf292..007746a 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -164,7 +164,7 @@ class TestProjectAdmin(TestController):
 
         # Check the audit log
         r = self.app.get('/admin/audit/')
-        assert "uninstall tool test-tool" in r.body, r.bodyt
+        assert "uninstall tool test-tool" in r.body, r.body
 
     @td.with_wiki
     def test_add_user_to_block_list(self):