[Zope-Checkins] CVS: Zope3/lib/python/Zope/Proxy - ContextWrapper.py:1.1.2.1 IProxyIntrospection.py:1.1.2.1 ProxyIntrospection.py:1.1.2.1 __init__.py:1.1.2.1

Jim Fulton jim@zope.com
Fri, 26 Apr 2002 14:25:03 -0400


Update of /cvs-repository/Zope3/lib/python/Zope/Proxy
In directory cvs.zope.org:/tmp/cvs-serv28156

Added Files:
      Tag: SecurityProxy-branch
	ContextWrapper.py IProxyIntrospection.py ProxyIntrospection.py 
	__init__.py 
Log Message:
Changed security code to use security proxies and name-based
security. This has pretty far-reaching implications:

- You now protect names/operations, *not* values. This means it's as
  easy yo protect data attributes that have simple values as it is to
  protect methods.

- There is no longer a __permissions__ attribute. :)

- There is no longer a validate method in either security managers or
  policies.

- No more need to have a special compiler for restricted code.
  In exchange, lots of objects are proxies and code sometimes needs to
  be prepared to remove proxies.

In addition:

- Basic objects (None, strings, numbers, etc.) are not wrapped in
  context wrappers.

- There is a test that fails unless Python 2.3 is used.



=== Added File Zope3/lib/python/Zope/Proxy/ContextWrapper.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
# 
##############################################################################
"""Wrapping/proxy coordination

Specifically, coordinate use of context wrappers and security proxies.

Revision information:
$Id: ContextWrapper.py,v 1.1.2.1 2002/04/26 18:25:02 jim Exp $
"""

from Zope.Security.Proxy import Proxy, getChecker, getObject
from Zope.ContextWrapper import Wrapper as _Wrapper, getobject, getdict
from Zope.ContextWrapper import getcontext, getinnercontext
from Zope.Security.Checker import defineChecker, selectChecker, BasicTypes

from IContextWrapper import IContextWrapper

__implements__ = IContextWrapper

def ContextWrapper(_ob, _parent, **kw):
    """Create a context wrapper around an object with data

    If the object is wrapped in a security proxy, then the context
    wrapper is inserted inside the security proxy.
    """
    
    if type(_ob) in BasicTypes:
        # Don't wrap basic objects
        return _ob
    elif type(_ob) is Proxy:
        # insert into proxies
        checker = getChecker(_ob)
        _ob = getObject(_ob)
        _ob = Proxy(_Wrapper(_ob, _parent, **kw), checker)
    else:
        _ob = _Wrapper(_ob, _parent, **kw)
        
    return _ob

def _contextWrapperChecker(ob):
    checker = selectChecker(getobject(ob))

defineChecker(_Wrapper, _contextWrapperChecker)

def getWrapperData(_ob):
    if type(_ob) is Proxy:
        _ob = getObject(_ob)
    return getdict(_ob)

def getWrapperContainer(_ob):
    if type(_ob) is Proxy:
        _ob = getObject(_ob)
    return getinnercontext(_ob)

def getWrapperContext(_ob):
    if type(_ob) is Proxy:
        _ob = getObject(_ob)
    return getcontext(_ob)
    

class ContainmentIterator:

    def __init__(self, obj):
        self._ob = _Wrapper(None, obj)

    def __iter__(self):
        return self
    
    def next(self):
        _ob = self._ob

        if type(_ob) is Proxy:
            _ob = getObject(_ob)
        
        if not isinstance(_ob, _Wrapper):
            raise StopIteration

        _ob = getinnercontext(_ob)
        self._ob = _ob
        return _ob


=== Added File Zope3/lib/python/Zope/Proxy/IProxyIntrospection.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
# 
##############################################################################
"""

Revision information:
$Id: IProxyIntrospection.py,v 1.1.2.1 2002/04/26 18:25:02 jim Exp $
"""

from Interface import Interface

class IProxyIntrospection(Interface):
    """Provides methods for indentifying proxies and extracting proxied objects
    """

    def removeProxy(obj):
        """Return the immediately proxied object.

        If obj is not a proxied object, return obj.

        Note that the object returned may still be a proxy, if there
        are multiple layers of proxy.
        """

    def removeAllProxies(obj):
        """Get the proxied oject with no proxies

        If obj is not a proxied object, return obj.

        The reurned object has no proxies.
        """

    def isProxy(obj):
        """Checkj whether the given object is a proxy
        """




=== Added File Zope3/lib/python/Zope/Proxy/ProxyIntrospection.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.
# 
##############################################################################

# XXX this module should bnecome unnecessary

"""Temporary hack module until there is a generic way to deal with proxies

This module provides some standard machinery to recognize and remove
proxies. It is hoped that it will be replaced by a cleaner
implementation based on a common proxy base class.

This module requires that proxy implementations register themselvss
with the module, by calling defineProxyType, however, it
short-circuits the definitions for two types, which, hopefully will be
the only two types that need to get registered. ;)

$Id: ProxyIntrospection.py,v 1.1.2.1 2002/04/26 18:25:02 jim Exp $
"""
from IProxyIntrospection import IProxyIntrospection

__implements__ = IProxyIntrospection


from Zope.Exceptions import DuplicationError

class ProxyRegistry:

    def __init__(self):
        self._proxy_types = {}

        # register security proxy
        from Zope.Security.Proxy import Proxy, getObject
        self._proxy_types[Proxy] = getObject

        # register context wrappers
        from Zope.ContextWrapper import Wrapper, getobject
        self._proxy_types[Wrapper] = getobject
        
    _clear = __init__

    def defineProxyType(self, type_, remover):
        """Register a proxy type
        
        A type and a function are provides. The function should take a
        proxy and return the object proxied.
        """
        if type_ in self._proxy_types:
            raise DuplicationError(type_)

        self._proxy_types[type_] = remover

    def removeProxy(self, obj):
        """Return the immediately proxied object.

        If obj is not a proxied object, return obj.

        Note that the object returned may still be a proxy, if there
        are multiple layers of proxy.
        
        """
        remover = self._proxy_types.get(type(obj))
        if remover is None:
            return obj

        return remover(obj)
        

    def removeAllProxies(self, obj):
        """Get the proxied oject with no proxies

        If obj is not a proxied object, return obj.

        The returned object has no proxies.
        """

        i=0
        get = self._proxy_types.get
        while i < 100:
            remover = get(type(obj))
            if remover is None:
                return obj
            
            obj = remover(obj)
            i=i+1

        raise TypeError('excessive proxy nesting')

    def isProxy(self, obj):
        """Checkj whether the given object is a proxy
        """
        return type(obj) in self._proxy_types
    
theProxyRegistry = ProxyRegistry()

isProxy = theProxyRegistry.isProxy
removeProxy = theProxyRegistry.removeProxy
removeAllProxies = theProxyRegistry.removeAllProxies
_clear = theProxyRegistry._clear


=== Added File Zope3/lib/python/Zope/Proxy/__init__.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 Zope proxy support

This package has some utility modules:

  - ProxyIntrospection has functions for testing for proxies and for
    removing layers of proxies.

  - ContextWrapper has functions for dealing with ContextWrappers even
    when they are wrapped in other proxies.

Revision information:
$Id: __init__.py,v 1.1.2.1 2002/04/26 18:25:02 jim Exp $
"""