Mercurial > p > roundup > code
view roundup/security.py @ 902:b0d3d3535998
Bugger it. Here's the current shape of the new security implementation.
Still to do:
. call the security funcs from cgi and mailgw
. change shipped templates to include correct initialisation and remove
the old config vars
... that seems like a lot. The bulk of the work has been done though. Honest :)
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Thu, 25 Jul 2002 07:14:06 +0000 |
| parents | |
| children | 502a5ae11cc5 |
line wrap: on
line source
import weakref from roundup import hyperdb, volatiledb class PermissionClass(volatiledb.VolatileClass): ''' Include the default attributes: - name (String) - classname (String) - description (String) The classname may be unset, indicating that this permission is not locked to a particular class. That means there may be multiple Permissions for the same name for different classes. ''' def __init__(self, db, classname, **properties): """ set up the default properties """ if not properties.has_key('name'): properties['name'] = hyperdb.String() if not properties.has_key('klass'): properties['klass'] = hyperdb.String() if not properties.has_key('description'): properties['description'] = hyperdb.String() volatiledb.VolatileClass.__init__(self, db, classname, **properties) class RoleClass(volatiledb.VolatileClass): ''' Include the default attributes: - name (String, key) - description (String) - permissions (PermissionClass Multilink) ''' def __init__(self, db, classname, **properties): """ set up the default properties """ if not properties.has_key('name'): properties['name'] = hyperdb.String() if not properties.has_key('description'): properties['description'] = hyperdb.String() if not properties.has_key('permissions'): properties['permissions'] = hyperdb.Multilink('permission') volatiledb.VolatileClass.__init__(self, db, classname, **properties) self.setkey('name') class Security: def __init__(self, db): ''' Initialise the permission and role classes, and add in the base roles (for admin user). ''' # use a weak ref to avoid circularity self.db = weakref.proxy(db) # create the permission class instance (we only need one)) self.permission = PermissionClass(db, "permission") # create the role class instance (we only need one) self.role = RoleClass(db, "role") # the default Roles self.addRole(name="User", description="A regular user, no privs") self.addRole(name="Admin", description="An admin user, full privs") self.addRole(name="Anonymous", description="An anonymous user") ee = self.addPermission(name="Edit", description="User may edit everthing") self.addPermissionToRole('Admin', ee) ae = self.addPermission(name="Access", description="User may access everything") self.addPermissionToRole('Admin', ae) ae = self.addPermission(name="Assign", description="User may be assigned to anything") self.addPermissionToRole('Admin', ae) reg = self.addPermission(name="Register Web", description="User may register through the web") self.addPermissionToRole('Anonymous', reg) reg = self.addPermission(name="Register Email", description="User may register through the email") self.addPermissionToRole('Anonymous', reg) # initialise the permissions and roles needed for the UIs from roundup import cgi_client, mailgw cgi_client.initialiseSecurity(self) mailgw.initialiseSecurity(self) def hasClassPermission(self, classname, permission, userid): ''' Look through all the Roles, and hence Permissions, and see if "permission" is there for the specified classname. ''' roles = self.db.user.get(userid, 'roles') for roleid in roles: for permissionid in self.db.role.get(roleid, 'permissions'): if self.db.permission.get(permissionid, 'name') != permission: continue klass = self.db.permission.get(permissionid, 'klass') if klass is None or klass == classname: return 1 return 0 def hasNodePermission(self, classname, nodeid, **propspec): ''' Check the named properties of the given node to see if the userid appears in them. If it does, then the user is granted this permission check. 'propspec' consists of a set of properties and values that must be present on the given node for access to be granted. If a property is a Link, the value must match the property value. If a property is a Multilink, the value must appear in the Multilink list. ''' klass = self.db.getclass(classname) properties = klass.getprops() for k,v in propspec.items(): value = klass.get(nodeid, k) if isinstance(properties[k], hyperdb.Multilink): if v not in value: return 0 else: if v != value: return 0 return 1 def addPermission(self, **propspec): ''' Create a new Permission with the properties defined in 'propspec' ''' return self.db.permission.create(**propspec) def addRole(self, **propspec): ''' Create a new Role with the properties defined in 'propspec' ''' return self.db.role.create(**propspec) def addPermissionToRole(self, rolename, permissionid): ''' Add the permission to the role's permission list. 'rolename' is the name of the role to add 'permissionid'. ''' roleid = self.db.role.lookup(rolename) permissions = self.db.role.get(roleid, 'permissions') permissions.append(permissionid) self.db.role.set(roleid, permissions=permissions)
