[gen] klass.creators can now be a method that either returns a list of global roles allowed to create instances of this class, or a boolean indicating if the currently logged user can create instances of this class or not. [gen] Bugfixes.

This commit is contained in:
Gaetan Delannay 2013-09-22 16:33:32 +02:00
parent e1b83574c5
commit 1f901e5545
6 changed files with 64 additions and 55 deletions

View file

@ -74,7 +74,7 @@ class Field:
# Displays a field label.
pxLabel = Px('''<label if="field.hasLabel and (field.type != 'Action')"
lfor="field.name">::zobj.translate('label', field=field)</label>''')
lfor=":field.name">::zobj.translate('label', field=field)</label>''')
# Displays a field description.
pxDescription = Px('''<span if="field.hasDescr"

View file

@ -185,14 +185,16 @@ class Transition:
# triggered if user has at least one of those roles and if all
# functions return True.
hasRole = None
for roleOrFunction in self.condition:
if isinstance(roleOrFunction, basestring):
for condition in self.condition:
# "Unwrap" role names from Role instances.
if isinstance(condition, Role): condition = condition.name
if isinstance(condition, basestring): # It is a role
if hasRole == None:
hasRole = False
if user.has_role(roleOrFunction, obj):
if user.has_role(condition, obj):
hasRole = True
elif type(roleOrFunction) == types.FunctionType:
if not roleOrFunction(wf, obj.appy()):
else: # It is a method
if not condition(wf, obj.appy()):
return False
if hasRole != False:
return True

View file

@ -158,17 +158,19 @@ class ClassDescriptor(Descriptor):
return res
def getCreators(self):
'''Gets the specific creators defined for this class.'''
'''Gets the specific creators defined for this class, excepted if
attribute "creators" does not contain a list or roles.'''
res = []
if self.klass.__dict__.has_key('creators') and self.klass.creators:
for creator in self.klass.creators:
if isinstance(creator, gen.Role):
if creator.local:
raise 'Local role "%s" cannot be used as a creator.' % \
creator.name
res.append(creator)
else:
res.append(gen.Role(creator))
if not hasattr(self.klass, 'creators'): return res
if not isinstance(self.klass.creators, list): return res
for creator in self.klass.creators:
if isinstance(creator, gen.Role):
if creator.local:
raise 'Local role "%s" cannot be used as a creator.' % \
creator.name
res.append(creator)
else:
res.append(gen.Role(creator))
return res
def getCreateMean(self, type='Import'):

View file

@ -501,7 +501,9 @@ class ZopeGenerator(Generator):
allRoles[role.name] = role
# Gather roles from "creators" attributes from every class
for cDescr in self.getClasses(include='all'):
for role in cDescr.getCreators():
creators = cDescr.getCreators()
if not creators: continue
for role in creators:
if role.name not in allRoles:
allRoles[role.name] = role
res = allRoles.values()

View file

@ -269,24 +269,18 @@ class ToolMixin(BaseMixin):
elems = sortMethod(elems)
return [importParams.headers, elems]
def showPortlet(self, context, layoutType):
'''When must the portlet be shown?'''
def showPortlet(self, obj, layoutType):
'''When must the portlet be shown? p_obj and p_layoutType can be None
if we are not browing any objet (ie, we are on the home page).'''
# Not on 'edit' pages.
if layoutType == 'edit': return
if context and (context.id == 'ui'): context = context.getParentNode()
res = True
if context and hasattr(context.aq_base, 'appy'):
appyObj = context.appy()
try:
res = appyObj.showPortlet()
except AttributeError:
res = True
if obj and hasattr(obj, 'showPortlet'):
res = obj.showPortlet()
else:
appyObj = self.appy()
try:
res = appyObj.showPortletAt(context)
except AttributeError:
res = True
tool = self.appy()
if hasattr(tool, 'showPortletAt'):
res = tool.showPortletAt(self.REQUEST['ACTUAL_URL'])
return res
def getObject(self, uid, appy=False, brain=False):
@ -300,23 +294,14 @@ class ToolMixin(BaseMixin):
return res.appy()
def getAllowedValue(self):
'''Gets, for the currently logged user, the value for index
"Allowed".'''
tool = self.appy()
'''Gets, for the current user, the value of index "Allowed".'''
user = self.getUser()
rq = tool.request
# Get the user roles
res = rq.userRoles
# Add role "Anonymous"
if 'Anonymous' not in res: res.append('Anonymous')
# Add the user id if not anonymous
userId = user.login
if userId != 'anon': res.append('user:%s' % userId)
# Add group ids
try:
res += ['user:%s' % g for g in rq.zopeUser.groups.keys()]
except AttributeError, ae:
pass # The Zope admin does not have this attribute.
res = user.getRoles()
# Get the user logins
if user.login != 'anon':
for login in user.getLogins():
res.append('user:%s' % login)
return res
def executeQuery(self, className, searchName=None, startNumber=0,
@ -499,21 +484,39 @@ class ToolMixin(BaseMixin):
res[means.id] = means
return res
def userMaySearch(self, rootClass):
'''May the logged user search among instances of p_rootClass ?'''
def userMaySearch(self, klass):
'''May the user search among instances of root p_klass ?'''
# When editing a form, one should avoid annoying the user with this.
url = self.REQUEST['ACTUAL_URL']
if url.endswith('/edit') or url.endswith('/do'): return
if 'maySearch' in rootClass.__dict__:
return pythonClass.rootClass(self.appy())
if hasattr(klass, 'maySearch'): return klass.maySearch(self.appy())
return True
def userMayCreate(self, klass):
'''May the logged user create instances of p_klass ?'''
allowedRoles = getattr(klass, 'creators', None) or \
self.getProductConfig().appConfig.defaultCreators
'''May the logged user create instances of p_klass ? This information
can be defined on p_klass, in static attribute "creators".
1. If this attr holds a list, we consider it to be a list of roles,
and we check that the user has at least one of those roles.
2. If this attr holds a boolean, we consider that the user can create
instances of this class if the boolean is True.
3. If this attr stores a method, we execute the method, and via its
result, we fall again in cases 1 or 2.
If p_klass does not define this attr "creators", we will use a
default list of roles as defined in the config.'''
# Get the value of attr "creators", or a default value if not present.
if hasattr(klass, 'creators'):
creators = klass.creators
else:
creators = self.getProductConfig().appConfig.defaultCreators
# Resolve case (3): if "creators" is a method, execute it.
if callable(creators): creators = creators(self.appy())
# Resolve case (2)
if isinstance(creators, bool) or not creators: return creators
# Resolve case (1): checks whether the user has at least one of the
# roles listed in "creators".
for role in self.getUser().getRoles():
if role in allowedRoles:
if role in creators:
return True
def onImportObjects(self):

View file

@ -91,7 +91,7 @@ class AbstractWrapper(object):
dummy=setattr(req, 'pxContext', _ctx_);
lang=ztool.getUserLanguage(); q=ztool.quote;
layoutType=ztool.getLayoutType();
showPortlet=ztool.showPortlet(zobj, layoutType);
showPortlet=ztool.showPortlet(obj, layoutType);
dir=ztool.getLanguageDirection(lang);
discreetLogin=ztool.getProductConfig(True).discreetLogin;
dleft=(dir == 'ltr') and 'left' or 'right';