[Erp5-report] r37454 luke - /erp5/trunk/products/ERP5Wizard/PAS/ERP5RemoteUserManager.py
nobody at svn.erp5.org
nobody at svn.erp5.org
Tue Aug 3 18:37:33 CEST 2010
Author: luke
Date: Tue Aug 3 18:37:30 2010
New Revision: 37454
URL: http://svn.erp5.org?rev=37454&view=rev
Log:
- implement ZODB cache for remote users authentication, which allows to use
instance even in case when remote server is dead, implemented in bug-to-bug
compatible way with WizardTool_authenticateCredentials
Reviewed by Vincent.
Modified:
erp5/trunk/products/ERP5Wizard/PAS/ERP5RemoteUserManager.py
Modified: erp5/trunk/products/ERP5Wizard/PAS/ERP5RemoteUserManager.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Wizard/PAS/ERP5RemoteUserManager.py?rev=37454&r1=37453&r2=37454&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Wizard/PAS/ERP5RemoteUserManager.py [utf8] (original)
+++ erp5/trunk/products/ERP5Wizard/PAS/ERP5RemoteUserManager.py [utf8] Tue Aug 3 18:37:30 2010
@@ -27,6 +27,10 @@ from Products.ERP5Type.Cache import Cach
from DateTime import DateTime
from Products.ERP5Security.ERP5UserManager import ERP5UserManager, SUPER_USER, _AuthenticationFailure
+from BTrees.OOBTree import OOBTree
+from zLOG import LOG, INFO, WARNING
+import socket
+from AccessControl.AuthEncoding import pw_validate, pw_encrypt
manage_addERP5RemoteUserManagerForm = PageTemplateFile(
'../dtml/ERP5Security_addERP5RemoteUserManager', globals(),
@@ -52,7 +56,71 @@ class ERP5RemoteUserManager(ERP5UserMana
meta_type = 'ERP5 Remote User Manager'
security = ClassSecurityInfo()
+ remote_authentication_cache = None
+ def _doRemoteAuthentication(self, login, password):
+ # Do remote authentication with local ZODB caching
+ # Thanks to this it is possible to login to instance, even
+ # if master authentication server is down
+ #
+ # socket.sslerror and socket.error are assumed as acceptable ones
+ # and invoke authentication against locally available cache of
+ # users
+ #
+ # any other error is assumed as fatal and results in disallowing
+ # authentication and clearing local cache
+ if self.remote_authentication_cache is None:
+ self.remote_authentication_cache = OOBTree()
+ portal = self.getPortalObject()
+ encrypted_password = pw_encrypt(password)
+ callRemoteProxyMethod = portal.portal_wizard.callRemoteProxyMethod
+ erp5_uid = portal.ERP5Site_getExpressInstanceUid()
+ try:
+ # XXX: This mix of passed parameters is based on
+ # WizardTool_authenticateCredentials. As current implementation
+ # shall be bug-to-bug compatible with previous one, kept such
+ # behaviour
+ result = int(callRemoteProxyMethod(
+ 'Base_authenticateCredentialsFromExpressInstance',
+ use_cache = 0,
+ ignore_exceptions = 0,
+ **{'login': login,
+ 'password': password,
+ 'erp5_uid': erp5_uid}))
+ except (socket.sslerror, socket.error):
+ # issue with socket, read from "ZODB cache"
+ LOG('ERP5RemoteUserManager', INFO, 'Socket issue with server, '
+ 'used local cache', error=True)
+ stored_encrypted_password = self.remote_authentication_cache.get(
+ login, None)
+ result = int(stored_encrypted_password is not None and pw_validate(
+ stored_encrypted_password, password))
+ except: # XXX: It would be better to do except Exception, but
+ # to-be-bug compatible with WizardTool_authenticateCredentials
+ # is better to catch the same way
+ # any other issue, work like WizardTool_authenticateCredentials
+ # XXX: To be fine tuned
+ LOG('ERP5RemoteUserManager', WARNING, 'Not supported exception '
+ 'assuming that authentication failed', error=True)
+ result = 0
+ # clear local cache
+ if login in self.remote_authentication_cache:
+ del self.remote_authentication_cache[login]
+ else:
+ # store in cache if different
+ if result == 1:
+ # successfully logged in
+ stored_encrypted_password = self.remote_authentication_cache\
+ .get(login, None)
+ if stored_encrypted_password is None or \
+ not pw_validate(stored_encrypted_password, password):
+ # not yet in cache or changed on server
+ self.remote_authentication_cache[login] = encrypted_password
+ else:
+ # wrong login, so clear local cache
+ if login in self.remote_authentication_cache:
+ del self.remote_authentication_cache[login]
+ return result
#
# IAuthenticationPlugin implementation
@@ -99,8 +167,7 @@ class ERP5RemoteUserManager(ERP5UserMana
valid_assignment_list.append(assignment)
# validate to remote ERP5 instance
- portal = self.getPortalObject()
- is_authenticated = int(portal.WizardTool_authenticateCredentials(login , password))
+ is_authenticated = self._doRemoteAuthentication(login, password)
if is_authenticated:
return login, login
finally:
More information about the Erp5-report
mailing list