appypod-rattail/gen/wrappers/UserWrapper.py

195 lines
8 KiB
Python

# ------------------------------------------------------------------------------
from appy.gen.wrappers import AbstractWrapper
# ------------------------------------------------------------------------------
class UserWrapper(AbstractWrapper):
def showLogin(self):
'''When must we show the login field?'''
if self.o.isTemporary(): return 'edit'
return 'view'
def showName(self):
'''Name and first name, by default, are always shown.'''
return True
def showEmail(self):
'''In most cases, email is the login. Show the field only if it is not
the case.'''
email = self.email
return email and (email != self.login)
def showRoles(self):
'''Only the admin can view or edit roles.'''
return self.user.has_role('Manager')
def validateLogin(self, login):
'''Is this p_login valid?'''
# The login can't be the id of the whole site or "admin"
if login == 'admin':
return 'This username is reserved.' # XXX Translate
# Check that no user or group already uses this login.
if self.count('User', login=login) or self.count('Group', login=login):
return 'This login is already in use.' # XXX Translate
return True
def validatePassword(self, password):
'''Is this p_password valid?'''
# Password must be at least 5 chars length
if len(password) < 5:
return 'Passwords must contain at least 5 letters.' # XXX Translate
return True
def showPassword(self):
'''When must we show the 2 fields for entering a password ?'''
# When someone creates the user
if self.o.isTemporary(): return 'edit'
# When the user itself (which is Owner of the object representing him)
# wants to edit information about himself.
if self.user.has_role('Owner', self): return 'edit'
def getGrantableRoles(self):
'''Returns the list of roles that the admin can grant to a user.'''
res = []
for role in self.o.getProductConfig().grantableRoles:
res.append( (role, self.translate('role_%s' % role)) )
return res
def validate(self, new, errors):
'''Inter-field validation.'''
page = self.request.get('page', 'main')
if page == 'main':
if hasattr(new, 'password1') and (new.password1 != new.password2):
# XXX Translate
msg = 'Passwords do not match.'
errors.password1 = msg
errors.password2 = msg
return self._callCustom('validate', new, errors)
def onEdit(self, created):
self.title = self.firstName + ' ' + self.name
aclUsers = self.o.acl_users
login = self.login
if created:
# Create the corresponding Zope user
aclUsers._doAddUser(login, self.password1, self.roles, ())
zopeUser = aclUsers.getUser(login)
# Remove our own password copies
self.password1 = self.password2 = ''
from persistent.mapping import PersistentMapping
# The following dict will store, for every group, global roles
# granted to it.
zopeUser.groups = PersistentMapping()
else:
# Update roles at the Zope level.
zopeUser = aclUsers.getUserById(login)
zopeUser.roles = self.roles
# Update the password if the user has entered new ones.
rq = self.request
if rq.has_key('password1'):
tool = self.tool.o
zopeUser.__ = tool._encryptPassword(rq['password1'])
# Update the cookie value
tool._updateCookie(login, rq['password1'])
self.password1 = self.password2 = ''
# "self" must be owned by its Zope user.
if 'Owner' not in self.o.get_local_roles_for_userid(login):
self.o.manage_addLocalRoles(login, ('Owner',))
# If the user was created by an Anonymous, Anonymous can't stay Owner
# of the object.
if None in self.o.__ac_local_roles__:
del self.o.__ac_local_roles__[None]
return self._callCustom('onEdit', created)
def getZopeUser(self):
'''Gets the Zope user corresponding to this user.'''
return self.o.acl_users.getUser(self.login)
def onDelete(self):
'''Before deleting myself, I must delete the corresponding Zope user.'''
self.o.acl_users._doDelUsers([self.login])
self.log('User "%s" deleted.' % self.login)
# Call a custom "onDelete" if any.
return self._callCustom('onDelete')
# ------------------------------------------------------------------------------
try:
from AccessControl.PermissionRole import _what_not_even_god_should_do, \
rolesForPermissionOn
from Acquisition import aq_base
except ImportError:
pass # For those using Appy without Zope
class ZopeUserPatches:
'''This class is a fake one that defines Appy variants of some of Zope's
AccessControl.User methods. The idea is to implement the notion of group
of users.'''
def getRoles(self):
'''Returns the global roles that this user (or any of its groups)
possesses.'''
res = list(self.roles)
if 'Anonymous' not in res: res.append('Authenticated')
# Add group global roles
if not hasattr(aq_base(self), 'groups'): return res
for roles in self.groups.itervalues():
for role in roles:
if role not in res: res.append(role)
return res
def getRolesInContext(self, object):
'''Return the list of global and local (to p_object) roles granted to
this user (or to any of its groups).'''
if isinstance(object, AbstractWrapper): object = object.o
object = getattr(object, 'aq_inner', object)
# Start with user global roles
res = self.getRoles()
# Add local roles
localRoles = getattr(object, '__ac_local_roles__', None)
if not localRoles: return res
userId = self.getId()
groups = getattr(self, 'groups', ())
for id, roles in localRoles.iteritems():
if (id != userId) and (id not in groups): continue
for role in roles:
if role not in res: res.append(role)
return res
def allowed(self, object, object_roles=None):
'''Checks whether the user has access to p_object. The user (or one of
its groups) must have one of the roles in p_object_roles.'''
if object_roles is _what_not_even_god_should_do: return 0
# If "Anonymous" is among p_object_roles, grant access.
if (object_roles is None) or ('Anonymous' in object_roles): return 1
# If "Authenticated" is among p_object_roles, grant access if the user
# is not anonymous.
if 'Authenticated' in object_roles and \
(self.getUserName() != 'Anonymous User'):
if self._check_context(object): return 1
# Try first to grant access based on global user roles
for role in self.getRoles():
if role not in object_roles: continue
if self._check_context(object): return 1
return
# Try then to grant access based on local roles
innerObject = getattr(object, 'aq_inner', object)
localRoles = getattr(innerObject, '__ac_local_roles__', None)
if not localRoles: return
userId = self.getId()
groups = getattr(self, 'groups', ())
for id, roles in localRoles.iteritems():
if (id != userId) and (id not in groups): continue
for role in roles:
if role not in object_roles: continue
if self._check_context(object): return 1
return
try:
from AccessControl.User import SimpleUser
SimpleUser.getRoles = getRoles
SimpleUser.getRolesInContext = getRolesInContext
SimpleUser.allowed = allowed
except ImportError:
pass
# ------------------------------------------------------------------------------