Skip to content

Commit

Permalink
Merge 86ccf81 into c2ac0b3
Browse files Browse the repository at this point in the history
  • Loading branch information
vangheem committed Jun 8, 2018
2 parents c2ac0b3 + 86ccf81 commit 652b3f8
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 5 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.rst
@@ -1,3 +1,10 @@
2.5.13 (unreleased)
-------------------

- Fix use of AllowSingle when overriding permissions
[vangheem]


2.5.12 (2018-04-02)
-------------------

Expand Down
21 changes: 16 additions & 5 deletions guillotina/security/policy.py
Expand Up @@ -55,7 +55,9 @@
def level_setting_as_boolean(level, value):
# We want to check if its allow
let = SettingAsBoolean[value]
return let == level if type(let) is str else let
# Never return False on AllowSingle
# If level is not o Allow single should not be taken care
return level == let or None if type(let) is str else let


class CacheEntry:
Expand Down Expand Up @@ -212,9 +214,16 @@ def cached_principal_permission(
cache = self.cache(parent)

try:
cache_prin = cache.prin
# We need to caches for first level and Allow Single
if level == 'o':
cache_prin = cache.prino
else:
cache_prin = cache.prin
except AttributeError:
cache_prin = cache.prin = {}
if level == 'o':
cache_prin = cache.prino = {}
else:
cache_prin = cache.prin = {}

cache_prin_per = cache_prin.get(principal)
if not cache_prin_per:
Expand Down Expand Up @@ -259,9 +268,11 @@ def cached_principal_permission(
level,
prinper_map.get_setting(permission, group, None))
if prinper is not None:
continue
# Once we conclude we exit
# May happen that first group Deny and second
# allows which will result on Deny for the first
break
if prinper is not None:
cache_prin_per[permission] = prinper
return prinper

# Find the permission recursivelly set to a user
Expand Down
65 changes: 65 additions & 0 deletions guillotina/tests/test_security.py
@@ -1,3 +1,4 @@
from guillotina.auth.users import GuillotinaUser
from guillotina.security.utils import get_principals_with_access_content
from guillotina.security.utils import get_roles_with_access_content
from guillotina.security.utils import settings_for_object
Expand Down Expand Up @@ -169,3 +170,67 @@ async def test_canido(container_requester):
'GET', '/db/guillotina/@canido?permission=guillotina.ViewContent')
assert status == 200
assert response


async def test_allowsingle(container_requester):
async with container_requester as requester:
response, status = await requester(
'POST',
'/db/guillotina/',
data=json.dumps({
'@type': 'Item',
'id': 'testing'
}))
assert status == 201

response, status = await requester(
'POST',
'/db/guillotina/@sharing',
data=json.dumps({
'prinperm': [{
'principal': 'group1',
'permission': 'guillotina.AccessContent',
'setting': 'AllowSingle'
}]
}))

assert status == 200

response, status = await requester(
'POST',
'/db/guillotina/testing/@sharing',
data=json.dumps({
'prinperm': [{
'principal': 'group2',
'permission': 'guillotina.AccessContent',
'setting': 'Allow'
}]
}))

assert status == 200

request = utils.get_mocked_request(requester.db)
container = await utils.get_container(requester, request)
content = await container.async_get('testing')

user = GuillotinaUser(request)
user.id = 'user1'
user._groups = ['group1', 'group2']

utils.login(request, user)

assert request.security.check_permission('guillotina.AccessContent',
request.container)
assert request.security.check_permission('guillotina.AccessContent',
content)

user = GuillotinaUser(request)
user.id = 'user2'
user._groups = ['group1']

utils.login(request, user)

assert request.security.check_permission('guillotina.AccessContent',
request.container)
assert not request.security.check_permission(
'guillotina.AccessContent', content)

0 comments on commit 652b3f8

Please sign in to comment.