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

Added prodct-defined permissions and product permission mapping

parent 9c1817e4
......@@ -85,8 +85,8 @@
__doc__='''short description
$Id: Permission.py,v 1.5 1999/03/22 16:49:40 jim Exp $'''
__version__='$Revision: 1.5 $'[11:-2]
$Id: Permission.py,v 1.6 1999/07/21 13:13:28 jim Exp $'''
__version__='$Revision: 1.6 $'[11:-2]
from Globals import HTMLFile, MessageDialog
from string import join, strip, split, find
......@@ -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):
return '_'+translate(name,name_trans)+"_Permission"
_marker=[]
class Permission:
# A Permission maps a named logical permission to a set
# of attribute names. Attribute names which appear in a
# permission may not appear in any other permission defined
# by the object.
def __init__(self,name,data,obj):
def __init__(self,name,data,obj,default=None):
self.name=name
self._p='_'+string.translate(name,name_trans)+"_Permission"
self.data=data
if hasattr(obj, 'aq_base'): obj=obj.aq_base
self.obj=obj
self.default=default
def getRoles(self):
def getRoles(self, default=_marker):
# Return the list of role names which have been given
# this permission for the object in question. To do
# this, we try to get __roles__ from all of the object
......@@ -124,7 +126,7 @@ class Permission:
obj=self.obj
name=self._p
if hasattr(obj, name): return getattr(obj, name)
roles=[]
roles=default
for name in self.data:
if name:
if hasattr(obj, name):
......@@ -152,6 +154,7 @@ class Permission:
except: return []
if roles is None: return ['Manager','Anonymous']
if roles is _marker: return ['Manager']
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 @@
__doc__='''Objects that implement Permission-based roles.
$Id: PermissionRole.py,v 1.6 1999/06/16 19:41:14 jim Exp $'''
__version__='$Revision: 1.6 $'[11:-2]
$Id: PermissionRole.py,v 1.7 1999/07/21 13:13:28 jim Exp $'''
__version__='$Revision: 1.7 $'[11:-2]
import sys
......@@ -98,7 +98,7 @@ name_trans=filter(lambda c, an=string.letters+string.digits+'_': c not in an,
map(chr,range(256)))
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
"""
im=imPermissionRole()
......
......@@ -84,19 +84,19 @@
##############################################################################
"""Access control support"""
__version__='$Revision: 1.33 $'[11:-2]
__version__='$Revision: 1.34 $'[11:-2]
from Globals import HTMLFile, MessageDialog, Dictionary
from string import join, strip, split, find
from Acquisition import Implicit
import Globals, ExtensionClass
import Globals, ExtensionClass, PermissionMapping, Products
from Permission import Permission
from App.Common import aq_base
ListType=type([])
class RoleManager(ExtensionClass.Base):
class RoleManager(ExtensionClass.Base, PermissionMapping.RoleManager):
"""An obect that has configurable permissions"""
__ac_permissions__=(
......@@ -132,8 +132,15 @@ class RoleManager(ExtensionClass.Base):
r=gather_permissions(self.__class__, [], d)
if all:
r=list(perms)+r
r.sort()
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.sort()
return tuple(r)
......@@ -494,6 +501,16 @@ class RoleManager(ExtensionClass.Base):
def _setRoles(self,acl_type,acl_roles):
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)
......
......@@ -5,7 +5,7 @@
<!--#/if manage_tabs-->
<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">
<table>
<tr><th align=left>Permission</th>
......
......@@ -84,36 +84,50 @@
##############################################################################
__doc__='''Principia Factories
$Id: Factory.py,v 1.12 1999/07/13 13:40:40 jim Exp $'''
__version__='$Revision: 1.12 $'[11:-2]
$Id: Factory.py,v 1.13 1999/07/21 13:15:23 jim Exp $'''
__version__='$Revision: 1.13 $'[11:-2]
import OFS.SimpleItem, Acquisition, Globals
import Product
import OFS.SimpleItem, Acquisition, Globals, AccessControl.Role
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"
meta_type='Zope Factory'
icon='p_/Factory_icon'
permission='' # Waaaa
_setObject=Acquisition.Acquired
__ac_permissions__=(
('Edit Factories', ('manage_edit','manage_main')),
('Use Factories', ('index_html','')),
)
manage_options=(
{'label':'Edit', 'action':'manage_main'},
{'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.title=title
self.object_type=object_type
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."
self._unregister()
self.title=title
self.object_type=object_type
self.initial=initial
self.permission=permission
self.manage_setPermissionMapping(('Use Factories',), (permission,))
self._register()
if REQUEST is not None: return self.manage_main(self, REQUEST)
......@@ -141,7 +155,7 @@ class Factory(Globals.Persistent, Acquisition.Implicit, OFS.SimpleItem.Item):
# Register with the product folder
product=self.aq_parent
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):
# Unregister with the product folder
......@@ -161,7 +175,5 @@ class Factory(Globals.Persistent, Acquisition.Implicit, OFS.SimpleItem.Item):
self.aq_parent.objectIds()
)
class ProductFactory(Factory): pass
......@@ -87,6 +87,7 @@
# Implement the manage_addProduct method of object managers
import Acquisition, sys
from string import rfind
from AccessControl.PermissionMapping import aqwrap
class ProductDispatcher(Acquisition.Implicit):
" "
......@@ -129,7 +130,12 @@ class FactoryDispatcher(Acquisition.Implicit):
p=self.__dict__['_product']
d=p.__dict__
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
m='Products.%s' % p.id
......@@ -149,6 +155,11 @@ class FactoryDispatcher(Acquisition.Implicit):
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 @@
# 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
import regex, zlib, Globals, cPickle, marshal, rotor
from string import rfind, atoi, find, strip, join
from Factory import Factory
from Permission import PermissionManager
import ZClasses, ZClasses.ZClass
class ProductFolder(Folder):
......@@ -145,7 +146,7 @@ class ProductFolder(Folder):
def _canCopy(self, op=0):
return 0
class Product(Folder):
class Product(Folder, PermissionManager):
"""Model a product that can be created through the web.
"""
meta_type='Product'
......@@ -153,6 +154,7 @@ class Product(Folder):
version=''
configurable_objects_=()
import_error_=None
_isBeingUsedAsAMethod_=1
def new_version(self,
_intending=regex.compile("[.]?[0-9]+$").search, #TS
......@@ -166,7 +168,7 @@ class Product(Folder):
meta_types=(
ZClasses.meta_types+
ZClasses.meta_types+PermissionManager.meta_types+
(
{
'name': Factory.meta_type,
......@@ -197,9 +199,9 @@ class Product(Folder):
manage_addPrincipiaFactoryForm=Globals.HTMLFile('addFactory',globals())
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)
if REQUEST is not None:
return self.manage_main(self,REQUEST,update_menu=1)
......@@ -309,6 +311,9 @@ class Product(Folder):
)).read()
except: return ''
def permissionMappingPossibleValues(self):
return self.possible_permissions()
class CompressedOutputFile:
def __init__(self, rot):
self._c=zlib.compressobj()
......
......@@ -156,7 +156,7 @@ class ProductContext:
OM=OFS.ObjectManager.ObjectManager
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:
permission="Add %ss" % (meta_type or instance_class.meta_type)
......@@ -178,7 +178,8 @@ class ProductContext:
if not perms.has_key(p):
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):
setattr(Globals.ApplicationDefaultPermissions,
pr_._p, default)
......
......@@ -144,6 +144,51 @@ class ProductRegistryMixin:
if permission: mt['permission']=permission
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):
# This class implements a protocol for registering products that
......@@ -155,10 +200,20 @@ class ProductRegistry(ProductRegistryMixin):
def _getProducts(self): return self.Control_Panel.Products
_product_meta_types=()
_product_permissions=()
_product_ac_permissions=()
def _getProductRegistryMetaTypes(self): return self._product_meta_types
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>
<body bgcolor="#FFFFFF" link="#000099" vlink="#555555" alink="#77003B">
<!--#var manage_tabs-->
<dtml-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>
<td align="LEFT" valign="TOP"><dtml-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>
size="40" value="<dtml-var title>"></td>
</tr>
<tr>
<th align="LEFT" valign="TOP">Add list name</th>
<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><th ALIGN="LEFT">Method</th>
<tr><th ALIGN="LEFT">Initial method</th>
<td ALIGN="LEFT">
<select name="initial">
<!--#in objectIds-->
<dtml-in objectIds>
<option
<!--#if expr="_.string.strip(_['sequence-item'])==initial"-->SELECTED<!--#/if-->
><!--#var sequence-item--></option>
<!--#/in-->
<dtml-if expr="_.string.strip(_['sequence-item'])==initial">
SELECTED</dtml-if>
><dtml-var sequence-item></option>
</dtml-in>
</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>
</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
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 @@
##############################################################################
__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
from Globals import HTMLFile, HTMLFile, Persistent
from Globals import MessageDialog, default__class_init__
......@@ -169,6 +169,12 @@ class ObjectManager(
except: pass
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):
"Those meta types for which a user has adequite permissions."
meta_types=[]
......
......@@ -89,8 +89,8 @@ Aqueduct database adapters, etc.
This module can also be used as a simple template for implementing new
item types.
$Id: SimpleItem.py,v 1.60 1999/07/19 05:58:34 amos Exp $'''
__version__='$Revision: 1.60 $'[11:-2]
$Id: SimpleItem.py,v 1.61 1999/07/21 13:17:43 jim Exp $'''
__version__='$Revision: 1.61 $'[11:-2]
import regex, sys, Globals, App.Management, Acquisition
from webdav.Resource import Resource
......@@ -317,21 +317,7 @@ class Item(Base, Resource, CopySource, App.Management.Tabs):
def __len__(self):
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)
......
......@@ -114,6 +114,7 @@ class p_:
BrokenProduct_icon=ImageFile('App/www/brokenProduct.gif')
Product_icon=ImageFile('App/www/product.gif')
Factory_icon=ImageFile('App/www/factory.gif')
Permission_icon=ImageFile('App/www/permission.gif')
ProductFolder_icon=ImageFile('App/www/productFolder.gif')
PyPoweredSmall_Gif=ImageFile('App/www/PythonPoweredSmall.gif')
......
......@@ -82,3 +82,4 @@
# attributions are listed in the accompanying credits file.
#
##############################################################################
__ac_permissions__=()
......@@ -87,7 +87,7 @@
import Globals, OFS.PropertySheets, OFS.Image, ExtensionClass
from string import split, join, strip
import Acquisition
import Acquisition, Products
class ZClassBasicSheet(OFS.PropertySheets.PropertySheet,
OFS.PropertySheets.View):
......@@ -98,7 +98,9 @@ class ZClassBasicSheet(OFS.PropertySheets.PropertySheet,
manage=Globals.HTMLFile('itemProp', globals())
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.
"""
if meta_type: self.setClassAttr('meta_type', meta_type)
......@@ -237,53 +239,27 @@ class ZClassPermissionsSheet(OFS.PropertySheets.PropertySheet,
manage=Globals.HTMLFile('classPermissions', globals())
def manage_delete(self, selected=[], REQUEST=None):
"Remove some permissions"
perms=self.classDefinedPermissions()
changed=0
message=[]
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:
message.append('Permissions are unchanged.')
if message: message=join(message, '<br>\n')
return self.manage(self, REQUEST, manage_tabs_message=message)
def possible_permissions(self):
r=map(
lambda p: p[0],
Products.__ac_permissions__+
self.aq_acquire('_getProductRegistryData')('ac_permissions')
)
r.sort()
return r
def manage_add(self, REQUEST, newPermission=''):
def manage_edit(self, selected=[], REQUEST=None):
"Remove some permissions"
perms=self.classDefinedPermissions()
aperms=perms+self.classInheritedPermissions()
changed=0
message=[]
r=[]
for p in (
Products.__ac_permissions__+
self.aq_acquire('_getProductRegistryData')('ac_permissions')):
if p[0] in selected:
r.append(p)
self.setClassAttr('__ac_permissions__', tuple(r))
return self.manage(self, REQUEST,
manage_tabs_message="Permissions updated")
newPermission=strip(newPermission)
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:
self.setClassAttr(
'__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
from string import strip
import App.Dialogs, ZClasses, App.Factory, App.Product, App.ProductRegistry
from ZClassOwner import ZClassOwner
from AccessControl.PermissionMapping import aqwrap, PermissionMapper
_marker=[]
class ZClassMethodsSheet(
......@@ -121,9 +122,9 @@ class ZClassMethodsSheet(
)
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)
if REQUEST is not None:
return self.manage_main(self,REQUEST,update_menu=1)
......@@ -149,6 +150,8 @@ class ZClassMethodsSheet(
if REQUEST is not None and wannaBe: REQUEST.response.notFoundError()
return 0
def permissionMappingPossibleValues(self):
return self.classDefinedAndInheritedPermissions()
def meta_type(self):
return self.aq_inner.aq_parent.aq_parent.meta_type
......@@ -181,7 +184,7 @@ class ZClassMethodsSheet(
return id+' '
def _setOb(self, id, object):
self.setClassAttr(strip(id), PermissionMapper(object))
self.setClassAttr(strip(id), MW(object))
def _delOb(self, id):
self.delClassAttr(strip(id))
......@@ -197,18 +200,31 @@ class ZClassMethodsSheet(
self._delOb(id)
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:
try: r=self.getClassAttr(strip(id))
except: return default
if hasattr(r, methodattr):
w=PermissionMapperManager(r)
self=w.__of__(self)
r=getattr(r, methodattr)
m=r.__dict__[methodattr]
if r.__class__ is W:
# 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
return r.__of__(self)
for k, v in r.__dict__.items():
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):
if hasattr(self, 'aq_base'):
......@@ -218,6 +234,9 @@ class ZClassMethodsSheet(
try: return self[name]
except: return getattr(self, name)
def possible_permissions(self):
return self.classDefinedAndInheritedPermissions()
default_dm_html='''<html>
<head><title><!--#var document_title--></title></head>
<body bgcolor="#FFFFFF" LINK="#000099" VLINK="#555555">
......@@ -231,11 +250,30 @@ the <!--#var title_and_id--> Folder.</P>
methodattr='_ZClassMethodPermissionMapperMethod_'
class W(Globals.Persistent):
_View_Permission='_View_Permission'
class MW(ExtensionClass.Base):
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):
# We want to make sure that any non-explicitly set methods are
......@@ -251,102 +289,6 @@ class W(Globals.Persistent):
def __of__(self, parent):
m=getattr(self, methodattr)
m=self.__dict__[methodattr]
if hasattr(m,'__of__'):
r=Helper()
r._ugh=self, m, parent
return r
if hasattr(m,'__of__'): return aqwrap(m, self, parent)
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):
isPrincipiaFolderish=1
__ac_permissions__=(
('View', ('', '__call__', 'index_html') ),
('Create class instances',
('', '__call__', 'index_html', 'createInObjectManager')),
)
def __init__(self, id, title, bases):
......
......@@ -3,35 +3,38 @@
<!--#if manage_tabs-->
<!--#var 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>
<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-->
<tr><td><em><!--#var sequence-item--></em></td></tr>
<em><!--#var sequence-item--></em><br>
<!--#/in-->
</td>
</tr>
</table>
</form>
</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