[Twisted-Python] Experiences with twisted.spread: representing an ACL
I am working on a networked backup server which is so new it doesn't even have a project page up on SF yet, although it might by the end of the week. To build this I am using spread and passport instead of building my own protocol. I'm having trouble with some of the concepts in spread, and at this point I'm still too naive to know whether I'm missing the point of something or whether passport is actually missing something I need. I want to implement access control lists. For each Identity, I want to assign a simple list of strings which more or less represent the ability to access a Perspective. For example: useracl=[ "store_files", "read_files", "encrypt", "create_lbu" ] There is a StoreFilesService, a ReadFilesService, and a CreateLBUService, and a Perspective for each. The "encrypt" permission is a modifier to Store and Read files, so I'm not sure how to implement that yet but I'll cross that bridge when I come to it. I have subclassed the Authorizer thus: class Authorizer(passport.Authorizer): def addIdentity(self, identity): if self.identities.has_key(identity.name): raise passport.KeyError("Already have an identity by that name.") self.identities[identity.name] = identity if identity.permissions == None: raise MissingPermissionsException(identity) # create all perspectives the user should have for permission in identity.acl: svc=servicelist.services[permission](permission, tap.the_app) svc.createPerspective(identity.name).setIdentity(identity) identity.addKeyForPerspective(svc.getPerspectiveNamed(identity.name)) Does passport already has something like the ACL mechanism which allows you to easily bind an ACL to a user? Is my solution the most parsimonious or do I really have to subclass the Authorizer to achieve this? It seems like I should be able to throw in a callback somewhere that creates the eligible service/perspective pairs when a user is added to the system. Second, if I modify a user's ACL, for example to grant a permission, where's the callback to create a new s/p pair for that permission? I have a suspicion that this is already taken care of somewhere in passport and I'm just missing the point. That's all for now, thanks. C __________________________________________________ Do You Yahoo!? Send FREE video emails in Yahoo! Mail! http://promo.yahoo.com/videomail/
First of all, let me apologize for not having documented this stuff more thoroughly. I'm glad you're making an effort to use this infrastructure, and please have the patience to help me complete it -- I need use-cases like yours to make the system more general. Passport is in the process of a major overhaul, to make it possible to store perspectives in a database. This is changing some of the basic APIs, so some of the answers to this (and your other thread) will be a bit vague. On Mon, 2002-01-14 at 23:13, Cory Dodt wrote:
I am working on a networked backup server which is so new it doesn't even have a project page up on SF yet, although it might by the end of the week. To build this I am using spread and passport instead of building my own protocol. I'm having trouble with some of the concepts in spread, and at this point I'm still too naive to know whether I'm missing the point of something or whether passport is actually missing something I need.
Passport has what you need, but it's different than you think, I think.
I want to implement access control lists. For each Identity, I want to assign a simple list of strings which more or less represent the ability to access a Perspective. For example:
useracl=[ "store_files", "read_files", "encrypt", "create_lbu" ]
There is a StoreFilesService, a ReadFilesService, and a CreateLBUService, and a Perspective for each. The "encrypt" permission is a modifier to Store and Read files, so I'm not sure how to implement that yet but I'll cross that bridge when I come to it.
If you have an ACL, implement it as an ACL. A perspective is a conglomeration of state for a particular service. If storing files, reading files, and creating LBUs all access the same repository of data, and all exist within an encapsulation boundary of some kind, they should probably all be one service that glues them together.
I have subclassed the Authorizer thus:
class Authorizer(passport.Authorizer): def addIdentity(self, identity): if self.identities.has_key(identity.name): raise passport.KeyError("Already have an identity by that name.") self.identities[identity.name] = identity if identity.permissions == None: raise MissingPermissionsException(identity) # create all perspectives the user should have for permission in identity.acl: svc=servicelist.services[permission](permission, tap.the_app) svc.createPerspective(identity.name).setIdentity(identity)
identity.addKeyForPerspective(svc.getPerspectiveNamed(identity.name))
Does passport already has something like the ACL mechanism which allows you to easily bind an ACL to a user? Is my solution the most parsimonious or do I really have to subclass the Authorizer to achieve this? It seems like I should be able to throw in a callback somewhere that creates the eligible service/perspective pairs when a user is added to the system.
It looks here like you want to add state (and potentially behavior) to Identity, which is not its purpose. The goal of the Identity/Passport distinction is to provide a very sharp boundary between different sorts of functionality (for example, a chat system and your backup software) but allow your users to have access to each. The reason you would add stuff to Identity is to add a new kind of authentication mechanism, for example, or to store them in an LDAP data repository. A perspective is a capability, not an ACL. An identity should be nothing more than an index of all perspectives available to a particular authentication token. Any information about or behavior for that identity is "application specific" can be reflected in a Perspective attached to it. Rather than trying to cram each operation into a Perspective of its own, you could just implement your ACLs internal to the Perspective, and test them with perspective.hasAbilityTo("some acl")... an implementation of a generalized, database-backed ACL system would be pretty handy, if you felt like contributing such a thing to Twisted :).
Second, if I modify a user's ACL, for example to grant a permission, where's the callback to create a new s/p pair for that permission? I have a suspicion that this is already taken care of somewhere in passport and I'm just missing the point.
Service.createPerspective is the current way to do that. -- ______ you are in a maze of twisted little applications, all | |_\ remarkably consistent. | | -- glyph lefkowitz, glyph @ twisted matrix . com |_____| http://www.twistedmatrix.com/
participants (2)
-
Cory Dodt
-
Glyph Lefkowitz