[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/Security/Registries - PermissionRegistry.py:1.1 PrincipalRegistry.py:1.1 RegisteredObject.py:1.1 Registry.py:1.1 RoleRegistry.py:1.1 __init__.py:1.1 configure.zcml:1.1 meta.zcml:1.1 metaConfigure.py:1.1

Jim Fulton jim@zope.com
Thu, 20 Jun 2002 11:55:04 -0400


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

Added Files:
	PermissionRegistry.py PrincipalRegistry.py RegisteredObject.py 
	Registry.py RoleRegistry.py __init__.py configure.zcml 
	meta.zcml metaConfigure.py 
Log Message:
implemented:

http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/MergeSecurityIntoZopeNamespace

While I was at it, I couldn't resist implementing a variation of:

http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/SecurityPackageReorg

which was a lot more work. 



=== Added File Zope3/lib/python/Zope/App/Security/Registries/PermissionRegistry.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 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.
# 
##############################################################################
""" Global permission registry."""

PREFIX = 'Global Permission'
SUFFIX = 'Zope.Public'
DESCRIP = 'Anybody can do this'

from Zope.App.Security.Registries.RegisteredObject import RegisteredObject
from Zope.App.Security.Registries.Registry import Registry
from Zope.App.Security.IPermission import IPermission
from Zope.App.Security.IPermissionService import IPermissionService


class Permission(RegisteredObject):
    __implements__ = IPermission


class PermissionRegistry(Registry):
    __implements__ = IPermissionService
    
    def __init__(self, prefix=PREFIX):
        Registry.__init__(self, Permission)
        self._prefix = prefix

    def definePermission(self, permission, title, description=''):
        """Define a new permission object, register, and return it.

        permission is the permission name, must be globally unique

        title is the permission title, human readable.

        description (optional) is human readable
        """
        if permission.startswith('.'):
            raise ValueError("permissions must not start with a '.'")
        return self.register(permission, title, description)

    def definedPermission(self, permission_id):
        """Return true if named permission is registered, otherwise return
        false
        """
        return self.is_registered(permission_id)

    def getPermission(self, permission_id):
        """Return permission object registered as permission_id.

        If no named permission is registered KeyError is raised.

        """
        return self.getRegisteredObject(permission_id)

    def getPermissions(self):
        """Return all registered permission objects.
        """
        return self.getRegisteredObjects()

    def _clear(self):
        Registry._clear(self)
        self.definePermission(
            'Zope.Public', 'Public',
            """Special permission used for resources that are always public

            The public permission is effectively an optimization, sine
            it allows security computation to be bypassed.
            """
            )

permissionRegistry = PermissionRegistry()

# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
from Zope.Testing.CleanUp import addCleanUp
addCleanUp(permissionRegistry._clear)
del addCleanUp


=== Added File Zope3/lib/python/Zope/App/Security/Registries/PrincipalRegistry.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 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.
# 
##############################################################################
"""

$Id: PrincipalRegistry.py,v 1.1 2002/06/20 15:55:02 jim Exp $
"""

from Zope.Exceptions import NotFoundError
from Zope.App.Security.ILoginPassword import ILoginPassword
from Zope.ComponentArchitecture import getAdapter, queryAdapter
from Zope.App.Security.IAuthenticationService import IAuthenticationService
from Zope.App.Security.IPrincipal import IPrincipal

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

# XXX why isn't this subclassing 'Registry' ? ? ?
class PrincipalRegistry:

    __implements__ = IAuthenticationService

    # Methods implementing IAuthenticationService
    
    def authenticate(self, request):
        a = queryAdapter(request, ILoginPassword, None)
        if a is not None:
            login = a.getLogin()
            if login is not None:
                p = self.__principalsByLogin.get(login, None)
                if p is not None:
                    password = a.getPassword()
                    if p.validate(password):
                        return p.getId()
        return None

    __defaultid = None
    __defaultObject = None

    def defineDefaultPrincipal(self, principal, title, description=''):
        id = principal
        if id in self.__principalsById:
            raise DuplicateId(id)
        self.__defaultid = id
        p = Principal(principal, title, description, '', '')
        self.__defaultObject = p
        return p

    def unauthenticatedPrincipal(self):
        return self.__defaultid

    def unauthorized(self, id, request):
        # XXX This is a mess. request has no place here!
        if id is None or id is self.__defaultid:
            a = getAdapter(request, ILoginPassword)
            a.needLogin(realm="zope")

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

    def getPrincipalByLogin(self, login):
        r = self.__principalsByLogin.get(login)
        if r is None: raise NotFoundError(login)
        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, principal, title, description='',
                        login='', password=''):
        id=principal
        if login in self.__principalsByLogin:
            raise DuplicateLogin(login)

        if id in self.__principalsById or id == self.__defaultid:
            raise DuplicateId(id)
        
        p = Principal(id, title, description, login, password)
        
        self.__principalsByLogin[login]=p
        self.__principalsById[id]=p

        return p

    def _clear(self):
        self.__init__()

