[Erp5-report] r37065 jm - in /erp5/trunk: bt5/erp5_base/SkinTemplateItem/portal_skins/erp5_...

nobody at svn.erp5.org nobody at svn.erp5.org
Mon Jul 12 19:06:15 CEST 2010


Author: jm
Date: Mon Jul 12 19:06:13 2010
New Revision: 37065

URL: http://svn.erp5.org?rev=37065&view=rev
Log:
Reimplement ERP5Site_getAuthenticatedMemberPersonValue without using acl_users.erp5_users

Because some sites don't have an 'erp5_users' plugin in acl_users, and what
ERP5Site_getAuthenticatedMemberPersonValue does is not specific to 'erp5_users'.

This is done by moving code outside ERP5UserManager class so that it can be
reused. Changes to ERP5UserManager.getUserLogin method are:
- use a transactional cache instead of erp5_content_short:
  - a transactional cache is enough because authenticateCredentials already
    caches its result in erp5_content_short
  - no need to care about empty result from the catalog, which was done using
    _AuthenticationFailure (instead, we simply return an empty list)
  - cache person objects instead of their path
- no need to use SUPER_USER since we use unrestrictedSearchResults

Modified:
    erp5/trunk/bt5/erp5_base/SkinTemplateItem/portal_skins/erp5_base/Base_getOwnerTitle.xml
    erp5/trunk/bt5/erp5_base/SkinTemplateItem/portal_skins/erp5_base/ERP5Site_getAuthenticatedMemberPersonValue.xml
    erp5/trunk/bt5/erp5_base/bt/revision
    erp5/trunk/products/ERP5Security/ERP5UserManager.py
    erp5/trunk/products/ERP5Security/__init__.py

