Commit 96c5843c authored by Jim Fulton's avatar Jim Fulton

Rearranged permission user interface machinery, alot.

parent f9f9dbc0
"""Access control support""" """Access control support"""
__version__='$Revision: 1.16 $'[11:-2] __version__='$Revision: 1.17 $'[11:-2]
from Globals import HTMLFile, MessageDialog from Globals import HTMLFile, MessageDialog
from string import join, strip, split, find from string import join, strip, split, find
from Acquisition import Implicit from Acquisition import Implicit
import Globals import Globals
from Permission import Permission
ListType=type([])
class RoleManager: class RoleManager:
...@@ -17,24 +20,126 @@ class RoleManager: ...@@ -17,24 +20,126 @@ class RoleManager:
('Add properties', []), ('Add properties', []),
('Change properties', []), ('Change properties', []),
('Delete properties', []), ('Delete properties', []),
('Shared permission',['']),
) )
__ac_roles__=('Manager', 'Anonymous', 'Shared') __ac_roles__=('Manager', 'Anonymous')
def access_permissions(self): #------------------------------------------------------------
# Return list of permission objects
list=[]
for name,value in self.__ac_permissions__:
list.append(Permission(name,value,self))
return list
def access_permissions_dict(self): def permission_settings(self):
# Return dict of access permission objects result=[]
dict={} valid=self.valid_roles()
for name,value in self.__ac_permissions__: indexes=range(len(valid))
dict[name]=Permission(name,value,self) ip=0
return dict for p in self.__ac_permissions__:
name, value = p[:2]
p=Permission(name,value,self)
roles=p.getRoles()
d={'name': name,
'acquire': type(roles) is ListType and 'CHECKED' or '',
'roles': map(
lambda ir, roles=roles, valid=valid, ip=ip:
{
'name': "p%dr%d" % (ip,ir),
'checked': (valid[ir] in roles) and 'CHECKED' or '',
},
indexes)
}
ip=ip+1
result.append(d)
return result
manage_roleForm=HTMLFile('roleEdit', globals())
def manage_role(self, role_to_manage, permissions=[], REQUEST=None):
"Change the permissions given to the given role"
for p in self.__ac_permissions__:
name, value = p[:2]
p=Permission(name,value,self)
p.setRole(role_to_manage, name in permissions)
if REQUEST is not None: return self.manage_access(self,REQUEST)
manage_permissionForm=HTMLFile('permissionEdit', globals())
def manage_permission(self, permission_to_manage,
roles=[], acquire=0, REQUEST=None):
"Change the settings for the given permission"
for p in self.__ac_permissions__:
name, value = p[:2]
if name==permission_to_manage:
p=Permission(name,value,self)
if acquire: roles=list(roles)
else: roles=tuple(roles)
p.setRoles(roles)
if REQUEST is not None: return self.manage_access(self,REQUEST)
return
raise 'Invalid Permission', (
"The permission <em>%s</em> is invalid." % permission_to_manage)
manage_access=HTMLFile('access', globals())
def manage_changePermissions(self, REQUEST):
" "
valid_roles=self.valid_roles()
indexes=range(len(valid_roles))
have=REQUEST.has_key
permissions=self.__ac_permissions__
for ip in range(len(permissions)):
roles=[]
for ir in indexes:
if have("p%dr%d" % (ip,ir)): roles.append(valid_roles[ir])
name, value = permissions[ip][:2]
p=Permission(name,value,self)
if not have('a%d' % ip): roles=tuple(roles)
p.setRoles(roles)
return MessageDialog(
title ='Success!',
message='Your changes have been saved',
action ='manage_access')
def permissionsOfRole(self, role):
r=[]
for p in self.__ac_permissions__:
name, value = p[:2]
p=Permission(name,value,self)
roles=p.getRoles()
r.append({'name': name,
'selected': role in roles and 'SELECTED' or '',
})
return r
def rolesOfPermission(self, permission):
valid_roles=self.valid_roles()
for p in self.__ac_permissions__:
name, value = p[:2]
if name==permission:
p=Permission(name,value,self)
roles=p.getRoles()
return map(
lambda role, roles=roles:
{'name': role,
'selected': role in roles and 'SELECTED' or '',
},
valid_roles)
raise 'Invalid Permission', (
"The permission <em>%s</em> is invalid." % permission)
def acquiredRolesAreUsedBy(self, permission):
for p in self.__ac_permissions__:
name, value = p[:2]
if name==permission:
p=Permission(name,value,self)
roles=p.getRoles()
return type(roles) is ListType and 'CHECKED' or ''
raise 'Invalid Permission', (
"The permission <em>%s</em> is invalid." % permission)
#------------------------------------------------------------
def access_debug_info(self): def access_debug_info(self):
# Return debug info # Return debug info
...@@ -91,35 +196,9 @@ class RoleManager: ...@@ -91,35 +196,9 @@ class RoleManager:
except: pass except: pass
return roles return roles
_mainAccess=HTMLFile('mainAccess', globals())
_editAccess=HTMLFile('editAccess', globals())
_add_Access=HTMLFile('addAccess', globals())
_del_Access=HTMLFile('delAccess', globals())
def manage_access(self,submit=None,REQUEST=None): def manage_defined_roles(self,submit=None,REQUEST=None):
""" """ """ """
if submit=='Add...':
return self._add_Access(self, REQUEST)
if submit=='Edit':
return self._editAccess(self, REQUEST)
if submit=='Add':
roles =reqattr(REQUEST, 'roles')
permissions=reqattr(REQUEST, 'permissions')
return self._addAccess(roles, permissions, REQUEST)
if submit=='Change':
role =reqattr(REQUEST, 'role')
permissions=reqattr(REQUEST, 'permissions')
return self._changeAccess(role, permissions, REQUEST)
if submit=='Remove...':
return self._del_Access(self, REQUEST)
if submit=='Remove':
roles=reqattr(REQUEST, 'roles')
return self._delAccess(roles, REQUEST)
if submit=='Add Role': if submit=='Add Role':
role=reqattr(REQUEST, 'role') role=reqattr(REQUEST, 'role')
...@@ -129,64 +208,7 @@ class RoleManager: ...@@ -129,64 +208,7 @@ class RoleManager:
roles=reqattr(REQUEST, 'roles') roles=reqattr(REQUEST, 'roles')
return self._delRoles(roles, REQUEST) return self._delRoles(roles, REQUEST)
return self._mainAccess(self,REQUEST) return self.manage_access(self,REQUEST)
def _addAccess(self, roles, permissions, REQUEST):
if not roles or not permissions:
return MessageDialog(
title ='Incomplete',
message='You must specify roles and permissions',
action ='manage_access')
if not self.validate_roles(roles):
return MessageDialog(
title ='Undefined Role',
message='An undefined role was specified',
action ='manage_access')
dict=self.access_permissions_dict()
if 0 in map(dict.has_key, permissions):
return MessageDialog(
title ='Unknown permission',
message='An unknown permission was specified',
action ='manage_changeAccess')
for p in dict.values():
p.delRoles(roles)
for p in permissions:
dict[p].setRoles(roles)
return self._mainAccess(self, REQUEST)
def _changeAccess(self, role, permissions, REQUEST=None):
if not role or not permissions:
return MessageDialog(
title ='Incomplete',
message='You must specify roles and permissions',
action ='manage_access')
if not self.validate_roles([role]):
return MessageDialog(
title ='Undefined Role',
message='An undefined role was specified',
action ='manage_access')
dict=self.access_permissions_dict()
if 0 in map(dict.has_key, permissions):
return MessageDialog(
title ='Unknown permission',
message='An unknown permission was specified',
action ='manage_changeAccess')
for p in dict.values():
p.delRoles([role])
for p in permissions:
dict[p].setRoles([role])
return self._mainAccess(self, REQUEST)
def _delAccess(self, roles, REQUEST=None):
if not roles:
return MessageDialog(
title ='Incomplete',
message='You must specify roles to remove',
action ='manage_access')
dict=self.access_permissions_dict()
for p in dict.values():
p.delRoles(roles)
return self._mainAccess(self, REQUEST)
def _addRole(self, role, REQUEST=None): def _addRole(self, role, REQUEST=None):
if not role: if not role:
...@@ -202,7 +224,7 @@ class RoleManager: ...@@ -202,7 +224,7 @@ class RoleManager:
data=list(self.__ac_roles__) data=list(self.__ac_roles__)
data.append(role) data.append(role)
self.__ac_roles__=tuple(data) self.__ac_roles__=tuple(data)
return self._mainAccess(self, REQUEST) return self.manage_access(self, REQUEST)
def _delRoles(self, roles, REQUEST): def _delRoles(self, roles, REQUEST):
if not roles: if not roles:
...@@ -215,7 +237,7 @@ class RoleManager: ...@@ -215,7 +237,7 @@ class RoleManager:
try: data.remove(role) try: data.remove(role)
except: pass except: pass
self.__ac_roles__=tuple(data) self.__ac_roles__=tuple(data)
return self._mainAccess(self, REQUEST) return self.manage_access(self, REQUEST)
# Compatibility names only!! # Compatibility names only!!
...@@ -233,100 +255,6 @@ class RoleManager: ...@@ -233,100 +255,6 @@ class RoleManager:
Globals.default__class_init__(RoleManager) Globals.default__class_init__(RoleManager)
ListType=type([])
class Permission:
# A Permission maps a named logical permission to a set
# of attribute names. Attribute names which appear in a
# permission may not appear in any other permission defined
# by the object.
def __init__(self,name,data,obj):
self.name=name
self.data=data
if hasattr(obj, 'aq_self'):
obj=obj.aq_self
self.obj =obj
def getRoles(self):
# Return the list of role names which have been given
# this permission for the object in question. To do
# this, we try to get __roles__ from all of the object
# attributes that this permission represents.
name=self.data[0]
if name=='': attr=self.obj
else: attr=getattr(self.obj, name)
if hasattr(attr,'aq_self'): attr=attr.aq_self
if hasattr(attr, '__roles__'):
roles=attr.__roles__
if roles is None:
return ['Manager','Anonymous']
return roles
#return []
return ['Shared']
def setRoles(self, roles):
# Add the given list of role names to the appropriate
# subobjects for this permission. To do this, we add
# the given roles to the __roles__ of each attribute
# that this permission represents.
first=1
data=None
for name in self.data:
if name=='': attr=self.obj
else: attr=getattr(self.obj, name)
if hasattr(attr,'aq_self'):
attr=attr.aq_self
if first:
if hasattr(attr, '__roles__'):
data=attr.__roles__
if data is None: data=[]
else: data=list(data)
else: data=[]
for role in roles: data.append(role)
first=0
attr.__roles__=data
def delRoles(self, roles):
# Remove the given list of role names from the appropriate
# subobjects for this permission. To do this, we remove
# the given roles from the __roles__ of each attribute
# that this permission represents. If the __roles__ of any
# attribute is thus left empty, it is deleted.
first=1
data=None
for name in self.data:
if name=='': attr=self.obj
else: attr=getattr(self.obj, name)
if hasattr(attr,'aq_self'):
attr=attr.aq_self
if first:
if hasattr(attr, '__roles__'):
data=attr.__roles__
if data is None: data=[]
else: data=list(data)
else: data=['Shared']
for role in roles:
if role in data: data.remove(role)
first=0
attr.__roles__=data
def __len__(self): return 1
def __str__(self): return self.name
def absattr(attr):
if callable(attr): return attr()
return attr
def reqattr(request, attr): def reqattr(request, attr):
try: return request[attr] try: return request[attr]
except: return None except: return None
......
"""Access control package""" """Access control package"""
__version__='$Revision: 1.46 $'[11:-2] __version__='$Revision: 1.47 $'[11:-2]
from PersistentMapping import PersistentMapping from PersistentMapping import PersistentMapping
...@@ -25,30 +25,18 @@ class User(Implicit, Persistent): ...@@ -25,30 +25,18 @@ class User(Implicit, Persistent):
return password==self.__ return password==self.__
def allowed(self,parent,roles=None): def allowed(self,parent,roles=None):
obj=parent
obj_roles=roles
usr_roles=self.roles usr_roles=self.roles
while 1: if roles is None or 'Anonymous' in roles: return 1
if (obj_roles is None) or ('Anonymous' in obj_roles):
return 1 for role in roles:
for role in obj_roles: if role in usr_roles:
if role in usr_roles: if (hasattr(self,'aq_parent') and
return 1 hasattr(self.aq_parent,'aq_parent')):
if 'Shared' in obj_roles: if not parent.aq_inContextOf(self.aq_parent.aq_parent,1):
if obj is None: return 0 return None
if hasattr(obj, '__roles__'): return 1
obj_roles=obj.__roles__ return None
else:
obj_roles=['Shared',]
if hasattr(obj, 'aq_parent'):
obj=obj.aq_parent
elif hasattr(obj, 'im_self'):
obj=obj.im_self
else:
obj=None
continue
return 0
hasRole=allowed hasRole=allowed
...@@ -86,7 +74,6 @@ nobody=User('Anonymous User','',('Anonymous',)) ...@@ -86,7 +74,6 @@ nobody=User('Anonymous User','',('Anonymous',))
class UserFolder(Implicit, Persistent, Navigation, Tabs, RoleManager, class UserFolder(Implicit, Persistent, Navigation, Tabs, RoleManager,
Item, App.Undo.UndoSupport): Item, App.Undo.UndoSupport):
""" """ """ """
__roles__=['Manager','Shared']
meta_type='User Folder' meta_type='User Folder'
id ='acl_users' id ='acl_users'
...@@ -110,7 +97,6 @@ class UserFolder(Implicit, Persistent, Navigation, Tabs, RoleManager, ...@@ -110,7 +97,6 @@ class UserFolder(Implicit, Persistent, Navigation, Tabs, RoleManager,
('Undo changes', ['manage_undo_transactions']), ('Undo changes', ['manage_undo_transactions']),
('Change permissions', ['manage_access']), ('Change permissions', ['manage_access']),
('Manage users', ['manage_users']), ('Manage users', ['manage_users']),
('Shared permission', ['']),
) )
...@@ -157,6 +143,9 @@ class UserFolder(Implicit, Persistent, Navigation, Tabs, RoleManager, ...@@ -157,6 +143,9 @@ class UserFolder(Implicit, Persistent, Navigation, Tabs, RoleManager,
if not user.authenticate(password): if not user.authenticate(password):
return None return None
# We need the user to be able to acquire!
user=user.__of__(self)
# Try to authorize user # Try to authorize user
if user.hasRole(parent, roles): if user.hasRole(parent, roles):
return user return user
...@@ -187,11 +176,6 @@ class UserFolder(Implicit, Persistent, Navigation, Tabs, RoleManager, ...@@ -187,11 +176,6 @@ class UserFolder(Implicit, Persistent, Navigation, Tabs, RoleManager,
message='Password and confirmation do not match', message='Password and confirmation do not match',
action ='manage_main') action ='manage_main')
if not roles: roles=[] if not roles: roles=[]
if 'Shared' in roles:
return MessageDialog(
title ='Illegal value',
message='Shared is not a legal role name',
action ='manage_main')
self.data[name]=User(name,password,roles) self.data[name]=User(name,password,roles)
if REQUEST: return self._mainUser(self, REQUEST) if REQUEST: return self._mainUser(self, REQUEST)
...@@ -212,11 +196,6 @@ class UserFolder(Implicit, Persistent, Navigation, Tabs, RoleManager, ...@@ -212,11 +196,6 @@ class UserFolder(Implicit, Persistent, Navigation, Tabs, RoleManager,
message='Password and confirmation do not match', message='Password and confirmation do not match',
action ='manage_main') action ='manage_main')
if not roles: roles=[] if not roles: roles=[]
if 'Shared' in roles:
return MessageDialog(
title ='Illegal value',
message='Shared is not a legal role name',
action ='manage_main')
user=self.data[name] user=self.data[name]
user.__=password user.__=password
user.roles=roles user.roles=roles
...@@ -312,6 +291,9 @@ if _remote_user_mode: ...@@ -312,6 +291,9 @@ if _remote_user_mode:
try: user=self.data[name] try: user=self.data[name]
except: return None except: return None
# We need the user to be able to acquire!
user=user.__of__(self)
# Try to authorize user # Try to authorize user
if user.hasRole(parent, roles): if user.hasRole(parent, roles):
return user return user
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment