Commit 773b9f8b authored by Jim Fulton's avatar Jim Fulton

Added prodct-defined permissions and product permission mapping

parent 9c1817e4
...@@ -85,8 +85,8 @@ ...@@ -85,8 +85,8 @@
__doc__='''short description __doc__='''short description
$Id: Permission.py,v 1.5 1999/03/22 16:49:40 jim Exp $''' $Id: Permission.py,v 1.6 1999/07/21 13:13:28 jim Exp $'''
__version__='$Revision: 1.5 $'[11:-2] __version__='$Revision: 1.6 $'[11:-2]
from Globals import HTMLFile, MessageDialog from Globals import HTMLFile, MessageDialog
from string import join, strip, split, find from string import join, strip, split, find
...@@ -103,20 +103,22 @@ name_trans=string.maketrans(string.join(name_trans,''), '_'*len(name_trans)) ...@@ -103,20 +103,22 @@ name_trans=string.maketrans(string.join(name_trans,''), '_'*len(name_trans))
def pname(name, translate=string.translate, name_trans=name_trans): def pname(name, translate=string.translate, name_trans=name_trans):
return '_'+translate(name,name_trans)+"_Permission" return '_'+translate(name,name_trans)+"_Permission"
_marker=[]
class Permission: class Permission:
# A Permission maps a named logical permission to a set # A Permission maps a named logical permission to a set
# of attribute names. Attribute names which appear in a # of attribute names. Attribute names which appear in a
# permission may not appear in any other permission defined # permission may not appear in any other permission defined
# by the object. # by the object.
def __init__(self,name,data,obj): def __init__(self,name,data,obj,default=None):
self.name=name self.name=name
self._p='_'+string.translate(name,name_trans)+"_Permission" self._p='_'+string.translate(name,name_trans)+"_Permission"
self.data=data self.data=data
if hasattr(obj, 'aq_base'): obj=obj.aq_base if hasattr(obj, 'aq_base'): obj=obj.aq_base
self.obj=obj self.obj=obj
self.default=default
def getRoles(self): def getRoles(self, default=_marker):
# Return the list of role names which have been given # Return the list of role names which have been given
# this permission for the object in question. To do # this permission for the object in question. To do
# this, we try to get __roles__ from all of the object # this, we try to get __roles__ from all of the object
...@@ -124,7 +126,7 @@ class Permission: ...@@ -124,7 +126,7 @@ class Permission:
obj=self.obj obj=self.obj
name=self._p name=self._p
if hasattr(obj, name): return getattr(obj, name) if hasattr(obj, name): return getattr(obj, name)
roles=[] roles=default
for name in self.data: for name in self.data:
if name: if name:
if hasattr(obj, name): if hasattr(obj, name):
...@@ -152,6 +154,7 @@ class Permission: ...@@ -152,6 +154,7 @@ class Permission:
except: return [] except: return []
if roles is None: return ['Manager','Anonymous'] if roles is None: return ['Manager','Anonymous']
if roles is _marker: return ['Manager']
return roles return roles
......
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
"""Permission Mapping
Sometimes, we need an object's permissions to be remapped to other permissions
when the object is used in specual ways. This is rather hard, since we
need the object's ordinary permissions intact so we can manage it.
"""
import ExtensionClass, Acquisition
from AccessControl.Permission import pname
class RoleManager:
def manage_getPermissionMapping(self):
"""Return the permission mapping for the object
This is a list of dictionaries with:
permission_name -- The name of the native object permission
class_permission -- The class permission the permission is
mapped to.
"""
wrapper=getattr(self, '_permissionMapper', None)
if wrapper is None: wrapper=PM()
perms={}
for p in self.possible_permissions():
perms[pname(p)]=p
r=[]
a=r.append
for ac_perms in self.ac_inherited_permissions(1):
p=perms.get(getPermissionMapping(ac_perms[0], wrapper), '')
a({'permission_name': ac_perms[0], 'class_permission': p})
return r
def manage_setPermissionMapping(self,
permission_names=[],
class_permissions=[], REQUEST=None):
"""Change the permission mapping
"""
wrapper=getattr(self, '_permissionMapper', None)
if wrapper is None: wrapper=PM()
perms=self.possible_permissions()
for i in range(len(permission_names)):
name=permission_names[i]
p=class_permissions[i]
if p and (p not in perms):
__traceback_info__=perms, p, i
raise 'waaa'
setPermissionMapping(name, wrapper, p)
self._permissionMapper=wrapper
if REQUEST is not None:
return self.manage_access(
self, REQUEST,
manage_tabs_message='The permission mapping has been updated')
def _isBeingUsedAsAMethod(self, REQUEST =None, wannaBe=0):
try:
if hasattr(self, 'aq_self'):
r=self.aq_acquire('_isBeingUsedAsAMethod_')
else:
r=self._isBeingUsedAsAMethod_
except: r=0
if REQUEST is not None:
if not r != (not wannaBe): REQUEST.response.notFoundError()
return r
def getPermissionMapping(name, obj, st=type('')):
obj=getattr(obj, 'aq_base', obj)
name=pname(name)
r=getattr(obj, name, '')
if type(r) is not st: r=''
return r
def setPermissionMapping(name, obj, v):
name=pname(name)
if v: setattr(obj, name, pname(v))
elif obj.__dict__.has_key(name): delattr(obj, name)
class PM(ExtensionClass.Base):
_View_Permission='_View_Permission'
def __getattr__(self, name):
# We want to make sure that any non-explicitly set methods are
# private!
if name[:1]=='_' and name[-11:]=="_Permission": return ''
raise AttributeError, name
PermissionMapper=PM
def aqwrap(object, wrapper, parent):
r=Rewrapper()
r._ugh=wrapper, object, parent
return r
class Rewrapper(ExtensionClass.Base):
def __of__(self, parent):
w, m, p = self._ugh
return m.__of__(
Acquisition.ImplicitAcquisitionWrapper(
w, parent))
def __getattr__(self, name):
w, m, parent = self._ugh
self=m.__of__(
Acquisition.ImplicitAcquisitionWrapper(
w, parent))
return getattr(self, name)
def __call__(self, *args, **kw):
w, m, parent = self._ugh
self=m.__of__(
Acquisition.ImplicitAcquisitionWrapper(
w, parent))
return apply(self, args, kw)
...@@ -85,8 +85,8 @@ ...@@ -85,8 +85,8 @@
__doc__='''Objects that implement Permission-based roles. __doc__='''Objects that implement Permission-based roles.
$Id: PermissionRole.py,v 1.6 1999/06/16 19:41:14 jim Exp $''' $Id: PermissionRole.py,v 1.7 1999/07/21 13:13:28 jim Exp $'''
__version__='$Revision: 1.6 $'[11:-2] __version__='$Revision: 1.7 $'[11:-2]
import sys import sys
...@@ -98,7 +98,7 @@ name_trans=filter(lambda c, an=string.letters+string.digits+'_': c not in an, ...@@ -98,7 +98,7 @@ name_trans=filter(lambda c, an=string.letters+string.digits+'_': c not in an,
map(chr,range(256))) map(chr,range(256)))
name_trans=string.maketrans(string.join(name_trans,''), '_'*len(name_trans)) name_trans=string.maketrans(string.join(name_trans,''), '_'*len(name_trans))
def rolesForPermissionOn(perm, object, default=()): def rolesForPermissionOn(perm, object, default=('Manager',)):
"""Return the roles that have the given permission on the given object """Return the roles that have the given permission on the given object
""" """
im=imPermissionRole() im=imPermissionRole()
......
...@@ -84,19 +84,19 @@ ...@@ -84,19 +84,19 @@
############################################################################## ##############################################################################
"""Access control support""" """Access control support"""
__version__='$Revision: 1.33 $'[11:-2] __version__='$Revision: 1.34 $'[11:-2]
from Globals import HTMLFile, MessageDialog, Dictionary from Globals import HTMLFile, MessageDialog, Dictionary
from string import join, strip, split, find from string import join, strip, split, find
from Acquisition import Implicit from Acquisition import Implicit
import Globals, ExtensionClass import Globals, ExtensionClass, PermissionMapping, Products
from Permission import Permission from Permission import Permission
from App.Common import aq_base from App.Common import aq_base
ListType=type([]) ListType=type([])
class RoleManager(ExtensionClass.Base): class RoleManager(ExtensionClass.Base, PermissionMapping.RoleManager):
"""An obect that has configurable permissions""" """An obect that has configurable permissions"""
__ac_permissions__=( __ac_permissions__=(
...@@ -132,6 +132,13 @@ class RoleManager(ExtensionClass.Base): ...@@ -132,6 +132,13 @@ class RoleManager(ExtensionClass.Base):
r=gather_permissions(self.__class__, [], d) r=gather_permissions(self.__class__, [], d)
if all: if all:
if hasattr(self, '_subobject_permissions'):
for p in self._subobject_permissions():
pname=p[0]
if not d.has_key(pname):
d[pname]=1
r.append(p)
r=list(perms)+r r=list(perms)+r
r.sort() r.sort()
...@@ -494,6 +501,16 @@ class RoleManager(ExtensionClass.Base): ...@@ -494,6 +501,16 @@ class RoleManager(ExtensionClass.Base):
def _setRoles(self,acl_type,acl_roles): def _setRoles(self,acl_type,acl_roles):
pass pass
def possible_permissions(self):
r=map(
lambda p: p[0],
Products.__ac_permissions__+
self.aq_acquire('_getProductRegistryData')('ac_permissions')
)
r.sort()
return r
Globals.default__class_init__(RoleManager) Globals.default__class_init__(RoleManager)
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<!--#/if manage_tabs--> <!--#/if manage_tabs-->
<p>The listing below shows the current permission mappings for this item.</p> <p>The listing below shows the current permission mappings for this item.</p>
<!--#with "_(valid=classDefinedAndInheritedPermissions())"--> <!--#with "_(valid=permissionMappingPossibleValues())"-->
<form action="manage_setPermissionMapping" method="POST"> <form action="manage_setPermissionMapping" method="POST">
<table> <table>
<tr><th align=left>Permission</th> <tr><th align=left>Permission</th>
......
...@@ -84,36 +84,50 @@ ...@@ -84,36 +84,50 @@
############################################################################## ##############################################################################
__doc__='''Principia Factories __doc__='''Principia Factories
$Id: Factory.py,v 1.12 1999/07/13 13:40:40 jim Exp $''' $Id: Factory.py,v 1.13 1999/07/21 13:15:23 jim Exp $'''
__version__='$Revision: 1.12 $'[11:-2] __version__='$Revision: 1.13 $'[11:-2]
import OFS.SimpleItem, Acquisition, Globals import OFS.SimpleItem, Acquisition, Globals, AccessControl.Role
import Product import Products, Product
class Factory(Globals.Persistent, Acquisition.Implicit, OFS.SimpleItem.Item): class Factory(
AccessControl.Role.RoleManager,
Globals.Persistent, Acquisition.Implicit, OFS.SimpleItem.Item
):
"Model factory meta-data" "Model factory meta-data"
meta_type='Zope Factory' meta_type='Zope Factory'
icon='p_/Factory_icon' icon='p_/Factory_icon'
permission='' # Waaaa
_setObject=Acquisition.Acquired _setObject=Acquisition.Acquired
__ac_permissions__=(
('Edit Factories', ('manage_edit','manage_main')),
('Use Factories', ('index_html','')),
)
manage_options=( manage_options=(
{'label':'Edit', 'action':'manage_main'}, {'label':'Edit', 'action':'manage_main'},
{'label':'Security', 'action':'manage_access'}, {'label':'Security', 'action':'manage_access'},
) )
def __init__(self, id, title, object_type, initial, product=None): def __init__(self, id, title, object_type, initial, permission=''):
self.id=id self.id=id
self.title=title self.title=title
self.object_type=object_type self.object_type=object_type
self.initial=initial self.initial=initial
self.permission=permission
def manage_edit(self, title, object_type, initial, REQUEST=None): def manage_edit(self, title, object_type, initial, permission='',
REQUEST=None):
"Modify factory properties." "Modify factory properties."
self._unregister() self._unregister()
self.title=title self.title=title
self.object_type=object_type self.object_type=object_type
self.initial=initial self.initial=initial
self.permission=permission
self.manage_setPermissionMapping(('Use Factories',), (permission,))
self._register() self._register()
if REQUEST is not None: return self.manage_main(self, REQUEST) if REQUEST is not None: return self.manage_main(self, REQUEST)
...@@ -141,7 +155,7 @@ class Factory(Globals.Persistent, Acquisition.Implicit, OFS.SimpleItem.Item): ...@@ -141,7 +155,7 @@ class Factory(Globals.Persistent, Acquisition.Implicit, OFS.SimpleItem.Item):
# Register with the product folder # Register with the product folder
product=self.aq_parent product=self.aq_parent
product.aq_acquire('_manage_add_product_meta_type')( product.aq_acquire('_manage_add_product_meta_type')(
product, self.id, self.object_type) product, self.id, self.object_type, self.permission)
def _unregister(self): def _unregister(self):
# Unregister with the product folder # Unregister with the product folder
...@@ -161,7 +175,5 @@ class Factory(Globals.Persistent, Acquisition.Implicit, OFS.SimpleItem.Item): ...@@ -161,7 +175,5 @@ class Factory(Globals.Persistent, Acquisition.Implicit, OFS.SimpleItem.Item):
self.aq_parent.objectIds() self.aq_parent.objectIds()
) )
class ProductFactory(Factory): pass
...@@ -87,6 +87,7 @@ ...@@ -87,6 +87,7 @@
# Implement the manage_addProduct method of object managers # Implement the manage_addProduct method of object managers
import Acquisition, sys import Acquisition, sys
from string import rfind from string import rfind
from AccessControl.PermissionMapping import aqwrap
class ProductDispatcher(Acquisition.Implicit): class ProductDispatcher(Acquisition.Implicit):
" " " "
...@@ -129,7 +130,12 @@ class FactoryDispatcher(Acquisition.Implicit): ...@@ -129,7 +130,12 @@ class FactoryDispatcher(Acquisition.Implicit):
p=self.__dict__['_product'] p=self.__dict__['_product']
d=p.__dict__ d=p.__dict__
if hasattr(p,name) and d.has_key(name): if hasattr(p,name) and d.has_key(name):
return d[name] m=d[name]
w=getattr(m, '_permissionMapper', None)
if w is not None:
m=ofWrapper(aqwrap(m, getattr(w,'aq_base',w), self))
return m
# Waaa # Waaa
m='Products.%s' % p.id m='Products.%s' % p.id
...@@ -149,6 +155,11 @@ class FactoryDispatcher(Acquisition.Implicit): ...@@ -149,6 +155,11 @@ class FactoryDispatcher(Acquisition.Implicit):
REQUEST['RESPONSE'].redirect(self.DestinationURL()+d) REQUEST['RESPONSE'].redirect(self.DestinationURL()+d)
import ExtensionClass
class ofWrapper(ExtensionClass.Base):
def __init__(self, o):
self._o=o
def __of__(self, parent): return self.__dict__['_o']
##############################################################################
#
# Zope Public License (ZPL) Version 1.0
# -------------------------------------
#
# Copyright (c) Digital Creations. All rights reserved.
#
# This license has been certified as Open Source(tm).
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions in source code must retain the above copyright
# notice, this list of conditions, and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions, and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# 3. Digital Creations requests that attribution be given to Zope
# in any manner possible. Zope includes a "Powered by Zope"
# button that is installed by default. While it is not a license
# violation to remove this button, it is requested that the
# attribution remain. A significant investment has been put
# into Zope, and this effort will continue if the Zope community
# continues to grow. This is one way to assure that growth.
#
# 4. All advertising materials and documentation mentioning
# features derived from or use of this software must display
# the following acknowledgement:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# In the event that the product being advertised includes an
# intact Zope distribution (with copyright and license included)
# then this clause is waived.
#
# 5. Names associated with Zope or Digital Creations must not be used to
# endorse or promote products derived from this software without
# prior written permission from Digital Creations.
#
# 6. Modified redistributions of any form whatsoever must retain
# the following acknowledgment:
#
# "This product includes software developed by Digital Creations
# for use in the Z Object Publishing Environment
# (http://www.zope.org/)."
#
# Intact (re-)distributions of any official Zope release do not
# require an external acknowledgement.
#
# 7. Modifications are encouraged but must be packaged separately as
# patches to official Zope releases. Distributions that do not
# clearly separate the patches from the original work must be clearly
# labeled as unofficial distributions. Modifications which do not
# carry the name Zope may be packaged in any form, as long as they
# conform to all of the clauses above.
#
#
# Disclaimer
#
# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# This software consists of contributions made by Digital Creations and
# many individuals on behalf of Digital Creations. Specific
# attributions are listed in the accompanying credits file.
#
##############################################################################
__doc__='''Zope registerable permissions
$Id: Permission.py,v 1.1 1999/07/21 13:15:24 jim Exp $'''
__version__='$Revision: 1.1 $'[11:-2]
import OFS.SimpleItem, Acquisition, Globals, ExtensionClass, AccessControl.Role
class Permission(
AccessControl.Role.RoleManager,
Globals.Persistent, Acquisition.Implicit, OFS.SimpleItem.Item
):
"Model Permission meta-data"
meta_type='Zope Permission'
icon='p_/Permission_icon'
manage_options=(
{'label':'Edit', 'action':'manage_main'},
{'label':'Security', 'action':'manage_access'},
)
def __init__(self, id, title, name):
self.id=id
self.title=title
self.name=name
def manage_edit(self, title, name, REQUEST=None):
"Modify Permission properties."
if title != self.title: self.title=title
if name != self.name:
self._unregister()
self.name=name
self._register()
if REQUEST is not None: return self.manage_main(self, REQUEST)
def manage_afterAdd(self, item, container):
self._register()
def manage_beforeDelete(self, item, container):
self._unregister()
def _register(self):
# Register with the product folder
product=self.aq_parent
product.aq_acquire('_manage_add_product_permission')(
product, self.name)
def _unregister(self):
# Unregister with the product folder
product=self.aq_parent
product.aq_acquire('_manage_remove_product_permission')(
product, self.name)
manage_main=Globals.HTMLFile('editPermission',globals())
index_html=None
class PermissionManager(ExtensionClass.Base):
__ac_permissions__=(
('Define permissions',
('manage_addPermissionForm', 'manage_addPermission')),
)
meta_types={
'name': Permission.meta_type, 'action': 'manage_addPermissionForm'
},
manage_addPermissionForm=Globals.HTMLFile('addPermission',globals())
def manage_addPermission(
self, id, title, permission, REQUEST=None):
' '
i=Permission(id, title, permission)
self._setObject(id,i)
if REQUEST is not None:
return self.manage_main(self,REQUEST,update_menu=1)
...@@ -106,11 +106,12 @@ ...@@ -106,11 +106,12 @@
# on restart if there is still a product directory. # on restart if there is still a product directory.
import Globals, OFS.Folder, OFS.SimpleItem, os, string, Acquisition import Globals, OFS.Folder, OFS.SimpleItem, os, string, Acquisition, Products
from OFS.Folder import Folder from OFS.Folder import Folder
import regex, zlib, Globals, cPickle, marshal, rotor import regex, zlib, Globals, cPickle, marshal, rotor
from string import rfind, atoi, find, strip, join from string import rfind, atoi, find, strip, join
from Factory import Factory from Factory import Factory
from Permission import PermissionManager
import ZClasses, ZClasses.ZClass import ZClasses, ZClasses.ZClass
class ProductFolder(Folder): class ProductFolder(Folder):
...@@ -145,7 +146,7 @@ class ProductFolder(Folder): ...@@ -145,7 +146,7 @@ class ProductFolder(Folder):
def _canCopy(self, op=0): def _canCopy(self, op=0):
return 0 return 0
class Product(Folder): class Product(Folder, PermissionManager):
"""Model a product that can be created through the web. """Model a product that can be created through the web.
""" """
meta_type='Product' meta_type='Product'
...@@ -153,6 +154,7 @@ class Product(Folder): ...@@ -153,6 +154,7 @@ class Product(Folder):
version='' version=''
configurable_objects_=() configurable_objects_=()
import_error_=None import_error_=None
_isBeingUsedAsAMethod_=1
def new_version(self, def new_version(self,
_intending=regex.compile("[.]?[0-9]+$").search, #TS _intending=regex.compile("[.]?[0-9]+$").search, #TS
...@@ -166,7 +168,7 @@ class Product(Folder): ...@@ -166,7 +168,7 @@ class Product(Folder):
meta_types=( meta_types=(
ZClasses.meta_types+ ZClasses.meta_types+PermissionManager.meta_types+
( (
{ {
'name': Factory.meta_type, 'name': Factory.meta_type,
...@@ -197,9 +199,9 @@ class Product(Folder): ...@@ -197,9 +199,9 @@ class Product(Folder):
manage_addPrincipiaFactoryForm=Globals.HTMLFile('addFactory',globals()) manage_addPrincipiaFactoryForm=Globals.HTMLFile('addFactory',globals())
def manage_addPrincipiaFactory( def manage_addPrincipiaFactory(
self, id, title, object_type, initial, REQUEST=None): self, id, title, object_type, initial, permission=None, REQUEST=None):
' ' ' '
i=Factory(id, title, object_type, initial) i=Factory(id, title, object_type, initial, permission)
self._setObject(id,i) self._setObject(id,i)
if REQUEST is not None: if REQUEST is not None:
return self.manage_main(self,REQUEST,update_menu=1) return self.manage_main(self,REQUEST,update_menu=1)
...@@ -309,6 +311,9 @@ class Product(Folder): ...@@ -309,6 +311,9 @@ class Product(Folder):
)).read() )).read()
except: return '' except: return ''
def permissionMappingPossibleValues(self):
return self.possible_permissions()
class CompressedOutputFile: class CompressedOutputFile:
def __init__(self, rot): def __init__(self, rot):
self._c=zlib.compressobj() self._c=zlib.compressobj()
......
...@@ -156,7 +156,7 @@ class ProductContext: ...@@ -156,7 +156,7 @@ class ProductContext:
OM=OFS.ObjectManager.ObjectManager OM=OFS.ObjectManager.ObjectManager
perms={} perms={}
for p in OM.__ac_permissions__: perms[p[0]]=None for p in Products.__ac_permissions__: perms[p[0]]=None
if permission is None: if permission is None:
permission="Add %ss" % (meta_type or instance_class.meta_type) permission="Add %ss" % (meta_type or instance_class.meta_type)
...@@ -178,7 +178,8 @@ class ProductContext: ...@@ -178,7 +178,8 @@ class ProductContext:
if not perms.has_key(p): if not perms.has_key(p):
perms[p]=None perms[p]=None
OM.__ac_permissions__=OM.__ac_permissions__+((p,(),default),) Products.__ac_permissions__=(
Products.__ac_permissions__+((p,(),default),))
if not hasattr(Globals.ApplicationDefaultPermissions, pr_._p): if not hasattr(Globals.ApplicationDefaultPermissions, pr_._p):
setattr(Globals.ApplicationDefaultPermissions, setattr(Globals.ApplicationDefaultPermissions,
pr_._p, default) pr_._p, default)
......
...@@ -145,6 +145,51 @@ class ProductRegistryMixin: ...@@ -145,6 +145,51 @@ class ProductRegistryMixin:
self._setProductRegistryMetaTypes(meta_types+(mt,)) self._setProductRegistryMetaTypes(meta_types+(mt,))
def _manage_remove_product_permission(self, product, permission=None):
r=[]
r2=[]
pid=product.id
for d in self._getProductRegistryData('permissions'):
if d.has_key('product'):
if d['product']==pid and (
permission is None or permission==d['name']):
continue
elif permission==d['name']: continue
r.append(d)
r2.append((d['name'], d['methods'], d['default']))
self._setProductRegistryData('permissions', tuple(r))
self._setProductRegistryData('ac_permissions', tuple(r2))
def _manage_add_product_permission(
self, product, permission, methods=(), default=('Manager',)
):
pid=product.id
permissions=self._getProductRegistryData('permissions')
for d in permissions:
if d['name']==permission:
if not d.has_key('product'): d['product']=pid
if d['product'] != pid:
raise 'Type Exists', (
'The permission <em>%s</em> is already defined.'
% permission)
d['methods']=methods
d['default']=default
return
d={'name': permission, 'methods': methods, 'default': default}
if permission: d['permission']=permission
self._setProductRegistryData('permissions', permissions+(d,))
self._setProductRegistryData(
'ac_permissions',
self._getProductRegistryData('ac_permissions')
+((d['name'], d['methods'], d['default']),)
)
class ProductRegistry(ProductRegistryMixin): class ProductRegistry(ProductRegistryMixin):
# This class implements a protocol for registering products that # This class implements a protocol for registering products that
# are defined through the web. It also provides methods for # are defined through the web. It also provides methods for
...@@ -155,10 +200,20 @@ class ProductRegistry(ProductRegistryMixin): ...@@ -155,10 +200,20 @@ class ProductRegistry(ProductRegistryMixin):
def _getProducts(self): return self.Control_Panel.Products def _getProducts(self): return self.Control_Panel.Products
_product_meta_types=() _product_meta_types=()
_product_permissions=()
_product_ac_permissions=()
def _getProductRegistryMetaTypes(self): return self._product_meta_types def _getProductRegistryMetaTypes(self): return self._product_meta_types
def _setProductRegistryMetaTypes(self, v): self._product_meta_types=v def _setProductRegistryMetaTypes(self, v): self._product_meta_types=v
def _getProductRegistryData(self, name):
return getattr(self, '_product_%s' % name)
def _setProductRegistryData(self, name, v):
name='_product_%s' % name
if hasattr(self, name):
return setattr(self, name, v)
else:
raise AttributeError, name
<html><head><title>Define a permission</title></head>
<body bgcolor="#FFFFFF" link="#000099" vlink="#555555" alink="#77003B">
<h2>Define a permission</h2>
<form action="manage_addPermission" method="POST">
<table cellspacing="2">
<tr>
<th align="LEFT" valign="TOP">Id</th>
<td align="LEFT" valign="TOP"><input type="TEXT" name="id"
size="40"></td>
</tr>
<tr>
<th align="LEFT" valign="TOP">Title</th>
<td align="LEFT" valign="TOP"><input type="TEXT" name="title"
size="40"></td>
</tr>
<tr>
<th align="LEFT" valign="TOP">Name</th>
<td align="LEFT" valign="TOP"><input type="TEXT" name="permission"
size="40"></td>
</tr>
<tr><td></td><td><br><input type="SUBMIT" value="Generate"></td></tr>
</table></form>
</body></html>
<html><head><title>Change a factory</title></head> <html><head><title>Change a factory</title></head>
<body bgcolor="#FFFFFF" link="#000099" vlink="#555555" alink="#77003B"> <body bgcolor="#FFFFFF" link="#000099" vlink="#555555" alink="#77003B">
<!--#var manage_tabs--> <dtml-var manage_tabs>
<form action="manage_edit" method="POST"> <form action="manage_edit" method="POST">
<table cellspacing="2"> <table cellspacing="2">
<tr> <tr>
<th align="LEFT" valign="TOP">Id</th> <th align="LEFT" valign="TOP">Id</th>
<td align="LEFT" valign="TOP"><!--#var id--></td> <td align="LEFT" valign="TOP"><dtml-var id></td>
</tr> </tr>
<tr> <tr>
<th align="LEFT" valign="TOP">Title</th> <th align="LEFT" valign="TOP">Title</th>
<td align="LEFT" valign="TOP"><input type="TEXT" name="title" <td align="LEFT" valign="TOP"><input type="TEXT" name="title"
size="40" value="<!--#var title-->"></td> size="40" value="<dtml-var title>"></td>
</tr> </tr>
<tr> <tr>
<th align="LEFT" valign="TOP">Add list name</th> <th align="LEFT" valign="TOP">Add list name</th>
<td align="LEFT" valign="TOP"><input type="TEXT" name="object_type" <td align="LEFT" valign="TOP"><input type="TEXT" name="object_type"
size="40" value="<!--#var object_type-->"></td> size="40" value="<dtml-var object_type>"></td>
</tr> </tr>
<tr><th ALIGN="LEFT">Method</th> <tr><th ALIGN="LEFT">Initial method</th>
<td ALIGN="LEFT"> <td ALIGN="LEFT">
<select name="initial"> <select name="initial">
<!--#in objectIds--> <dtml-in objectIds>
<option <option
<!--#if expr="_.string.strip(_['sequence-item'])==initial"-->SELECTED<!--#/if--> <dtml-if expr="_.string.strip(_['sequence-item'])==initial">
><!--#var sequence-item--></option> SELECTED</dtml-if>
<!--#/in--> ><dtml-var sequence-item></option>
</dtml-in>
</select></td></tr> </select></td></tr>
<tr>
<th align="LEFT" valign="TOP">Permission</th>
<td align="LEFT" valign="TOP">
<select name=permission>
<dtml-in possible_permissions>
<option
<dtml-if "_['sequence-item']==permission">selected</dtml-if>
><dtml-var sequence-item></option>
</dtml-in>
</select>
</td>
</tr>
<tr><td></td><td><br><input type="SUBMIT" value="Change"></td></tr> <tr><td></td><td><br><input type="SUBMIT" value="Change"></td></tr>
</table></form> </table></form>
The <strong>Method</strong> is the method that will be invoked when a The <strong>initial method</strong> is the method that will be invoked when a
user adds a new object. This must be one of the objects in the user adds a new object. This must be one of the objects in the
product, typically a Document. product, typically a Document.
......
<html><head><title>Change a permission</title></head>
<body bgcolor="#FFFFFF" link="#000099" vlink="#555555" alink="#77003B">
<!--#var manage_tabs-->
<form action="manage_edit" method="POST">
<table cellspacing="2">
<tr>
<th align="LEFT" valign="TOP">Id</th>
<td align="LEFT" valign="TOP"><!--#var id--></td>
</tr>
<tr>
<th align="LEFT" valign="TOP">Title</th>
<td align="LEFT" valign="TOP"><input type="TEXT" name="title"
size="40" value="<!--#var title-->"></td>
</tr>
<tr>
<th align="LEFT" valign="TOP">Name</th>
<td align="LEFT" valign="TOP"><input type="TEXT" name="name"
size="40" value="&dtml-name;"></td>
</tr>
<tr><td></td><td><br><input type="SUBMIT" value="Change"></td></tr>
</table></form>
</body></html>
...@@ -84,11 +84,11 @@ ...@@ -84,11 +84,11 @@
############################################################################## ##############################################################################
__doc__="""Object Manager __doc__="""Object Manager
$Id: ObjectManager.py,v 1.78 1999/07/19 05:58:34 amos Exp $""" $Id: ObjectManager.py,v 1.79 1999/07/21 13:17:43 jim Exp $"""
__version__='$Revision: 1.78 $'[11:-2] __version__='$Revision: 1.79 $'[11:-2]
import App.Management, Acquisition, App.Undo, Globals, CopySupport import App.Management, Acquisition, App.Undo, Globals, CopySupport, Products
import os, App.FactoryDispatcher, ts_regex, Products import os, App.FactoryDispatcher, ts_regex, Products
from Globals import HTMLFile, HTMLFile, Persistent from Globals import HTMLFile, HTMLFile, Persistent
from Globals import MessageDialog, default__class_init__ from Globals import MessageDialog, default__class_init__
...@@ -169,6 +169,12 @@ class ObjectManager( ...@@ -169,6 +169,12 @@ class ObjectManager(
except: pass except: pass
return self.meta_types+Products.meta_types+pmt return self.meta_types+Products.meta_types+pmt
def _subobject_permissions(self):
return (Products.__ac_permissions__+
self.aq_acquire('_getProductRegistryData')('ac_permissions')
)
def filtered_meta_types(self, user): def filtered_meta_types(self, user):
"Those meta types for which a user has adequite permissions." "Those meta types for which a user has adequite permissions."
meta_types=[] meta_types=[]
......
...@@ -89,8 +89,8 @@ Aqueduct database adapters, etc. ...@@ -89,8 +89,8 @@ Aqueduct database adapters, etc.
This module can also be used as a simple template for implementing new This module can also be used as a simple template for implementing new
item types. item types.
$Id: SimpleItem.py,v 1.60 1999/07/19 05:58:34 amos Exp $''' $Id: SimpleItem.py,v 1.61 1999/07/21 13:17:43 jim Exp $'''
__version__='$Revision: 1.60 $'[11:-2] __version__='$Revision: 1.61 $'[11:-2]
import regex, sys, Globals, App.Management, Acquisition import regex, sys, Globals, App.Management, Acquisition
from webdav.Resource import Resource from webdav.Resource import Resource
...@@ -318,20 +318,6 @@ class Item(Base, Resource, CopySource, App.Management.Tabs): ...@@ -318,20 +318,6 @@ class Item(Base, Resource, CopySource, App.Management.Tabs):
def __len__(self): def __len__(self):
return 1 return 1
def _isBeingUsedAsAMethod(self, REQUEST =None, wannaBe=0):
try:
if hasattr(self, 'aq_self'):
r=self.aq_acquire('_isBeingUsedAsAMethod_')
else:
r=self._isBeingUsedAsAMethod_
except: r=0
if REQUEST is not None:
if not r != (not wannaBe): REQUEST.response.notFoundError()
return r
Globals.default__class_init__(Item) Globals.default__class_init__(Item)
......
...@@ -114,6 +114,7 @@ class p_: ...@@ -114,6 +114,7 @@ class p_:
BrokenProduct_icon=ImageFile('App/www/brokenProduct.gif') BrokenProduct_icon=ImageFile('App/www/brokenProduct.gif')
Product_icon=ImageFile('App/www/product.gif') Product_icon=ImageFile('App/www/product.gif')
Factory_icon=ImageFile('App/www/factory.gif') Factory_icon=ImageFile('App/www/factory.gif')
Permission_icon=ImageFile('App/www/permission.gif')
ProductFolder_icon=ImageFile('App/www/productFolder.gif') ProductFolder_icon=ImageFile('App/www/productFolder.gif')
PyPoweredSmall_Gif=ImageFile('App/www/PythonPoweredSmall.gif') PyPoweredSmall_Gif=ImageFile('App/www/PythonPoweredSmall.gif')
......
...@@ -82,3 +82,4 @@ ...@@ -82,3 +82,4 @@
# attributions are listed in the accompanying credits file. # attributions are listed in the accompanying credits file.
# #
############################################################################## ##############################################################################
__ac_permissions__=()
...@@ -87,7 +87,7 @@ ...@@ -87,7 +87,7 @@
import Globals, OFS.PropertySheets, OFS.Image, ExtensionClass import Globals, OFS.PropertySheets, OFS.Image, ExtensionClass
from string import split, join, strip from string import split, join, strip
import Acquisition import Acquisition, Products
class ZClassBasicSheet(OFS.PropertySheets.PropertySheet, class ZClassBasicSheet(OFS.PropertySheets.PropertySheet,
OFS.PropertySheets.View): OFS.PropertySheets.View):
...@@ -98,7 +98,9 @@ class ZClassBasicSheet(OFS.PropertySheets.PropertySheet, ...@@ -98,7 +98,9 @@ class ZClassBasicSheet(OFS.PropertySheets.PropertySheet,
manage=Globals.HTMLFile('itemProp', globals()) manage=Globals.HTMLFile('itemProp', globals())
def manage_edit(self, meta_type='', icon='', file='', def manage_edit(self, meta_type='', icon='', file='',
class_id=None, title=None, REQUEST=None): class_id=None, title=None,
selected=(),
REQUEST=None):
"""Set basic item properties. """Set basic item properties.
""" """
if meta_type: self.setClassAttr('meta_type', meta_type) if meta_type: self.setClassAttr('meta_type', meta_type)
...@@ -237,53 +239,27 @@ class ZClassPermissionsSheet(OFS.PropertySheets.PropertySheet, ...@@ -237,53 +239,27 @@ class ZClassPermissionsSheet(OFS.PropertySheets.PropertySheet,
manage=Globals.HTMLFile('classPermissions', globals()) manage=Globals.HTMLFile('classPermissions', globals())
def manage_delete(self, selected=[], REQUEST=None): def possible_permissions(self):
"Remove some permissions" r=map(
perms=self.classDefinedPermissions() lambda p: p[0],
changed=0 Products.__ac_permissions__+
message=[] self.aq_acquire('_getProductRegistryData')('ac_permissions')
for s in selected:
if s in perms:
perms.remove(s)
changed=1
else: message.append('Invalid permission: %s' % s)
if changed:
self.setClassAttr(
'__ac_permissions__',
tuple(map(lambda p: (p,()), perms))
) )
else: r.sort()
message.append('Permissions are unchanged.') return r
if message: message=join(message, '<br>\n')
return self.manage(self, REQUEST, manage_tabs_message=message) def manage_edit(self, selected=[], REQUEST=None):
def manage_add(self, REQUEST, newPermission=''):
"Remove some permissions" "Remove some permissions"
perms=self.classDefinedPermissions() r=[]
aperms=perms+self.classInheritedPermissions() for p in (
changed=0 Products.__ac_permissions__+
message=[] self.aq_acquire('_getProductRegistryData')('ac_permissions')):
if p[0] in selected:
r.append(p)
newPermission=strip(newPermission) self.setClassAttr('__ac_permissions__', tuple(r))
if newPermission:
if newPermission in aperms:
message.append('The new permission, %s, is already in use'
% newPermission)
else:
perms.append(newPermission)
changed=1
if changed: return self.manage(self, REQUEST,
self.setClassAttr( manage_tabs_message="Permissions updated")
'__ac_permissions__',
tuple(map(lambda p: (p,()), perms))
)
else:
message.append('Permissions are unchanged.')
if message: message=join(message, '<br>\n')
return self.manage(self, REQUEST, manage_tabs_message=message)
...@@ -90,6 +90,7 @@ from AccessControl.Permission import pname ...@@ -90,6 +90,7 @@ from AccessControl.Permission import pname
from string import strip from string import strip
import App.Dialogs, ZClasses, App.Factory, App.Product, App.ProductRegistry import App.Dialogs, ZClasses, App.Factory, App.Product, App.ProductRegistry
from ZClassOwner import ZClassOwner from ZClassOwner import ZClassOwner
from AccessControl.PermissionMapping import aqwrap, PermissionMapper
_marker=[] _marker=[]
class ZClassMethodsSheet( class ZClassMethodsSheet(
...@@ -121,9 +122,9 @@ class ZClassMethodsSheet( ...@@ -121,9 +122,9 @@ class ZClassMethodsSheet(
) )
def manage_addPrincipiaFactory( def manage_addPrincipiaFactory(
self, id, title, object_type, initial, REQUEST=None): self, id, title, object_type, initial, permission=None, REQUEST=None):
' ' ' '
i=App.Factory.Factory(id, title, object_type, initial, self) i=App.Factory.Factory(id, title, object_type, initial, permission)
self._setObject(id,i) self._setObject(id,i)
if REQUEST is not None: if REQUEST is not None:
return self.manage_main(self,REQUEST,update_menu=1) return self.manage_main(self,REQUEST,update_menu=1)
...@@ -149,6 +150,8 @@ class ZClassMethodsSheet( ...@@ -149,6 +150,8 @@ class ZClassMethodsSheet(
if REQUEST is not None and wannaBe: REQUEST.response.notFoundError() if REQUEST is not None and wannaBe: REQUEST.response.notFoundError()
return 0 return 0
def permissionMappingPossibleValues(self):
return self.classDefinedAndInheritedPermissions()
def meta_type(self): def meta_type(self):
return self.aq_inner.aq_parent.aq_parent.meta_type return self.aq_inner.aq_parent.aq_parent.meta_type
...@@ -181,7 +184,7 @@ class ZClassMethodsSheet( ...@@ -181,7 +184,7 @@ class ZClassMethodsSheet(
return id+' ' return id+' '
def _setOb(self, id, object): def _setOb(self, id, object):
self.setClassAttr(strip(id), PermissionMapper(object)) self.setClassAttr(strip(id), MW(object))
def _delOb(self, id): def _delOb(self, id):
self.delClassAttr(strip(id)) self.delClassAttr(strip(id))
...@@ -197,18 +200,31 @@ class ZClassMethodsSheet( ...@@ -197,18 +200,31 @@ class ZClassMethodsSheet(
self._delOb(id) self._delOb(id)
def _getOb(self, id, default=_marker): def _getOb(self, id, default=_marker):
if default is _marker: r=self.getClassAttr(strip(id)) if default is _marker:
r=self.getClassAttr(strip(id))
else: else:
try: r=self.getClassAttr(strip(id)) try: r=self.getClassAttr(strip(id))
except: return default except: return default
if hasattr(r, methodattr): if hasattr(r, methodattr):
w=PermissionMapperManager(r) m=r.__dict__[methodattr]
self=w.__of__(self) if r.__class__ is W:
r=getattr(r, methodattr) # Ugh, we need to convert an old wrapper to a new one
wrapper=getattr(m, '_permissionMapper', None)
if wrapper is None: wrapper=PermissionMapper()
if hasattr(r,'aq_base'): r=r.aq_base for k, v in r.__dict__.items():
return r.__of__(self) if k[:1]=='_' and k[-11:]=='_Permission':
setattr(wrapper, k, v)
m._permissionMapper=wrapper
mw=MW(m)
self.setClassAttr(strip(id), mw)
r=m
return getattr(r, 'aq_base', r).__of__(self)
def __bobo_traverse__(self, request, name): def __bobo_traverse__(self, request, name):
if hasattr(self, 'aq_base'): if hasattr(self, 'aq_base'):
...@@ -218,6 +234,9 @@ class ZClassMethodsSheet( ...@@ -218,6 +234,9 @@ class ZClassMethodsSheet(
try: return self[name] try: return self[name]
except: return getattr(self, name) except: return getattr(self, name)
def possible_permissions(self):
return self.classDefinedAndInheritedPermissions()
default_dm_html='''<html> default_dm_html='''<html>
<head><title><!--#var document_title--></title></head> <head><title><!--#var document_title--></title></head>
<body bgcolor="#FFFFFF" LINK="#000099" VLINK="#555555"> <body bgcolor="#FFFFFF" LINK="#000099" VLINK="#555555">
...@@ -231,12 +250,31 @@ the <!--#var title_and_id--> Folder.</P> ...@@ -231,12 +250,31 @@ the <!--#var title_and_id--> Folder.</P>
methodattr='_ZClassMethodPermissionMapperMethod_' methodattr='_ZClassMethodPermissionMapperMethod_'
class W(Globals.Persistent): class MW(ExtensionClass.Base):
_View_Permission='_View_Permission'
def __init__(self, meth): self.__dict__[methodattr]=meth def __init__(self, meth): self.__dict__[methodattr]=meth
def __of__(self, parent):
m=getattr(self, methodattr)
m=self.__dict__[methodattr]
wrapper=getattr(m, '_permissionMapper', None)
if wrapper is None: wrapper=PermissionMapper()
if hasattr(m,'__of__'): return aqwrap(m, wrapper, parent)
return m
def findMethodIds(klass):
r=[]
for k, v in klass.__dict__.items():
if type(v) is W or type(v) is MW: r.append(k)
return r
# Backward compat. Waaaaa
class W(Globals.Persistent, MW):
_View_Permission='_View_Permission'
def __getattr__(self, name): def __getattr__(self, name):
# We want to make sure that any non-explicitly set methods are # We want to make sure that any non-explicitly set methods are
# private! # private!
...@@ -251,102 +289,6 @@ class W(Globals.Persistent): ...@@ -251,102 +289,6 @@ class W(Globals.Persistent):
def __of__(self, parent): def __of__(self, parent):
m=getattr(self, methodattr) m=getattr(self, methodattr)
m=self.__dict__[methodattr] m=self.__dict__[methodattr]
if hasattr(m,'__of__'): if hasattr(m,'__of__'): return aqwrap(m, self, parent)
r=Helper()
r._ugh=self, m, parent
return r
return m return m
PermissionMapper=W
class Helper(ExtensionClass.Base):
def __of__(self, parent):
w, m, p = self._ugh
return m.__of__(
Acquisition.ImplicitAcquisitionWrapper(
w, parent))
def __getattr__(self, name):
w, m, parent = self._ugh
self=m.__of__(
Acquisition.ImplicitAcquisitionWrapper(
w, parent))
return getattr(self, name)
def __call__(self, *args, **kw):
w, m, parent = self._ugh
self=m.__of__(
Acquisition.ImplicitAcquisitionWrapper(
w, parent))
return apply(self, args, kw)
class PermissionMapperManager(Acquisition.Implicit):
def __init__(self, wrapper): self._wrapper___=wrapper
def manage_getPermissionMapping(self):
"""Return the permission mapping for the object
This is a list of dictionaries with:
permission_name -- The name of the native object permission
class_permission -- The class permission the permission is
mapped to.
"""
wrapper=self.__dict__['_wrapper___']
method=getattr(wrapper, methodattr)
# ugh
perms={}
for p in self.classDefinedAndInheritedPermissions():
perms[pname(p)]=p
r=[]
a=r.append
for ac_perms in method.ac_inherited_permissions(1):
p=perms.get(getPermissionMapping(ac_perms[0], wrapper), '')
a({'permission_name': ac_perms[0], 'class_permission': p})
return r
def manage_setPermissionMapping(trueself, self,
permission_names=[],
class_permissions=[], REQUEST=None):
"""Change the permission mapping
"""
wrapper=trueself.__dict__['_wrapper___']
perms=trueself.classDefinedAndInheritedPermissions()
for i in range(len(permission_names)):
name=permission_names[i]
p=class_permissions[i]
if p and (p not in perms):
__traceback_info__=perms, p, i
raise 'waaa'
p=''
setPermissionMapping(name, wrapper, p)
if REQUEST is not None:
return self.manage_access(
self, REQUEST,
manage_tabs_message='The permission mapping has been updated')
def getPermissionMapping(name, obj, st=type('')):
if hasattr(obj, 'aq_base'): obj=obj.aq_base
name=pname(name)
r=getattr(obj, name)
if type(r) is not st: r=''
return r
def setPermissionMapping(name, obj, v):
name=pname(name)
if v: setattr(obj, name, pname(v))
elif obj.__dict__.has_key(name): delattr(obj, name)
def findMethodIds(klass):
r=[]
for k, v in klass.__dict__.items():
if type(v) is PermissionMapper: r.append(k)
return r
...@@ -204,7 +204,8 @@ class ZClass(OFS.SimpleItem.SimpleItem): ...@@ -204,7 +204,8 @@ class ZClass(OFS.SimpleItem.SimpleItem):
isPrincipiaFolderish=1 isPrincipiaFolderish=1
__ac_permissions__=( __ac_permissions__=(
('View', ('', '__call__', 'index_html') ), ('Create class instances',
('', '__call__', 'index_html', 'createInObjectManager')),
) )
def __init__(self, id, title, bases): def __init__(self, id, title, bases):
......
...@@ -3,35 +3,38 @@ ...@@ -3,35 +3,38 @@
<!--#if manage_tabs--> <!--#if manage_tabs-->
<!--#var manage_tabs--> <!--#var manage_tabs-->
<!--#/if manage_tabs--> <!--#/if manage_tabs-->
<p>
Use this view to select permissions used by this class.
When setting permissions for individual methods or property sheets,
you will be able to select from class permissions and inherited permissions.
<form action=.>
<table>
<tr><td></td><th align=left>Permissions:</th></tr>
<!--#in classDefinedPermissions sort-->
<tr>
<td><input type=checkbox name=selected:list
value="<!--#var sequence-item-->"></td>
<td><!--#var sequence-item--></td>
</tr>
<!--#/in-->
<tr><td></td><td>
<input type=submit value=" Delete " name="manage_delete:method">
</td></tr>
</table>
</form>
<form action=manage_add>
Add a new permission:<br>
<input name=newPermission>
<input type=submit value=" Add ">
</form>
<form action="manage_edit">
<table> <table>
<tr><th align=left>Inherited Permissions:</th></tr> <tr><th align=left>Class permissions</th>
<td align=left>Inherited permissions</th>
</tr>
<tr>
<td>
<dtml-let selected=classDefinedPermissions>
<select name="selected:list" multiple size=9>
<dtml-in possible_permissions>
<option
<dtml-if "_['sequence-item'] in selected">selected</dtml-if>
>&dtml-sequence-item;</option>
</dtml-in>
</select>
</dtml-let>
<br>
<input type=submit value=" Change ">
</td>
<td valign=top>
<!--#in classInheritedPermissions sort--> <!--#in classInheritedPermissions sort-->
<tr><td><em><!--#var sequence-item--></em></td></tr> <em><!--#var sequence-item--></em><br>
<!--#/in--> <!--#/in-->
</td>
</tr>
</table> </table>
</form>
</body></html> </body></html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment