[Zope-PTK] LoginManger Usage (was Re: Status of LoginManager)

Phillip J. Eby pje@telecommunity.com
Wed, 08 Mar 2000 09:02:39 -0500


At 08:09 PM 3/7/00 -0800, John Eikenberry wrote:
>
>I'll have a folder (probably the acl_users folder) containing User
>Zclasses.  With a propertysheet containing the username, passwd, etc. Plus
>a few methods for accessing other relevant data. 
>
>So the LoginManager will use getUser() to get the User ZClass instance
>from this folder and then the User ZClass will handle getting the roles,
>domains, etc. Once authenticated, this User ZClass instance will get
>placed in the AUTHENTICATED_USER variable to provide access to the methods
>on the instance. 
>
>Now from what I can tell from the sources, I'm going to need to implement
>my own UserSource.  Based on the documentation, I shouldn't need to define
>rolesForUser(), domainsForUser() and authenticateUser() on my UserSource
>as these will be defined on the User ZClass. So it will just need the 
>getUser() method and mabey a caching system for efficiency. 
>
>The handling of passing the requests for roles, domains and authentication
>will automatically be passed though to the User ZClass. And the User
>ZClass instance will automatically be put into the AUTHENTICATED_USER
>variable... right?
>
>Does this all sound right? Am I overlooking something or making this too
>hard.

I think you've got it right.  We are planning to create a
PersistentUserSource (aka PUS) which will do almost exactly what you
described, but there are a bunch of things we need to finish first, like
SheetProviders and the PlugIn framework.

(The rest of this message has nothing to do with your question, it's just
babble about what we're doing with the LM code from here...)


By the way, LoginManager is about to undergo another round of internal
mutations to support a new pattern framework we call PlugIns.  These
changes should mostly only affect the procedure for registering new
UserSource and LoginMethod *classes*.  However, if you're doing deep voodoo
with LoginManager then other things may be affected.  Basically, we're
changing things so that both UserSources and LoginMethods register with
their LoginManager by way of a "registerPlugIn" method.  This will result
in a lot less duplication of code, and make it easier for us to add a
sophisticated SheetProvider plugin framework, as well as being able to
reuse the PlugIn framework for other projects we have in the pipeline.

The PlugIn framework allows classes to be registered as members of "PlugIn
Kinds", allowing their instances to be added to objects which support that
kind of plugin.  For example, LoginMethod subclasses would register in the
"LoginMethod" kind, and LoginManagers will support adding such subclasses.
LoginManager itself will be a PlugInContainer, which will allow plugins to
register with it when added.

PlugInContainer objects use PlugInGroup objects to keep track of the
PlugIns that are of a particular Kind.  PlugInContainers will support a
simple event mechanism to broadcast events of interest to its PlugInGroups,
which will interpret and/or relay these events on behalf of their kind of
plugins.  This will let us do things like add SheetProviders to a
LoginManager and automatically notify all of the UserSources of the
availability of the SheetProvider, as well as allowing SheetProviders to
tell UserSources when they have changed what they provide.

The other internal change to LoginManager is that we are going to make
UserSources more clearly derive from Racks, and begin moving more code from
the BasicUserSource to the Rack abstract class.  Thus, it will be possible
to make other kinds of containers that like UserSource, maintain a
collection of objects which can be provided with propertysheets and other
behavior, and which can specify what class will be used to implement the
objects.

This has many spin-offs.  It will in fact be an actual skeleton
implementation of the "Rack" pattern I presented at the Python Conference.
LoginManager is already an example of the "Implementor" pattern, although
it is not in reusable form yet.  We will be trying to break out any true
Implementor abstractions into a base class also, although right now the
only thing that seems to be reusable for Implementor generally is the fact
that all Implementors are both PlugIns and PlugInContainers which support
plugin kinds "implementor", "rack", and "sheet provider".

At the time of the conference, all of the patterns Ty and I had identified
were just an analysis of systems that I'd created in the past synthesized
into a working theory of how to write good Zope frameworks.  The
LoginManager project has worked out fantastically as far as showing how
easy it is to take a set of framework requirements and actually build it
using the RIPP pattern language.  I think we made Mike P. a little worried
at first, because I don't think Ty or I have ever successfully explained to
anyone else how RIPP works.  But when we reach a "1.0" on LoginManager,
there will be code not only for the first two key patterns (Rack and
Implementor) as abstract bases, but also an example application of the
pattern.  Specifically, LoginManager as an Implementor of the LoginUser
abstract type, and UserSources as Racks of specific LoginUser implementations.

Hopefully, it will then be ripe for a follow-up paper explaining at least
those two patterns in terms of code that folks can see and touch and use.
And perhaps another paper on the PlugIns mini-pattern...