[schema security] fix so that when cheking attributes perms for an entity being created, 'owners' and has_*_permission in erqlexpr are considered satisfied
--- a/schema.py Wed Feb 17 11:26:09 2010 +0100
+++ b/schema.py Wed Feb 17 12:21:28 2010 +0100
@@ -254,7 +254,9 @@
return
# if 'owners' in allowed groups, check if the user actually owns this
# object, if so that's enough
- if 'owners' in groups and 'eid' in kwargs and session.user.owns(kwargs['eid']):
+ if 'owners' in groups and (
+ kwargs.get('creating')
+ or ('eid' in kwargs and session.user.owns(kwargs['eid'])):
return
# else if there is some rql expressions, check them
if any(rqlexpr.check(session, **kwargs)
@@ -787,13 +789,19 @@
session may actually be a request as well
"""
- if self.eid is not None:
+ creating = kwargs.get('creating')
+ if not creating and self.eid is not None:
key = (self.eid, tuple(sorted(kwargs.iteritems())))
try:
return session.local_perm_cache[key]
except KeyError:
pass
rql, has_perm_defs, keyarg = self.transform_has_permission()
+ if creating:
+ # when creating an entity, consider has_*_permission satisfied
+ if has_perm_defs:
+ return True
+ return False
if keyarg is None:
# on the server side, use unsafe_execute, but this is not available
# on the client side (session is actually a request)
@@ -864,10 +872,13 @@
rql += ', U eid %(u)s'
return rql
- def check(self, session, eid=None):
+ def check(self, session, eid=None, creating=False):
if 'X' in self.rqlst.defined_vars:
if eid is None:
+ if creating:
+ return self._check(session, creating=True)
return False
+ assert creating == False
return self._check(session, x=eid)
return self._check(session)
--- a/web/uicfg.py Wed Feb 17 11:26:09 2010 +0100
+++ b/web/uicfg.py Wed Feb 17 12:21:28 2010 +0100
@@ -379,7 +379,8 @@
continue
rdef = rschema.role_rdef(eschema, tschema, role)
if rschema.final:
- if not rdef.has_perm(cw, permission, eid=eid):
+ if not rdef.has_perm(cw, permission, eid=eid,
+ creating=eid is None):
continue
elif strict or not rdef.has_local_role(relpermission):
if role == 'subject':