Mercurial > p > roundup > code
comparison doc/security.txt @ 876:2ccfd7fa0099
Getting closer to a good framework.
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Wed, 17 Jul 2002 23:29:34 +0000 |
| parents | d19dd123bda2 |
| children | 7d41d4dae378 |
comparison
equal
deleted
inserted
replaced
| 875:d19dd123bda2 | 876:2ccfd7fa0099 |
|---|---|
| 1 =================== | 1 =================== |
| 2 Security Mechanisms | 2 Security Mechanisms |
| 3 =================== | 3 =================== |
| 4 | 4 |
| 5 :Version: $Revision: 1.9 $ | 5 :Version: $Revision: 1.10 $ |
| 6 | 6 |
| 7 Current situation | 7 Current situation |
| 8 ================= | 8 ================= |
| 9 | 9 |
| 10 Current logical controls: | 10 Current logical controls: |
| 172 - name (String, key) | 172 - name (String, key) |
| 173 - description (String) | 173 - description (String) |
| 174 - permissions (PermissionClass Multilink) | 174 - permissions (PermissionClass Multilink) |
| 175 ''' | 175 ''' |
| 176 | 176 |
| 177 def hasClassPermission(db, classname, permission, userid): | 177 class Security: |
| 178 ''' Look through all the Roles, and hence Permissions, and see if | 178 def __init__(self, db): |
| 179 "permission" is there for the specified classname. | 179 ''' Initialise the permission and role classes, and add in the |
| 180 | 180 base roles (for admin user). |
| 181 ''' | 181 ''' |
| 182 | 182 # use a weak ref to avoid circularity |
| 183 def hasNodePermission(db, classname, nodeid, userid, properties): | 183 self.db = weakref.proxy(db) |
| 184 ''' Check the named properties of the given node to see if the userid | 184 |
| 185 appears in them. If it does, then the user is granted this | 185 # create the permission class instance (we only need one)) |
| 186 permission check. | 186 self.permission = PermissionClass(db, "permission") |
| 187 | 187 |
| 188 'propspec' consists of a list of property names. The property | 188 # create the role class instance (we only need one) |
| 189 names must be the name of a property of classname, or a | 189 self.role = RoleClass(db, "role") |
| 190 KeyError is raised. That property must be a Link or Multilink | 190 |
| 191 property, or a TypeError is raised. | 191 # the default Roles |
| 192 | 192 self.addRole(name="User", description="A regular user, no privs") |
| 193 If the property is a Link, the userid must match the property | 193 self.addRole(name="Admin", description="An admin user, full privs") |
| 194 value. If the property is a Multilink, the userid must appear | 194 self.addRole(name="No Rego", |
| 195 in the Multilink list. | 195 description="A user who can't register") |
| 196 ''' | 196 |
| 197 ee = self.addPermission(name="Edit", | |
| 198 description="User may edit everthing") | |
| 199 self.addPermissionToRole('Admin', ee) | |
| 200 ae = self.addPermission(name="Assign", | |
| 201 description="User may be assigned to anything") | |
| 202 self.addPermissionToRole('Admin', ae) | |
| 203 | |
| 204 def hasClassPermission(self, db, classname, permission, userid): | |
| 205 ''' Look through all the Roles, and hence Permissions, and see if | |
| 206 "permission" is there for the specified classname. | |
| 207 | |
| 208 ''' | |
| 209 | |
| 210 def hasNodePermission(self, db, classname, nodeid, userid, properties): | |
| 211 ''' Check the named properties of the given node to see if the | |
| 212 userid appears in them. If it does, then the user is granted | |
| 213 this permission check. | |
| 214 | |
| 215 'propspec' consists of a list of property names. The property | |
| 216 names must be the name of a property of classname, or a | |
| 217 KeyError is raised. That property must be a Link or Multilink | |
| 218 property, or a TypeError is raised. | |
| 219 | |
| 220 If the property is a Link, the userid must match the property | |
| 221 value. If the property is a Multilink, the userid must appear | |
| 222 in the Multilink list. | |
| 223 ''' | |
| 224 | |
| 225 def addPermission(self, **propspec): | |
| 226 ''' Create a new Permission with the properties defined in | |
| 227 'propspec' | |
| 228 ''' | |
| 229 | |
| 230 def addRole(self, **propspec): | |
| 231 ''' Create a new Role with the properties defined in 'propspec' | |
| 232 ''' | |
| 233 | |
| 234 def addPermissionToRole(self, rolename, permissionid): | |
| 235 ''' Add the permission to the role's permission list. | |
| 236 | |
| 237 'rolename' is the name of the role to add 'permissionid'. | |
| 238 ''' | |
| 239 | |
| 240 Modules such as ``cgi_client.py`` and ``mailgw.py`` define their own | |
| 241 permissions like so (this example is ``cgi_client.py``):: | |
| 242 | |
| 243 # XXX GAH. If the permissions are instance-db-specific then this can't | |
| 244 # work! | |
| 245 from roundup import permission | |
| 246 | |
| 247 # create some Permissions | |
| 248 newid = permission.addPermission(name="Web Access", | |
| 249 description="User may use the web interface") | |
| 250 permission.addToRole('User', newid) | |
| 251 permission.addToRole('No Rego', newid) | |
| 252 newid = permission.addPermission(name="Web Registration", | |
| 253 description="User may register through the web") | |
| 254 permission.addToRole('User', newid) | |
| 255 # XXX GAH! | |
| 197 | 256 |
| 198 The instance dbinit module then has in ``open()``:: | 257 The instance dbinit module then has in ``open()``:: |
| 199 | 258 |
| 200 perm = permission.PermissionClass(db, "permission") | 259 # open the database - it must be modified to init the Security class |
| 201 role = permission.RoleClass(db, "role") | 260 # from permissions.py as db.security |
| 202 | 261 db = Database(instance_config, name) |
| 203 # create some Permissions | 262 |
| 204 wa = perm.create(name="Web Access", | 263 # add some extra permissions and associate them with roles |
| 205 description="User may use the web interface") | 264 ei = db.security.addPermission(name="Edit", classname="issue", |
| 206 wr = perm.create(name="Web Registration", | |
| 207 description="User may register through the web") | |
| 208 | |
| 209 ma = perm.create(name="Mail Access", | |
| 210 description="User may use the email interface") | |
| 211 mr = perm.create(name="Mail Registration", | |
| 212 description="User may register through email") | |
| 213 | |
| 214 ee = perm.create(name="Edit", | |
| 215 description="User may edit everthing") | |
| 216 ei = perm.create(name="Edit", classname="issue", | |
| 217 description="User is allowed to edit issues") | 265 description="User is allowed to edit issues") |
| 218 | 266 db.security.addPermissionToRole('User', ei) |
| 219 ae = perm.create(name="Assign", | 267 ai = db.security.addPermission(name="Assign", classname="issue", |
| 220 description="User may be assigned to anything") | |
| 221 ai = perm.create(name="Assign", classname="issue", | |
| 222 description="User may be assigned to issues") | 268 description="User may be assigned to issues") |
| 223 | 269 db.security.addPermissionToRole('User', ei) |
| 224 # create some Roles that use the Permissions | 270 |
| 225 role.create(name="User", description="A regular user, no privs", | 271 In the dbinit ``init()``:: |
| 226 permissions=[wa, wr, ma, mr, ei, ai]) | |
| 227 role.create(name="Admin", description="An admin user, full privs", | |
| 228 permissions=[ee, ae]) | |
| 229 role.create(name="No Rego", description="A user who can't register", | |
| 230 permissions=[wa, ma]) | |
| 231 | |
| 232 in ``init()``:: | |
| 233 | 272 |
| 234 r = db.getclass('role').lookup('Admin') | 273 r = db.getclass('role').lookup('Admin') |
| 235 user.create(username="admin", password=Password(adminpw), | 274 user.create(username="admin", password=Password(adminpw), |
| 236 address=instance_config.ADMIN_EMAIL, roles=[r]) | 275 address=instance_config.ADMIN_EMAIL, roles=[r]) |
| 237 | 276 |
| 241 user.create(username="anonymous", roles=[r]) | 280 user.create(username="anonymous", roles=[r]) |
| 242 | 281 |
| 243 Then in the code that matters, calls to ``hasPermission`` are made to | 282 Then in the code that matters, calls to ``hasPermission`` are made to |
| 244 determine if the user has permission to perform some action:: | 283 determine if the user has permission to perform some action:: |
| 245 | 284 |
| 246 if security.hasClassPermission('issue', 'Edit', self.user): | 285 if db.security.hasClassPermission('issue', 'Edit', self.user): |
| 247 # all ok | 286 # all ok |
| 248 | 287 |
| 249 if security.hasNodePermission('issue', nodeid, self.user, ['assignedto']): | 288 if db.security.hasNodePermission('issue', nodeid, self.user, |
| 289 ['assignedto']): | |
| 250 # all ok | 290 # all ok |
| 251 | 291 |
| 252 The htmltemplate will implement a new tag, <permission> which has the form:: | 292 The htmltemplate will implement a new tag, <permission> which has the form:: |
| 253 | 293 |
| 254 <permission require=name,name,name node=assignedto> | 294 <permission require=name,name,name node=assignedto> |
