comparison roundup/security.py @ 908:a8d80ffe37cc

Removed the unnecessary volatiledb and the related complications. Security much simpler and self-contained now.
author Richard Jones <richard@users.sourceforge.net>
date Mon, 29 Jul 2002 00:56:06 +0000
parents 502a5ae11cc5
children ef9c759c243e
comparison
equal deleted inserted replaced
907:38a74d1351c5 908:a8d80ffe37cc
1 import weakref 1 import weakref
2 2
3 from roundup import hyperdb, volatiledb 3 from roundup import hyperdb
4 4
5 class PermissionClass(volatiledb.VolatileClass): 5 class Permission:
6 ''' Include the default attributes: 6 ''' Defines a Permission with the attributes
7 - name (String) 7 - name
8 - classname (String) 8 - description
9 - description (String) 9 - klass (optional)
10 10
11 The classname may be unset, indicating that this permission is not 11 The klass may be unset, indicating that this permission is not
12 locked to a particular class. That means there may be multiple 12 locked to a particular class. That means there may be multiple
13 Permissions for the same name for different classes. 13 Permissions for the same name for different classes.
14 ''' 14 '''
15 def __init__(self, db, classname, **properties): 15 def __init__(self, name='', description='', klass=None):
16 """ set up the default properties 16 self.name = name
17 """ 17 self.description = description
18 if not properties.has_key('name'): 18 self.klass = klass
19 properties['name'] = hyperdb.String()
20 if not properties.has_key('klass'):
21 properties['klass'] = hyperdb.String()
22 if not properties.has_key('description'):
23 properties['description'] = hyperdb.String()
24 volatiledb.VolatileClass.__init__(self, db, classname, **properties)
25 19
26 class RoleClass(volatiledb.VolatileClass): 20 def __repr__(self):
27 ''' Include the default attributes: 21 return '<Permission 0x%x %r,%r>'%(id(self), self.name, self.klass)
28 - name (String, key) 22
29 - description (String) 23 class Role:
30 - permissions (PermissionClass Multilink) 24 ''' Defines a Role with the attributes
25 - name
26 - description
27 - permissions
31 ''' 28 '''
32 def __init__(self, db, classname, **properties): 29 def __init__(self, name='', description='', permissions=None):
33 """ set up the default properties 30 self.name = name
34 """ 31 self.description = description
35 if not properties.has_key('name'): 32 if permissions is None:
36 properties['name'] = hyperdb.String() 33 permissions = []
37 if not properties.has_key('description'): 34 self.permissions = permissions
38 properties['description'] = hyperdb.String() 35
39 if not properties.has_key('permissions'): 36 def __repr__(self):
40 properties['permissions'] = hyperdb.Multilink('permission') 37 return '<Role 0x%x %r,%r>'%(id(self), self.name, self.permissions)
41 volatiledb.VolatileClass.__init__(self, db, classname, **properties)
42 self.setkey('name')
43 38
44 class Security: 39 class Security:
45 def __init__(self, db): 40 def __init__(self, db):
46 ''' Initialise the permission and role classes, and add in the 41 ''' Initialise the permission and role classes, and add in the
47 base roles (for admin user). 42 base roles (for admin user).
48 ''' 43 '''
49 # use a weak ref to avoid circularity 44 self.db = weakref.proxy(db) # use a weak ref to avoid circularity
50 self.db = weakref.proxy(db)
51 45
52 # create the permission class instance (we only need one)) 46 # permssions are mapped by name to a list of Permissions by class
53 self.permission = PermissionClass(db, "permission") 47 self.permission = {}
54 48
55 # create the role class instance (we only need one) 49 # roles are mapped by name to the Role
56 self.role = RoleClass(db, "role") 50 self.role = {}
57 51
58 # the default Roles 52 # the default Roles
59 self.addRole(name="User", description="A regular user, no privs") 53 self.addRole(name="User", description="A regular user, no privs")
60 self.addRole(name="Admin", description="An admin user, full privs") 54 self.addRole(name="Admin", description="An admin user, full privs")
61 self.addRole(name="Anonymous", description="An anonymous user") 55 self.addRole(name="Anonymous", description="An anonymous user")
80 ''' Find the Permission matching the name and for the class, if the 74 ''' Find the Permission matching the name and for the class, if the
81 classname is specified. 75 classname is specified.
82 76
83 Raise ValueError if there is no exact match. 77 Raise ValueError if there is no exact match.
84 ''' 78 '''
85 perm = self.db.permission 79 if not self.permission.has_key(permission):
86 for permissionid in perm.stringFind(name=permission):
87 klass = perm.get(permissionid, 'klass')
88 if classname is not None and classname == klass:
89 return permissionid
90 elif not classname and not klass:
91 return permissionid
92 if not classname:
93 raise ValueError, 'No permission "%s" defined'%permission 80 raise ValueError, 'No permission "%s" defined'%permission
81 for perm in self.permission[permission]:
82 if perm.klass is not None and perm.klass == classname:
83 return perm
84 elif not perm.klass and not classname:
85 return perm
94 raise ValueError, 'No permission "%s" defined for "%s"'%(permission, 86 raise ValueError, 'No permission "%s" defined for "%s"'%(permission,
95 classname) 87 classname)
96 88
97 def hasPermission(self, permission, userid, classname=None): 89 def hasPermission(self, permission, userid, classname=None):
98 ''' Look through all the Roles, and hence Permissions, and see if 90 ''' Look through all the Roles, and hence Permissions, and see if
99 "permission" is there for the specified classname. 91 "permission" is there for the specified classname.
100
101 ''' 92 '''
102 roles = self.db.user.get(userid, 'roles') 93 roles = self.db.user.get(userid, 'roles')
103 if roles is None: 94 if roles is None:
104 return 0 95 return 0
105 for rolename in roles.split(','): 96 for rolename in roles.split(','):
106 if not rolename: 97 if not rolename:
107 continue 98 continue
108 roleid = self.db.role.lookup(rolename) 99 for perm in self.role[rolename].permissions:
109 for permissionid in self.db.role.get(roleid, 'permissions'): 100 if perm.klass is None or perm.klass == classname:
110 if self.db.permission.get(permissionid, 'name') != permission:
111 continue
112 klass = self.db.permission.get(permissionid, 'klass')
113 if klass is None or klass == classname:
114 return 1 101 return 1
115 return 0 102 return 0
116 103
117 def hasNodePermission(self, classname, nodeid, **propspec): 104 def hasNodePermission(self, classname, nodeid, **propspec):
118 ''' Check the named properties of the given node to see if the 105 ''' Check the named properties of the given node to see if the
140 127
141 def addPermission(self, **propspec): 128 def addPermission(self, **propspec):
142 ''' Create a new Permission with the properties defined in 129 ''' Create a new Permission with the properties defined in
143 'propspec' 130 'propspec'
144 ''' 131 '''
145 return self.db.permission.create(**propspec) 132 perm = Permission(**propspec)
133 self.permission.setdefault(perm.name, []).append(perm)
134 return perm
146 135
147 def addRole(self, **propspec): 136 def addRole(self, **propspec):
148 ''' Create a new Role with the properties defined in 'propspec' 137 ''' Create a new Role with the properties defined in 'propspec'
149 ''' 138 '''
150 return self.db.role.create(**propspec) 139 role = Role(**propspec)
140 self.role[role.name] = role
141 return role
151 142
152 def addPermissionToRole(self, rolename, permissionid): 143 def addPermissionToRole(self, rolename, permission):
153 ''' Add the permission to the role's permission list. 144 ''' Add the permission to the role's permission list.
154 145
155 'rolename' is the name of the role to add 'permissionid'. 146 'rolename' is the name of the role to add the permission to.
156 ''' 147 '''
157 roleid = self.db.role.lookup(rolename) 148 role = self.role[rolename]
158 permissions = self.db.role.get(roleid, 'permissions') 149 role.permissions.append(permission)
159 permissions.append(permissionid)
160 self.db.role.set(roleid, permissions=permissions)
161 150

Roundup Issue Tracker: http://roundup-tracker.org/