Modified: erp5/trunk/bt5/erp5_base/SkinTemplateItem/portal_skins/erp5_base/Base_getOwnerTitle.xml
URL: http://svn.erp5.org/erp5/trunk/bt5/erp5_base/SkinTemplateItem/portal_skins/erp5_base/Base_getOwnerTitle.xml?rev=37065&r1=37064&r2=37065&view=diff
==============================================================================
--- erp5/trunk/bt5/erp5_base/SkinTemplateItem/portal_skins/erp5_base/Base_getOwnerTitle.xml [utf8] (original)
+++ erp5/trunk/bt5/erp5_base/SkinTemplateItem/portal_skins/erp5_base/Base_getOwnerTitle.xml [utf8] Mon Jul 12 19:06:13 2010
@@ -57,11 +57,10 @@
 """\n
 owner_id_list = [i[0] for i in context.get_local_roles() if \'Owner\' in i[1]]\n
 if owner_id_list:\n
-  found_user_list = context.acl_users.erp5_users.getUserByLogin(owner_id_list[0])\n
+  from Products.ERP5Security.ERP5UserManager import getUserByLogin\n
+  found_user_list = getUserByLogin(context.getPortalObject(), tuple(owner_id_list))\n
   if found_user_list:\n
     return found_user_list[0].getTitle()\n
-\n
-return owner\n
 </string> </value>
         </item>
         <item>
@@ -106,8 +105,10 @@ return owner\n
                             <string>i</string>
                             <string>_getitem_</string>
                             <string>owner_id_list</string>
+                            <string>Products.ERP5Security.ERP5UserManager</string>
+                            <string>getUserByLogin</string>
+                            <string>tuple</string>
                             <string>found_user_list</string>
-                            <string>owner</string>
                           </tuple>
                         </value>
                     </item>

Modified: erp5/trunk/bt5/erp5_base/SkinTemplateItem/portal_skins/erp5_base/ERP5Site_getAuthenticatedMemberPersonValue.xml
URL: http://svn.erp5.org/erp5/trunk/bt5/erp5_base/SkinTemplateItem/portal_skins/erp5_base/ERP5Site_getAuthenticatedMemberPersonValue.xml?rev=37065&r1=37064&r2=37065&view=diff
==============================================================================
--- erp5/trunk/bt5/erp5_base/SkinTemplateItem/portal_skins/erp5_base/ERP5Site_getAuthenticatedMemberPersonValue.xml [utf8] (original)
+++ erp5/trunk/bt5/erp5_base/SkinTemplateItem/portal_skins/erp5_base/ERP5Site_getAuthenticatedMemberPersonValue.xml [utf8] Mon Jul 12 19:06:13 2010
@@ -56,15 +56,14 @@
             <value> <string>"""Find and returns Person object for current logged in user.\n
 Returns None if no corresponding person, for example when not using ERP5Security.ERP5UserManager.\n
 """\n
+portal = context.getPortalObject()\n
 if user_name is None:\n
-  user_name = context.portal_membership.getAuthenticatedMember()\n
+  user_name = portal.portal_membership.getAuthenticatedMember()\n
 \n
-found_user_list = context.acl_users.erp5_users.getUserByLogin(str(user_name))\n
-found_users = len(found_user_list)\n
-if found_users != 1:\n
-  return None\n
-\n
-return found_user_list[0]\n
+from Products.ERP5Security.ERP5UserManager import getUserByLogin\n
+found_user_list = getUserByLogin(portal, str(user_name))\n
+if len(found_user_list) == 1:\n
+  return found_user_list[0]\n
 </string> </value>
         </item>
         <item>
@@ -110,13 +109,15 @@ return found_user_list[0]\n
                         <value>
                           <tuple>
                             <string>user_name</string>
-                            <string>None</string>
                             <string>_getattr_</string>
                             <string>context</string>
+                            <string>portal</string>
+                            <string>None</string>
+                            <string>Products.ERP5Security.ERP5UserManager</string>
+                            <string>getUserByLogin</string>
                             <string>str</string>
                             <string>found_user_list</string>
                             <string>len</string>
-                            <string>found_users</string>
                             <string>_getitem_</string>
                           </tuple>
                         </value>

Modified: erp5/trunk/bt5/erp5_base/bt/revision
URL: http://svn.erp5.org/erp5/trunk/bt5/erp5_base/bt/revision?rev=37065&r1=37064&r2=37065&view=diff
==============================================================================
--- erp5/trunk/bt5/erp5_base/bt/revision [utf8] (original)
+++ erp5/trunk/bt5/erp5_base/bt/revision [utf8] Mon Jul 12 19:06:13 2010
@@ -1 +1 @@
-803
\ No newline at end of file
+804
\ No newline at end of file

Modified: erp5/trunk/products/ERP5Security/ERP5UserManager.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Security/ERP5UserManager.py?rev=37065&r1=37064&r2=37065&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Security/ERP5UserManager.py [utf8] (original)
+++ erp5/trunk/products/ERP5Security/ERP5UserManager.py [utf8] Mon Jul 12 19:06:13 2010
@@ -26,7 +26,7 @@ from Products.PluggableAuthService.plugi
 from Products.PluggableAuthService.utils import classImplements
 from Products.PluggableAuthService.interfaces.plugins import IAuthenticationPlugin
 from Products.PluggableAuthService.interfaces.plugins import IUserEnumerationPlugin
-from Products.ERP5Type.Cache import CachingMethod
+from Products.ERP5Type.Cache import CachingMethod, transactional_cached
 from ZODB.POSException import ConflictError
 import sys
 from DateTime import DateTime
@@ -64,6 +64,36 @@ class _AuthenticationFailure(Exception):
   etc...)
   """
 