principalRegistry=PrincipalRegistry()

# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
from Zope.Testing.CleanUp import addCleanUp
addCleanUp(principalRegistry._clear)
del addCleanUp

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

    def validate(self, pw):
        return pw == self.__pw


=== Added File Zope3/lib/python/Zope/App/Security/Registries/RegisteredObject.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 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.
# 
##############################################################################
"""An implementation of things that can be registered in a Registry."""

from Zope.App.Security.IRegisteredObject import IRegisteredObject

class RegisteredObject(object):
    __implements__ = IRegisteredObject

    def __init__(self, id, title, description):
        self._id = id
        self._title = title
        self._description = description

    def getId(self):
        return self._id

    def getTitle(self):
        return self._title

    def getDescription(self):
        return self._description


=== Added File Zope3/lib/python/Zope/App/Security/Registries/Registry.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 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.
# 
##############################################################################
"""Generic registry of ids to objects."""

from Interface.Verify import verifyClass
from Zope.App.Security.IRegisteredObject import IRegisteredObject
from Zope.Exceptions import ZopeError


class AlreadyRegisteredError(ZopeError, ValueError):
    """An attempt was made to register an object with an already registered id.
    """


class Registry:
    def __init__(self, class_):
        """Instantiate a generic registry.

        class_ is the class of the thing that we're going to instantiate.
        """
        assert verifyClass(IRegisteredObject, class_)
        self._class = class_
        self._clear()

    def register(self, id, title='', description=''):
        """Create a registered object with the given id, title, and description

        Register and return the object.  The empty string will be used if
        either the optional title or description is omitted.  The id must be
        unique.

        If the id is already registered, an AlreadyRegisteredError is raised.
        """
        if id in self._byid:
            raise AlreadyRegisteredError('Id is not unique: %s' % id)
        obj = self._class(id, title, description)
        self._byid[id] = obj
        return obj

    def is_registered(self, id):
        """Return true if an object is registered with the given id.
        Otherwise false is returned.
        """
        return id in self._byid

    def getRegisteredObject(self, id):
        """Return the object registered under the given id.
        """
        return self._byid.get(id)

    def getRegisteredObjects(self):
        """Return all registered objects.
        """
        return self._byid.values()

    def _clear(self):
        # Map ids to instantiated objects
        self._byid = {}


=== Added File Zope3/lib/python/Zope/App/Security/Registries/RoleRegistry.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 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.
# 
##############################################################################
"""Global role registry."""

PREFIX = 'Global Role'

from Zope.App.Security.Registries.RegisteredObject import RegisteredObject
from Zope.App.Security.Registries.Registry import Registry
from Zope.App.Security.IRole import IRole
from Zope.App.Security.IRoleService import IRoleService

class Role(RegisteredObject):
    __implements__ = IRole


class RoleRegistry(Registry):
    __implements__ = IRoleService

    def __init__(self, prefix=PREFIX):
        Registry.__init__(self, Role)
        self._prefix = prefix

    def _make_global_id(self, suffix):
        return self._prefix + '.' + suffix

    def defineRole(self, role, title, description=None):
        """Define a new role object, register, and return it.

        role is the role name.

        title is the role title, human readable.

        description (optional) is human readable
        """
        if description is None:
            description = ''
        id = role
        return self.register(id, title, description)

    def definedRole(self, id):
        """Return true if named role is registered, otherwise return false
        """
        return self.is_registered(id)

    def getRole(self, id):
        """Return role object registered as name.

        If no named role is registered KeyError is raised.
        """
        return self.getRegisteredObject(id)

    def getRoles(self):
        """Return all registered role objects.
        """
        return self.getRegisteredObjects()

    def _clear(self):
        # Standard roles
        Registry._clear(self)
        self.register("Anonymous", "Everybody",
                      "All users have this role implicitly")

