[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/Security - IAuthenticationService.py:1.1.2.1 IPrincipal.py:1.1.2.1 PrincipalRegistry.py:1.1.2.1

Jim Fulton jim@zope.com
Wed, 12 Dec 2001 16:37:36 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/App/Security
In directory cvs.zope.org:/tmp/cvs-serv31987

Added Files:
      Tag: Zope-3x-branch
	IAuthenticationService.py IPrincipal.py PrincipalRegistry.py 
Log Message:
Initial cut at IAuthenticationService without actual authentication.

Note that IAuthenticationService may get factored into separate
services based on pje's suggestions, unless it isn't.


=== Added File Zope3/lib/python/Zope/App/Security/IAuthenticationService.py ===
##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
# 
##############################################################################
"""

Revision information: $Id: IAuthenticationService.py,v 1.1.2.1 2001/12/12 21:37:35 jim Exp $
"""

from Interface import Interface

class IAuthenticationService(Interface):
    """
    Provide support for establishing principals for requests and for
    performing protocol-specific actions, such as issuing challenges
    or providing login interfaces.
    
    IAuthenticationService objects are used to implement
    authentication services. Because they implement services, they are
    expected to collaborate with services in other contexts. Client
    code doesn't sarch a context and call multiple services. Instead,
    client code will call the most specific service in a place and
    rely on the service to delegate to other services as necessary.
    
    The interface doesn't include methods for data
    management. Services may use external data and not allow
    management in Zope. Simularly, the data to be managed may vary
    with different implementations of a service.
    """    

    def authenticate(request):
        """
        
        Indentify a principal for a request

        If a principal can be identified, then return the
        principal id. Otherwise, return None.

        The request object is fairly opaque. We may decide
        that it implements some generic request interface.

        Implementation note

        It is likely that the component will dispatch
        to another component based on the actual
        request interface. This will allow different
        kinds of requests to be handled correctly.

        For example, a component that authenticates
        based on user names and passwords might request
        an adapter for the request as in::

          getpw=getAdapter(request,
                       IUsernamePassword, place=self)


        The place keyword argument is used to control
        where the IUsernamePassword component is
        searched for. This is necessary because
        requests are placeless.
        """

        
    def unauthorized(id, request):
        """
        Signal an authorization failure
        
        This method is called when an auhorization problem
        occurs. It can perform a variety of actions, such
        as issuing an HTTP authentication challenge or
        displaying a login interface.
        
        Note that the authentication service nearest to the
        requested resource is called. It is up to
        authentication service implementations to
        colaborate with services higher in the object
        hierarchy.
        
        If no principal has been identified, id will be
        None.
        """

    def getPrincipal(pid):
        """
        Get principal meta-data

        Returns an object of type IPrincipal for the given principal
        id. A NotFoundErrorx is raised if the principal cannot be
        found.

        Note that the authentication service nearest to the requested
        resource is called. It is up to authentication service
        implementations to colaborate with services higher in the
        object hierarchy.
        """

    def getPrincipals(name):
        """
        Get principals with matching names.

        Get a iterable object with the principals with names that are
        similar to (e.g. contain) the given name.
        """



=== Added File Zope3/lib/python/Zope/App/Security/IPrincipal.py ===
##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
# 
##############################################################################
"""

Revision information: $Id: IPrincipal.py,v 1.1.2.1 2001/12/12 21:37:35 jim Exp $
"""

from Interface import Interface

class IPrincipal(Interface):
    """Provide information about principals.

    It is likely that IPrincipal objects will have associated
    views used to list principals in management
    interfaces. For example, a system in which other meta-data are
    provided for principals might extend IPrincipal and register a
    view for the extended interface that displays the extended
    information. We'll probably want to define a standard view
    name (e.g.  "inline_summary") for this purpose.
    """

    def getId():
        """Return a unique id string for the principal.
        """

    def getTitle():
        """Return a label for the principal

        The label will be used in interfaces to allow users to make
        security assertions (e.g. role or permission
        assignments) about principals.
        """
    def getDescription():
        """Return a description of the principal."""


=== Added File Zope3/lib/python/Zope/App/Security/PrincipalRegistry.py ===
##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
# 
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
# 
##############################################################################
"""

Revision information: $Id: PrincipalRegistry.py,v 1.1.2.1 2001/12/12 21:37:35 jim Exp $
"""

from IAuthenticationService import IAuthenticationService
from IPrincipal import IPrincipal
from Zope.Exceptions import NotFoundError

class DuplicateLogin(Exception): pass
class DuplicateId(Exception): pass

class PrincipalRegistry:


    __implements__ = IAuthenticationService

    # Methods implementing IAuthenticationService
    
    def authenticate(self, request):
        pass

        
    def unauthorized(self, id, request):
        pass

    def getPrincipal(self, pid):
        r = self.__principalsById.get(pid)
        if r is None: raise NotFoundError(pid)
        return r

    def getPrincipals(self, name):
        name = name.lower()
        return [p for p in self.__principalsById.itervalues()
                  if p.getTitle().lower().startswith(name) or
                     p.getLogin().lower().startswith(name)]

    # Management methods

    def __init__(self):
        self.__principalsById={}
        self.__principalsByLogin = {}

    def definePrincipal(self, id, title, description, login, pw):
        p = Principal(id, title, description, login, pw)
        if login in self.__principalsByLogin:
            raise DuplicateLogin(login)

        if id in self.__principalsById:
            raise DuplicateId(id)
        
        self.__principalsByLogin[login]=p
        self.__principalsById[id]=p

        

class Principal:

    __implements__ = IPrincipal

    def __init__(self, id, title, description, login, pw):
        self.__id = id
        self.__title = title
        self.__description = description
        self.__login = login
        self.__pw = pw

    def getId(self):
        return self.__id

    def getTitle(self):
        return self.__title

    def getDescription(self):
        return self.__description

    def getLogin(self):
        return self.__login