LoginManager API

  Both User Sources and Login Methods must be implemented as PlugIns
  (class Products.ZPatterns.PlugIns.PlugIn) of the appropriate
  __plugin_kind__ ("User Source" or "Login Method").  They should also
  be derived from the base classes UserSources.BasicUserSource and
  LoginMethods.LoginMethod, respectively.


  The Login Process

    XXX Document REQUEST.LOGIN_METHODS, forbiddenPage, loginForm, logoutForm, GUS here

  UserSource

    UserSources are 'plugged in' to a LoginManager by instantiating
    one in the LoginManager.  The UserSource's manage_afterAdd method
    will register the UserSource with the LoginManager.
    (manage_beforeDelete performs the inverse operation.)

    API

      A UserSource is required to implement the following methods:

        o retrieveItem(self, name)

          Find or construct and return the user object corresponding
          to 'name'.  If not found, return None.

      Technically, retrieveItem is the only method that is required. If you
      know that your User class implements any of the following
      itself, then the US doesn't have to. But normally, the US will
      have to implement these.

        o rolesForUser(self, user)

	  Return a list of the names of the roles 'user' has.  'user'
	  will be an actual user object.

	o domainsForUser(self, user)

	  Return a list of domains, hosts, hostname patterns and IP
       	  addresses that 'user', a user object, is allowed to log in
       	  from.

        o authenticateUser(self, user, password, request)

	  This is called by the user object's authenticate method.
	  This returns a python truth value, with true indicating
	  successful authentication.  'user' is a user object, and
	  'request' is the actual REQUEST.


  LoginMethod

    LoginMethods are also instantiated in LoginManagers.  A
    LoginManager may have any number of LoginMethods.  The
    LoginManager maintains a list defining the order the LoginMethods
    are tried in, which the user may reorder.

    API

      A LoginMethod is required to implement the following methods:

        o findLogin(self, manager, request, auth, user, roles)

	  findLogin is called by the LoginManager's validate method.
	  It is passed the LoginManager which called it, the web
	  REQUEST, and the auth string passed to validate.  It is
	  expected to examine the request and/or auth string to
	  identify a potential user, fetch that user from the
	  UserStore (via manager) and ask that user to authenticate
	  itself with the information it extracted from request/auth.

	  If successful, it is to return the user object.  Otherwise,
	  it returns None.

	  If this is not the first LoginMethod the LoginManager has
	  tried, 'user' will be the result of the previous LoginMethod.
	  This allows specialty LMs to veto previous ones, or implement
	  some kind of voting, or stuff extra data into the user
	  object, etc.  LoginManagers which are not interested in such
	  things should immediately return user if it is non-None.

	  'roles' is the roles that validate() was handed.  Most
          LoginMethods will not need this parameter, but it is provided
          so that specialty LMs can require different credentials based
          on needed roles, or similar operations/decisions.


      Optionally, a LoginMethod may override the following methods (both
      of which are only called if the LoginMethod registers itself as
      having been involved in the login of the current user):

        o credentialsChanged(self, manager, user, name, credentials):

	  This method is called when the user changes their password
	  or other information which may require that the browser
	  start submitting new credentials.  This gives the
	  LoginMethod an opportunity to expire/refresh browser
	  cookies, or do anything else that may be necessary to keep
	  the user from being mysteriously logged out.  "manager" is
          the LoginManager, "user" is the user object, name is the
          the user's name, and "credentials" is whatever is passed in
          by the code that calls user.credentialsChanged().

        o logoutCurrentUser(self, manager, name)

          This method is called whenever the current user's logout()
          method is called, and as with credentialsChanged(), can be
          used to expire/update cookies, etc.