roleRegistry = RoleRegistry()


# Register our cleanup with Testing.CleanUp to make writing unit tests simpler.
from Zope.Testing.CleanUp import addCleanUp
addCleanUp(roleRegistry._clear)
del addCleanUp


=== Added File Zope3/lib/python/Zope/App/Security/Registries/__init__.py ===
##############################################################################
#
# Copyright (c) 2002 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.
# 
##############################################################################
"""XXX short summary goes here.

XXX longer description goes here.

$Id: __init__.py,v 1.1 2002/06/20 15:55:02 jim Exp $
"""


=== Added File Zope3/lib/python/Zope/App/Security/Registries/configure.zcml ===
<zopeConfigure
   xmlns='http://namespaces.zope.org/zope'
   xmlns:zmi='http://namespaces.zope.org/zmi'
   xmlns:browser='http://namespaces.zope.org/browser'
   package="Zope.App.Security"
>

  <serviceType
      id="RoleService" 
      interface=".IRoleService." />
  <service
      serviceType="RoleService" 
      component=".Registries.RoleRegistry.roleRegistry" />

  <serviceType
      id="PermissionService" 
      interface=".IPermissionService." />
  <service
      serviceType="PermissionService" 
      component=".Registries.PermissionRegistry.permissionRegistry" />

  <serviceType
      id="AuthenticationService" 
      interface=".IAuthenticationService." />
  <service
      serviceType="AuthenticationService" 
      component=".Registries.PrincipalRegistry.principalRegistry" />

  <!-- protect Roles and Permissions -->
  <content class=".Registries.RoleRegistry.Role">
    <allow
        interface="Zope.App.Security.IRegisteredObject." />
  </content>
  <content class=".Registries.PermissionRegistry.Permission">
    <allow
        interface="Zope.App.Security.IRegisteredObject." />
  </content>
  
</zopeConfigure>



=== Added File Zope3/lib/python/Zope/App/Security/Registries/meta.zcml ===
<zopeConfigure xmlns='http://namespaces.zope.org/zope'>

  <!-- Zope.App.Security -->
  <directives namespace="http://namespaces.zope.org/zope">
    <directive name="permission"
               attributes="id title description"
               handler=".metaConfigure.definePermission" />
    <directive name="role"
               attributes="id title description"
               handler=".metaConfigure.defineRole" />
    <directive name="principal" attributes="id title description"
       handler=".metaConfigure.principal" />
    <directive name="unauthenticatedPrincipal" 
               attributes="principal title description"
       handler=".metaConfigure.unauthenticatedPrincipal" />
  </directives>

</zopeConfigure>


=== Added File Zope3/lib/python/Zope/App/Security/Registries/metaConfigure.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 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.
# 
##############################################################################
""" Register security related configuration directives.

$Id: metaConfigure.py,v 1.1 2002/06/20 15:55:02 jim Exp $
"""
from PermissionRegistry import permissionRegistry as perm_reg
from RoleRegistry import roleRegistry as role_reg
from Zope.Security.SecurityManager import setSecurityPolicy
from PrincipalRegistry import principalRegistry
from Zope.Configuration.Action import Action

def definePermission(_context, id, title, description=''):
    return [
        Action(
            discriminator = ('definePermission', id),
            callable = perm_reg.definePermission,
            args = (id, title, description),
            )
        ]

def defineRole(_context, id, title, description=''):
    return [
        Action(
            discriminator = ('defineRole', id),
            callable = role_reg.defineRole,
            args = (id, title, description),
            )
        ]

def principal(_context, id, title, login, password, description=''):
    return [
        Action(
            discriminator = ('principal', id),
            callable = principalRegistry.definePrincipal,
            args = (id, title, description, login, password),
            )
        ]

def unauthenticatedPrincipal(_context, id, title, description=''):
    return [
        Action(
            discriminator = 'unauthenticatedPrincipal',
            callable = principalRegistry.defineDefaultPrincipal,
            args = (id, title, description),
            )
        ]