[Erp5-report] r19218 - /erp5/trunk/products/ERP5/Document/WebSection.py
nobody at svn.erp5.org
nobody at svn.erp5.org
Sun Feb 10 18:27:16 CET 2008
Author: jp
Date: Sun Feb 10 18:27:16 2008
New Revision: 19218
URL: http://svn.erp5.org?rev=19218&view=rev
Log:
Reimplemented permanent URLs as it should have been: with __bobo_traverse__. We do not need anylonger with this to specify the webmaster as we did. Security is taken into account to access permanent URL documents. One remaining issue: support of transactional cache in __bobo_traverse__.
Modified:
erp5/trunk/products/ERP5/Document/WebSection.py
Modified: erp5/trunk/products/ERP5/Document/WebSection.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/WebSection.py?rev=19218&r1=19217&r2=19218&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/WebSection.py (original)
+++ erp5/trunk/products/ERP5/Document/WebSection.py Sun Feb 10 18:27:16 2008
@@ -1,6 +1,15 @@
##############################################################################
#
+# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
# Copyright (c) 2002-2006 Nexedi SARL and Contributors. All Rights Reserved.
+# Copyright (c) 2006-2007 Nexedi SA and Contributors. All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (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.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
@@ -8,20 +17,6 @@
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
-#
-# This program is Free Software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
@@ -37,44 +32,13 @@
from Globals import get_request
from zLOG import LOG, WARNING
+import sys
from Products.ERP5Type.Cache import getReadOnlyTransactionCache
# Global keys used for URL generation
WEBSECTION_KEY = 'web_section_value'
-WEBSITE_USER = 'web_site_user'
-
-Domain_getattr = Domain.inheritedAttribute('__getattr__')
-
-# We use a request key (CACHE_KEY) to store access attributes and prevent infinite recursion
-# We define a couple of reserved names for which we are not
-# going to try to do acquisition
-CACHE_KEY = 'web_site_aq_cache'
-DOCUMENT_NAME_KEY = 'web_section_document_name'
-reserved_name_dict = { 'getApplicableLayout' : 1,
- 'getWebmaster' : 1,
- 'getContainerLayout': 1,
- 'isWebMode' : 1,
- 'getLayout' : 1,
- 'Localizer' : 1,
- 'field_render' : 1,
- 'getListItemUrl' : 1,
- 'getLocalPropertyManager' : 1,
- 'getOrderedGlobalActionList' : 1,
- 'allow_discussion' : 1,
- 'im_func' : 1,
- 'im_self' : 1,
- 'ListBox_asHTML' : 1,
- 'id' : 1,
- 'method_id' : 1,
- 'role_map' : 1,
- 'func_defaults': 1,
- '_v_section_webmaster': 1,
- 'priority': 1,
- 'to_processing_date': 1,
- 'categories': 1,
- }
-reserved_name_dict_init = 0
+MARKER = []
class WebSection(Domain):
"""
@@ -129,17 +93,14 @@
web_section_key = WEBSECTION_KEY
- def _aq_dynamic(self, name):
- """
- Try to find a suitable document based on the
- web site local naming policies as defined by
- the getDocumentValue method
- """
- global reserved_name_dict_init
- global reserved_name_dict
- request = self.REQUEST
+ security.declareProtected(Permissions.View, '__bobo_traverse__')
+ def __bobo_traverse__(self, request, name):
+ """
+ If no subobject is found through Folder API
+ then try to lookup the object by invoking getDocumentValue
+ """
# Register current web site physical path for later URL generation
- if not request.has_key(self.web_section_key):
+ if request.get(self.web_section_key, MARKER) is MARKER:
request[self.web_section_key] = self.getPhysicalPath()
# Normalize web parameter in the request
# Fix common user mistake and transform '1' string to boolean
@@ -149,66 +110,83 @@
request.set(web_param, True)
else:
request.set(web_param, False)
- # First let us call the super method
- dynamic = Domain._aq_dynamic(self, name)
- if dynamic is not None:
- return dynamic
- # Do some optimisation here for names which can not be names of documents
- if reserved_name_dict.has_key(name) \
- or name.endswith('_getDocumentValue') \
- or name.startswith('_') or name.startswith('portal_')\
- or name.startswith('aq_') or name.startswith('selection_') \
- or name.startswith('sort-') or name.startswith('WebSite_') \
- or name.startswith('WebSection_') or name.startswith('Base_'):
- return None
- if not reserved_name_dict_init:
- # Feed reserved_name_dict_init with skin names
- portal = self.getPortalObject()
- for skin_folder in portal.portal_skins.objectValues():
- for id in skin_folder.objectIds():
- reserved_name_dict[id] = 1
- for id in portal.objectIds():
- reserved_name_dict[id] = 1
- reserved_name_dict_init = 1
- #LOG('aq_dynamic name',0, name)
- if not request.has_key(CACHE_KEY):
- request[CACHE_KEY] = {}
- elif request[CACHE_KEY].has_key(name):
- return request[CACHE_KEY][name]
+
+ # Normal traversal
try:
- portal = self.getPortalObject()
- # Use the webmaster identity to find documents
- if request[CACHE_KEY].has_key(WEBSITE_USER):
- user = request[CACHE_KEY][WEBSITE_USER] # Retrieve user from request cache
- else:
- # Cache webmaster for faster lookup
- if not hasattr(aq_base(self), '_v_section_webmaster'):
- self._v_section_webmaster = self.getWebmaster()
- user = portal.acl_users.getUserById(self._v_section_webmaster)
- request[CACHE_KEY][WEBSITE_USER] = user # Cache user per request
- if user is not None:
- old_manager = getSecurityManager()
- newSecurityManager(get_request(), user)
- else:
- LOG('WebSection _aq_dynamic', WARNING, 'No user defined for %s.'
- 'This will prevent accessing object through their permanent URL' % self.getWebmaster())
- #LOG('Lookup', 0, str(name))
- document = self.getDocumentValue(name=name, portal=portal)
- request[CACHE_KEY][name] = document
- if user is not None:
- setSecurityManager(old_manager)
- except:
- # Cleanup non recursion dict in case of exception
- if request[CACHE_KEY].has_key(name):
- del request[CACHE_KEY][name]
- raise
+ return getattr(self, name)
+ except AttributeError:
+ pass
+
+ try:
+ return self[name]
+ except KeyError:
+ pass
+
+ # Permanent URL traversal
+ # First we must get the logged user by forcing identification
+ cache = getReadOnlyTransactionCache(self)
+ # LOG('getReadOnlyTransactionCache', 0, repr(cache)) # Currently, it is always None
+ if cache is not None:
+ key = ('__bobo_traverse__', self, 'user')
+ try:
+ user = cache[key]
+ except KeyError:
+ user = MARKER
+ else:
+ user = MARKER
+ old_user = getSecurityManager().getUser()
+ if user is MARKER:
+ user = None # By default, do nothing
+ if old_user is None or old_user.getUserName() == 'Anonymous User':
+ user_folder = getToolByName(self, 'acl_users', None)
+ if user_folder is not None:
+ try:
+ if request.get('PUBLISHED', MARKER) is MARKER:
+ # request['PUBLISHED'] is required by validate
+ request.other['PUBLISHED'] = self
+ has_published = False
+ else:
+ has_published = True
+ user = user_folder.validate(request)
+ if not has_published:
+ del request.other['PUBLISHED']
+ except:
+ LOG("ERP5 WARNING",0,
+ "Failed to retrieve user in __bobo_traverse__ of WebSection %s" % self.getPath(),
+ error=sys.exc_info())
+ user = None
+ if user is not None and user.getUserName() == 'Anonymous User':
+ user = None # If the user which is connected is anonymous,
+ # do not try to change SecurityManager
+ if cache is not None:
+ cache[key] = user
+ if user is not None:
+ # We need to perform identification
+ old_manager = getSecurityManager()
+ newSecurityManager(get_request(), user)
+ # Next get the document per name
+ portal = self.getPortalObject()
+ document = self.getDocumentValue(name=name, portal=portal)
+ # Last, cleanup everything
+ if user is not None:
+ setSecurityManager(old_manager)
if document is not None:
- request[DOCUMENT_NAME_KEY] = name
- document = aq_base(document.asContext(id=name, # Hide some properties to permit location the original
+ document = aq_base(document.asContext(id=name, # Hide some properties to permit locating the original
original_container=document.getParentValue(),
original_id=document.getId(),
editable_absolute_url=document.absolute_url()))
- return document
+ return document.__of__(self)
+
+ # Not found section
+ method = request.get('REQUEST_METHOD', 'GET')
+ if not method in ('GET', 'POST'):
+ return NullResource(self, name, request).__of__(self)
+ # Waaa. unrestrictedTraverse calls us with a fake REQUEST.
+ # There is proabably a better fix for this.
+ try:
+ request.RESPONSE.notFoundError("%s\n%s" % (name, method))
+ except AttributeError:
+ raise KeyError, name
security.declareProtected(Permissions.AccessContentsInformation, 'getWebSectionValue')
def getWebSectionValue(self):
@@ -303,7 +281,7 @@
fallback_script_id='WebSection_getDocumentValue')
if cache is not None:
- if not cache.has_key(key): cache[key] = method
+ if cache.get(key, MARKER) is MARKER: cache[key] = method
return method(name, portal=portal, **kw)
More information about the Erp5-report
mailing list