Pastebin

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
diff --git Allura/allura/tests/test_security.py Allura/allura/tests/test_security.py
index 0ac8658..9d12e40 100644
--- Allura/allura/tests/test_security.py
+++ Allura/allura/tests/test_security.py
@@ -27,6 +27,11 @@
 from forgewiki import model as WM


+def _allow(obj, role, perm):
+    obj.acl.insert(0, M.ACE.allow(role._id, perm))
+    ThreadLocalODMSession.flush_all()
+    Credentials.get().clear()
+
 def _deny(obj, role, perm):
     obj.acl.insert(0, M.ACE.deny(role._id, perm))
     ThreadLocalODMSession.flush_all()
@@ -89,23 +94,23 @@ def test_all_allowed(self):
         assert_equal(all_allowed(wiki, test_user), set(['read', 'create', 'edit', 'post']))

     @td.with_wiki
-    def test_weird_allow_vs_deny(self):
+    def test_deny_vs_allow(self):
         '''
-        Test weird interaction of DENYs and ALLOWs in has_access.
+        Test interaction of DENYs and ALLOWs in has_access.
         '''
         wiki = c.project.app_instance('wiki')
         page = WM.Page.query.get(app_config_id=wiki.config._id)
+        anon_role = M.ProjectRole.by_name('*anonymous')
         auth_role = M.ProjectRole.by_name('*authenticated')
         test_user = M.User.by_username('test-user')


-        # DENY for auth_role on page prevents chaining of auth_role for 'read'
-        # but anon_role still chains so ALLOW read for anon_role on wiki applies
-        # and authed user can still read.  'post' and 'unmoderated_post' don't
-        # match DENY rule so they chain as normal.
-        #
-        # This behavior seems wrong and should probably be fixed at some point,
-        # but this test is here to confirm that all_allowed matches has_access.
+        # confirm that *anon has expected access
+        assert has_access(page, 'read', anon_role)()
+        assert has_access(page, 'post', anon_role)()
+        assert has_access(page, 'unmoderated_post', anon_role)()
+        assert_equal(all_allowed(page, anon_role), set(['read']))
+        # as well as an authenticated user
         assert has_access(page, 'read', test_user)()
         assert has_access(page, 'post', test_user)()
         assert has_access(page, 'unmoderated_post', test_user)()
@@ -113,26 +118,25 @@ def test_weird_allow_vs_deny(self):

         _deny(page, auth_role, 'read')

-        assert has_access(page, 'read', test_user)()
+        # read granted to *anon should *not* bubble up past the *auth DENY
+        assert not has_access(page, 'read', test_user)()
+        # but other perms should not be affected
         assert has_access(page, 'post', test_user)()
         assert has_access(page, 'unmoderated_post', test_user)()
-        assert_equal(all_allowed(page, test_user), set(['read', 'post', 'unmoderated_post']))
+        assert_equal(all_allowed(page, test_user), set(['post', 'unmoderated_post']))


-        # Same thing applies to ALLOW vs DENY on the same ACL;
-        # an ALLOW on any applicable role overrides a DENY on any other.
-        #
-        # In this case it's reasonable since you might want to DENY read for
-        # *anon but ALLOW it for *auth.  *anon ALLOW overriding *auth DENY is
-        # just an unfortunate side-effect of not having a true heiarchy of roles.
         assert has_access(wiki, 'read', test_user)()
         assert has_access(wiki, 'post', test_user)()
         assert has_access(wiki, 'unmoderated_post', test_user)()
         assert_equal(all_allowed(wiki, test_user), set(['read', 'post', 'unmoderated_post']))

-        _deny(wiki, auth_role, 'read')
+        _deny(wiki, anon_role, 'read')
+        _allow(wiki, auth_role, 'read')

-        assert has_access(wiki, 'read', test_user)()
+        # there isn't a true heiarchy of roles, so any applicable DENY
+        # will block a user, even if there's an explicit ALLOW "higher up"
+        assert not has_access(wiki, 'read', test_user)()
         assert has_access(wiki, 'post', test_user)()
         assert has_access(wiki, 'unmoderated_post', test_user)()
         assert_equal(all_allowed(wiki, test_user), set(['read', 'post', 'unmoderated_post']))