[Twisted-Python] Experiences with twisted.spread: representing an ACL

Glyph Lefkowitz glyph at twistedmatrix.com
Mon Jan 14 22:53:05 MST 2002


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/





More information about the Twisted-Python mailing list