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"> </div>
<hr>
-<div class="grid-13"><div class="grid-13"> </div>
+<div class="grid-13"> </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"> </div>
<hr>
- <div class="grid-13"><div class="grid-13"> </div>
+ <div class="grid-13"> </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):