Commit 22a6aaad authored by Arnaud Fontaine's avatar Arnaud Fontaine

ZODB Components: Migrate Products.ERP5Type.SessionTool from filesystem.

parent e1dd670f
Pipeline #10120 failed with stage
......@@ -31,7 +31,7 @@ import unittest
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from AccessControl.SecurityManagement import newSecurityManager
from Products.ERP5Type.tests.Sequence import SequenceList
from Products.ERP5Type.Tool.SessionTool import SESSION_CACHE_FACTORY
from erp5.component.tool.SessionTool import SESSION_CACHE_FACTORY
from string import letters as LETTERS
from random import choice
import time
......
......@@ -111,7 +111,6 @@ class DistributedSession(Session):
def _updateStorage(self):
""" Update backend storage. """
global storage_plugin
storage_plugin.set(self.session_id, \
SESSION_SCOPE, \
value = self, \
......@@ -130,7 +129,7 @@ class DistributedSession(Session):
Session.clear(self)
self._updateStorage()
def update(self, dict=None, **kwargs):
def update(self, dict=None, **kwargs): # pylint: disable=redefined-builtin
Session.update(self, dict, **kwargs)
self._updateStorage()
......@@ -198,13 +197,13 @@ class SessionTool(BaseTool):
security.declarePrivate('getSession')
def getSession(self, session_id, session_duration=None):
""" Return session object. """
storage_plugin = self._getStoragePlugin()
storage_plugin_ = self._getStoragePlugin()
# expire explicitly as each session can have a different life duration
storage_plugin.expireOldCacheEntries(forceCheck=1)
session = storage_plugin.get(session_id, SESSION_SCOPE, None)
storage_plugin_.expireOldCacheEntries(forceCheck=1)
session = storage_plugin_.get(session_id, SESSION_SCOPE, None)
if session is None:
# init it in cache and use different Session types based on cache plugin type used as a storage
storage_plugin_type = storage_plugin.__class__.__name__
storage_plugin_type = storage_plugin_.__class__.__name__
if storage_plugin_type in ("RamCache",):
session = RamSession()
elif storage_plugin_type in ("DistributedRamCache",):
......@@ -215,14 +214,14 @@ class SessionTool(BaseTool):
cache_plugin = self.portal_caches[SESSION_CACHE_FACTORY].objectValues()[0]
session_duration = cache_plugin.getCacheDuration()
session._updateSessionDuration(session_duration)
storage_plugin.set(session_id, SESSION_SCOPE, session, session_duration)
storage_plugin_.set(session_id, SESSION_SCOPE, session, session_duration)
else:
# cache plugin returns wrapper (CacheEntry instance)
session = session.getValue()
return session
security.declarePublic('newContent')
def newContent(self, id, **kw):
def newContent(self, id, **kw): # pylint: disable=redefined-builtin
""" Create new session object. """
session = self.getSession(id)
session._updatecontext(self)
......@@ -230,16 +229,16 @@ class SessionTool(BaseTool):
return session
security.declareProtected(Permissions.AccessContentsInformation, 'manage_delObjects')
def manage_delObjects(self, ids=[], REQUEST=None):
def manage_delObjects(self, ids=(), REQUEST=None, *args, **kw):
""" Delete session object. """
storage_plugin = self._getStoragePlugin()
storage_plugin_ = self._getStoragePlugin()
if not isinstance(ids, (list, tuple)):
ids = [ids]
for session_id in ids:
storage_plugin.delete(session_id, SESSION_SCOPE)
storage_plugin_.delete(session_id, SESSION_SCOPE)
def _getStoragePlugin(self):
""" Get cache storage plugin."""
global storage_plugin
global storage_plugin # pylint: disable=global-statement
storage_plugin = self.portal_caches.getRamCacheRoot()[SESSION_CACHE_FACTORY].getCachePluginList()[0]
return storage_plugin
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Tool Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>SessionTool</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>Products.ERP5Type.Tool.SessionTool</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>tool.erp5.SessionTool</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Tool Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -10,5 +10,6 @@ tool.erp5.NotificationTool
tool.erp5.OrderTool
tool.erp5.PasswordTool
tool.erp5.RuleTool
tool.erp5.SessionTool
tool.erp5.SimulationTool
tool.erp5.TestTool
\ No newline at end of file
......@@ -88,7 +88,7 @@ import Products.ERP5Type.Workflow
def initialize( context ):
# Import Product Components
from Tool import (CacheTool, MemcachedTool, SessionTool,
from Tool import (CacheTool, MemcachedTool,
TypesTool, WebServiceTool, PropertySheetTool,
ComponentTool)
import Document
......@@ -104,7 +104,6 @@ def initialize( context ):
ERP5TypeInformation, )
portal_tools = ( CacheTool.CacheTool,
MemcachedTool.MemcachedTool,
SessionTool.SessionTool,
TypesTool.TypesTool,
WebServiceTool.WebServiceTool,
PropertySheetTool.PropertySheetTool,
......
  • For reference, this can cause difficulties when products are updated and business template is not yet updated. setAuthCookie here is using session tool to set the user cookie. This fail when session tool is broken (when removed from filesystem but not yet installed by business template).

    There are several easy workarounds, login in from / instead of /erp5 or apply a patch like this:

    diff --git a/product/ERP5Type/patches/CookieCrumbler.py b/product/ERP5Type/patches/CookieCrumbler.py
    index d73385ccbf..91638d7af3 100644
    --- a/product/ERP5Type/patches/CookieCrumbler.py
    +++ b/product/ERP5Type/patches/CookieCrumbler.py
    @@ -145,7 +145,13 @@ def modifyRequest(self, req, resp):
                                 path=self.getCookiePath())
             method = self.getCookieMethod( 'setAuthCookie'
                                            , self.defaultSetAuthCookie )
    +
    +        # XXX make sure we can login when session tool is not yet migrated
    +        from ZODB.broken import PersistentBroken
    +        if isinstance(getattr(self.getPortalObject(), 'portal_sessions', None), PersistentBroken):
    +          method = self.defaultSetAuthCookie
             method( resp, self.auth_cookie, quote( ac ) )
    +
           elif req.has_key(self.auth_cookie):
             # Attempt to resume a session if the cookie is valid.
             # Copy __ac to the auth header.
  • Maybe it would be nice to have a way to run upgrader that does not require any user action.

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