|
1 | 1 | import weakref |
2 | 2 |
|
3 | | -from roundup import hyperdb, volatiledb |
| 3 | +from roundup import hyperdb |
4 | 4 |
|
5 | | -class PermissionClass(volatiledb.VolatileClass): |
6 | | - ''' Include the default attributes: |
7 | | - - name (String) |
8 | | - - classname (String) |
9 | | - - description (String) |
| 5 | +class Permission: |
| 6 | + ''' Defines a Permission with the attributes |
| 7 | + - name |
| 8 | + - description |
| 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 | 12 | locked to a particular class. That means there may be multiple |
13 | 13 | Permissions for the same name for different classes. |
14 | 14 | ''' |
15 | | - def __init__(self, db, classname, **properties): |
16 | | - """ set up the default properties |
17 | | - """ |
18 | | - if not properties.has_key('name'): |
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 | | - |
26 | | -class RoleClass(volatiledb.VolatileClass): |
27 | | - ''' Include the default attributes: |
28 | | - - name (String, key) |
29 | | - - description (String) |
30 | | - - permissions (PermissionClass Multilink) |
| 15 | + def __init__(self, name='', description='', klass=None): |
| 16 | + self.name = name |
| 17 | + self.description = description |
| 18 | + self.klass = klass |
| 19 | + |
| 20 | + def __repr__(self): |
| 21 | + return '<Permission 0x%x %r,%r>'%(id(self), self.name, self.klass) |
| 22 | + |
| 23 | +class Role: |
| 24 | + ''' Defines a Role with the attributes |
| 25 | + - name |
| 26 | + - description |
| 27 | + - permissions |
31 | 28 | ''' |
32 | | - def __init__(self, db, classname, **properties): |
33 | | - """ set up the default properties |
34 | | - """ |
35 | | - if not properties.has_key('name'): |
36 | | - properties['name'] = hyperdb.String() |
37 | | - if not properties.has_key('description'): |
38 | | - properties['description'] = hyperdb.String() |
39 | | - if not properties.has_key('permissions'): |
40 | | - properties['permissions'] = hyperdb.Multilink('permission') |
41 | | - volatiledb.VolatileClass.__init__(self, db, classname, **properties) |
42 | | - self.setkey('name') |
| 29 | + def __init__(self, name='', description='', permissions=None): |
| 30 | + self.name = name |
| 31 | + self.description = description |
| 32 | + if permissions is None: |
| 33 | + permissions = [] |
| 34 | + self.permissions = permissions |
| 35 | + |
| 36 | + def __repr__(self): |
| 37 | + return '<Role 0x%x %r,%r>'%(id(self), self.name, self.permissions) |
43 | 38 |
|
44 | 39 | class Security: |
45 | 40 | def __init__(self, db): |
46 | 41 | ''' Initialise the permission and role classes, and add in the |
47 | 42 | base roles (for admin user). |
48 | 43 | ''' |
49 | | - # use a weak ref to avoid circularity |
50 | | - self.db = weakref.proxy(db) |
| 44 | + self.db = weakref.proxy(db) # use a weak ref to avoid circularity |
51 | 45 |
|
52 | | - # create the permission class instance (we only need one)) |
53 | | - self.permission = PermissionClass(db, "permission") |
| 46 | + # permssions are mapped by name to a list of Permissions by class |
| 47 | + self.permission = {} |
54 | 48 |
|
55 | | - # create the role class instance (we only need one) |
56 | | - self.role = RoleClass(db, "role") |
| 49 | + # roles are mapped by name to the Role |
| 50 | + self.role = {} |
57 | 51 |
|
58 | 52 | # the default Roles |
59 | 53 | self.addRole(name="User", description="A regular user, no privs") |
@@ -82,35 +76,28 @@ def getPermission(self, permission, classname=None): |
82 | 76 |
|
83 | 77 | Raise ValueError if there is no exact match. |
84 | 78 | ''' |
85 | | - perm = self.db.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: |
| 79 | + if not self.permission.has_key(permission): |
93 | 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 | 86 | raise ValueError, 'No permission "%s" defined for "%s"'%(permission, |
95 | 87 | classname) |
96 | 88 |
|
97 | 89 | def hasPermission(self, permission, userid, classname=None): |
98 | 90 | ''' Look through all the Roles, and hence Permissions, and see if |
99 | 91 | "permission" is there for the specified classname. |
100 | | -
|
101 | 92 | ''' |
102 | 93 | roles = self.db.user.get(userid, 'roles') |
103 | 94 | if roles is None: |
104 | 95 | return 0 |
105 | 96 | for rolename in roles.split(','): |
106 | 97 | if not rolename: |
107 | 98 | continue |
108 | | - roleid = self.db.role.lookup(rolename) |
109 | | - for permissionid in self.db.role.get(roleid, 'permissions'): |
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: |
| 99 | + for perm in self.role[rolename].permissions: |
| 100 | + if perm.klass is None or perm.klass == classname: |
114 | 101 | return 1 |
115 | 102 | return 0 |
116 | 103 |
|
@@ -142,20 +129,22 @@ def addPermission(self, **propspec): |
142 | 129 | ''' Create a new Permission with the properties defined in |
143 | 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 | 136 | def addRole(self, **propspec): |
148 | 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 | 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) |
158 | | - permissions = self.db.role.get(roleid, 'permissions') |
159 | | - permissions.append(permissionid) |
160 | | - self.db.role.set(roleid, permissions=permissions) |
| 148 | + role = self.role[rolename] |
| 149 | + role.permissions.append(permission) |
161 | 150 |
|
0 commit comments