+ at transactional_cached(lambda portal, *args: args)
+def getUserByLogin(portal, login, exact_match=True):
+  if isinstance(login, basestring):
+    login = login,
+  if exact_match:
+    reference_key = 'ExactMatch'
+  else:
+    reference_key = 'Keyword'
+  result = portal.portal_catalog.unrestrictedSearchResults(
+      select_expression='reference',
+      portal_type="Person",
+      reference=dict(query=login, key=reference_key))
+  # XXX: Here, we filter catalog result list ALTHOUGH we did pass
+  # parameters to unrestrictedSearchResults to restrict result set.
+  # This is done because the following values can match person with
+  # reference "foo":
+  # "foo " because of MySQL (feature, PADSPACE collation):
+  #  mysql> SELECT reference as r FROM catalog
+  #      -> WHERE reference="foo      ";
+  #  +-----+
+  #  | r   |
+  #  +-----+
+  #  | foo |
+  #  +-----+
+  #  1 row in set (0.01 sec)
+  # "bar OR foo" because of ZSQLCatalog tokenizing searched strings
+  #  by default (feature).
+  return [x.getObject() for x in result if not exact_match
+                                           or x['reference'] in login]
+
 
 class ERP5UserManager(BasePlugin):
     """ PAS plugin for managing users in ERP5
@@ -180,81 +210,30 @@ class ERP5UserManager(BasePlugin):
 
         return tuple(user_info)
 
-
     def getUserByLogin(self, login, exact_match=True):
         # Search the Catalog for login and return a list of person objects
         # login can be a string or a list of strings
         # (no docstring to prevent publishing)
         if not login:
           return []
-
-        portal = self.getPortalObject()
-
-        def _getUserByLogin(login, exact_match):
-          # because we aren't logged in, we have to create our own
-          # SecurityManager to be able to access the Catalog
-          if isinstance(login, list):
-            login = tuple(login)
-          elif not isinstance(login, tuple):
-            login = (str(login),)
-          sm = getSecurityManager()
-          if sm.getUser().getId() != SUPER_USER:
-            newSecurityManager(self, self.getUser(SUPER_USER))
-  
-          try:
-            try:
-              if exact_match:
-                reference_key = 'ExactMatch'
-              else:
-                reference_key = 'Keyword'
-
-              result = portal.portal_catalog.unrestrictedSearchResults(
-                                        select_expression='reference',
-                                        portal_type="Person",
-                                        reference=dict(query=login,
-                                                       key=reference_key))
-            except ConflictError:
-              raise
-            except:
-              LOG('ERP5Security', PROBLEM, 'getUserByLogin failed', error=sys.exc_info())
-              # Here we must raise an exception to prevent callers from caching
-              # a result of a degraded situation.
-              # The kind of exception does not matter as long as it's catched by
-              # PAS and causes a lookup using another plugin or user folder.
-              # As PAS does not define explicitely such exception, we must use
-              # the _SWALLOWABLE_PLUGIN_EXCEPTIONS list.
-              raise _SWALLOWABLE_PLUGIN_EXCEPTIONS[0]
-          finally:
-            setSecurityManager(sm)
-          # XXX: Here, we filter catalog result list ALTHOUGH we did pass
-          # parameters to unrestrictedSearchResults to restrict result set.
-          # This is done because the following values can match person with
-          # reference "foo":
-          # "foo " because of MySQL (feature, PADSPACE collation):
-          #  mysql> SELECT reference as r FROM catalog
-          #      -> WHERE reference="foo      ";
-          #  +-----+
-          #  | r   |
-          #  +-----+
-          #  | foo |
-          #  +-----+
-          #  1 row in set (0.01 sec)
-          # "bar OR foo" because of ZSQLCatalog tokenizing searched strings
-          #  by default (feature).
-          result = [x.path for x in result if (not exact_match)
-                          or x['reference'] in login]
-          if not result:
-            raise _AuthenticationFailure()
-          return result
-
-        _getUserByLogin = CachingMethod(_getUserByLogin,
-                                        id='ERP5UserManager_getUserByLogin',
-                                        cache_factory='erp5_content_short')
+        if isinstance(login, list):
+          login = tuple(login)
+        elif not isinstance(login, tuple):
+          login = str(login)
         try:
-          return [portal.unrestrictedTraverse(x) for x in
-                              _getUserByLogin(login, exact_match)]
-        except _AuthenticationFailure:
-          return []
+          return getUserByLogin(self.getPortalObject(), login, exact_match)
+        except ConflictError:
+          raise
+        except:
+          LOG('ERP5Security', PROBLEM, 'getUserByLogin failed', error=sys.exc_info())
+          # Here we must raise an exception to prevent callers from caching
+          # a result of a degraded situation.
+          # The kind of exception does not matter as long as it's catched by
+          # PAS and causes a lookup using another plugin or user folder.
+          # As PAS does not define explicitely such exception, we must use
+          # the _SWALLOWABLE_PLUGIN_EXCEPTIONS list.
+          raise _SWALLOWABLE_PLUGIN_EXCEPTIONS[0]
+
 
 classImplements( ERP5UserManager
                , IAuthenticationPlugin

Modified: erp5/trunk/products/ERP5Security/__init__.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Security/__init__.py?rev=37065&r1=37064&r2=37065&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Security/__init__.py [utf8] (original)
+++ erp5/trunk/products/ERP5Security/__init__.py [utf8] Mon Jul 12 19:06:13 2010
@@ -108,3 +108,6 @@ def initialize(context):
                          , icon='www/portal.gif'
                          )
 
+from AccessControl.SecurityInfo import ModuleSecurityInfo
+ModuleSecurityInfo('Products.ERP5Security.ERP5UserManager').declarePublic(
+  'getUserByLogin')




More information about the Erp5-report mailing list