Commit 72645f84 authored by Arnaud Fontaine's avatar Arnaud Fontaine

ZODB Components: Fix bootstrap of migrated bt5s.

* Upon bt5 installation, install portal_type* items before bt5 {Document,
  Extensions...} as corresponding Portal Type are required once they have been
  migrated to ZODB Components.

* Likewise portal_{property_sheets, types}, portal_components must be created
  automatically *before* installing any bt5. This is required when Products
  will be migrated but also for bt5 items before bootstrapping erp5_core bt5.

* Set Permissions in ComponentTool instanciation and revoke all permissions,
  then allow only some of them for security sake.

* When creating ERP5 site with unit tests, add ERP5TypeTestCase to Developer
  Role ASAP so that there is no Permission issue when installing bootstrap bt5
  and test bt5s containing ZODB Components.
parent da8e1eb4
...@@ -4791,6 +4791,7 @@ Business Template is a set of definitions, such as skins, portal types and categ ...@@ -4791,6 +4791,7 @@ Business Template is a set of definitions, such as skins, portal types and categ
# This is a global variable # This is a global variable
# Order is important for installation # Order is important for installation
# We want to have: # We want to have:
# * workflow and portal_type* before ZODB Component {Document,Extension...}
# * path after module, because path can be module content # * path after module, because path can be module content
# * path after categories, because path can be categories content # * path after categories, because path can be categories content
# * path after portal types roles so that roles in the current bt can be used # * path after portal types roles so that roles in the current bt can be used
...@@ -4802,6 +4803,12 @@ Business Template is a set of definitions, such as skins, portal types and categ ...@@ -4802,6 +4803,12 @@ Business Template is a set of definitions, such as skins, portal types and categ
_item_name_list = [ _item_name_list = [
'_registered_version_priority_selection_item', '_registered_version_priority_selection_item',
'_workflow_item', '_workflow_item',
'_portal_type_item',
#'_portal_type_workflow_chain_item',
'_portal_type_allowed_content_type_item',
'_portal_type_hidden_content_type_item',
'_portal_type_property_sheet_item',
'_portal_type_base_category_item',
'_product_item', '_product_item',
'_document_item', '_document_item',
'_property_sheet_item', '_property_sheet_item',
...@@ -4812,12 +4819,6 @@ Business Template is a set of definitions, such as skins, portal types and categ ...@@ -4812,12 +4819,6 @@ Business Template is a set of definitions, such as skins, portal types and categ
'_tool_item', '_tool_item',
'_message_translation_item', '_message_translation_item',
'_site_property_item', '_site_property_item',
'_portal_type_item',
#'_portal_type_workflow_chain_item',
'_portal_type_allowed_content_type_item',
'_portal_type_hidden_content_type_item',
'_portal_type_property_sheet_item',
'_portal_type_base_category_item',
'_category_item', '_category_item',
'_module_item', '_module_item',
'_portal_type_roles_item', '_portal_type_roles_item',
......
2013-06-25 arnaud.fontaine
* ZODB Components: Fix bootstrap of migrated bt5s.
2013-06-24 arnaud.fontaine 2013-06-24 arnaud.fontaine
* Meaningless to remove ZODB Components migrated from FS. This will not work when there are several nodes anyway, so just display a message to the user. * Meaningless to remove ZODB Components migrated from FS. This will not work when there are several nodes anyway, so just display a message to the user.
......
41098 41099
\ No newline at end of file \ No newline at end of file
mimetypes_registry mimetypes_registry
portal_components
portal_contribution_registry portal_contribution_registry
portal_notifications portal_notifications
portal_sessions portal_sessions
......
...@@ -41,7 +41,6 @@ from Products.CMFCore.Expression import Expression ...@@ -41,7 +41,6 @@ from Products.CMFCore.Expression import Expression
from Products.ERP5Type.tests.utils import LogInterceptor from Products.ERP5Type.tests.utils import LogInterceptor
from Products.ERP5Type.Workflow import addWorkflowByType from Products.ERP5Type.Workflow import addWorkflowByType
from Products.ERP5Type.tests.backportUnittest import expectedFailure, skip from Products.ERP5Type.tests.backportUnittest import expectedFailure, skip
from Products.ERP5Type.tests.testDynamicClassGeneration import TestDeveloperMixin
from Products.ERP5VCS.WorkingCopy import getVcsTool from Products.ERP5VCS.WorkingCopy import getVcsTool
import shutil import shutil
import os import os
...@@ -58,7 +57,7 @@ from Products.PortalTransforms.Transform import Transform ...@@ -58,7 +57,7 @@ from Products.PortalTransforms.Transform import Transform
Transform_tr_init = Transform._tr_init Transform_tr_init = Transform._tr_init
Transform_manage_beforeDelete = Transform.manage_beforeDelete Transform_manage_beforeDelete = Transform.manage_beforeDelete
class BusinessTemplateMixin(TestDeveloperMixin, ERP5TypeTestCase, LogInterceptor): class BusinessTemplateMixin(ERP5TypeTestCase, LogInterceptor):
def getBusinessTemplateList(self): def getBusinessTemplateList(self):
return ('erp5_base', return ('erp5_base',
'erp5_csv_style', 'erp5_csv_style',
......
...@@ -35,6 +35,7 @@ import sys ...@@ -35,6 +35,7 @@ import sys
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
from AccessControl.Permission import Permission
from Products.ERP5Type.Tool.BaseTool import BaseTool from Products.ERP5Type.Tool.BaseTool import BaseTool
from Products.ERP5Type.Base import Base from Products.ERP5Type.Base import Base
from Products.ERP5Type.TransactionalVariable import getTransactionalVariable from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
...@@ -61,6 +62,51 @@ class ComponentTool(BaseTool): ...@@ -61,6 +62,51 @@ class ComponentTool(BaseTool):
security = ClassSecurityInfo() security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation) security.declareObjectProtected(Permissions.AccessContentsInformation)
def __init__(self, *args, **kwargs):
"""
Except 'Access *', 'View*' and 'WebDAV' permissions (Acquired) and 'Reset
dynamic classes' (Manager, required to reset Components), everything
requires Developer Role.
Another solution would be to load it from XML as it was previously done,
but from a security point of view, it's better to forbid everything and
allows only some.
XXX-arnau: Really all 'Access *' and 'View*'? nothing else?
"""
obj = BaseTool.__init__(self, *args, **kwargs)
for permission_tuple in self.ac_inherited_permissions(1):
name = permission_tuple[0]
value = permission_tuple[1]
if name == 'Reset dynamic classes':
p = Permission(name, value, self)
p.setRoles(('Manager',))
elif not (name.startswith('Access ') or
name.startswith('View') or
name.startswith('WebDAV')):
p = Permission(name, value, self)
p.setRoles(('Developer',))
return obj
def _isBootstrapRequired(self):
"""
Required by synchronizeDynamicModules() to bootstrap an empty site and
thus create portal_components
XXX-arnau: Only bt5 items for now
"""
return False
def _bootstrap(self):
"""
Required by synchronizeDynamicModules() to bootstrap an empty site and
thus create portal_components
XXX-arnau: Only bt5 items for now
"""
pass
security.declareProtected(Permissions.ResetDynamicClasses, 'reset') security.declareProtected(Permissions.ResetDynamicClasses, 'reset')
def reset(self, def reset(self,
force=False, force=False,
......
...@@ -332,8 +332,9 @@ def synchronizeDynamicModules(context, force=False): ...@@ -332,8 +332,9 @@ def synchronizeDynamicModules(context, force=False):
migrate = False migrate = False
from Products.ERP5Type.Tool.PropertySheetTool import PropertySheetTool from Products.ERP5Type.Tool.PropertySheetTool import PropertySheetTool
from Products.ERP5Type.Tool.TypesTool import TypesTool from Products.ERP5Type.Tool.TypesTool import TypesTool
from Products.ERP5Type.Tool.ComponentTool import ComponentTool
try: try:
for tool_class in TypesTool, PropertySheetTool: for tool_class in TypesTool, PropertySheetTool, ComponentTool:
# if the instance has no property sheet tool, or incomplete # if the instance has no property sheet tool, or incomplete
# property sheets, we need to import some data to bootstrap # property sheets, we need to import some data to bootstrap
# (only likely to happen on the first run ever) # (only likely to happen on the first run ever)
......
...@@ -218,6 +218,21 @@ def _parse_args(self, *args, **kw): ...@@ -218,6 +218,21 @@ def _parse_args(self, *args, **kw):
_parse_args._original = DateTime._original_parse_args _parse_args._original = DateTime._original_parse_args
DateTime._parse_args = _parse_args DateTime._parse_args = _parse_args
def addUserToDeveloperRole(user_name):
config = getConfiguration()
product_config = getattr(config, 'product_config', None)
if product_config is None:
product_config = config.product_config = {}
if product_config.get('erp5') is None:
class DummyDeveloperConfig(object):
pass
dummy_developer_config = DummyDeveloperConfig()
dummy_developer_config.developer_list = [user_name]
product_config['erp5'] = dummy_developer_config
elif user_name not in product_config['erp5'].developer_list:
product_config['erp5'].developer_list.append(user_name)
class ERP5TypeTestCaseMixin(ProcessingNodeTestCase, PortalTestCase): class ERP5TypeTestCaseMixin(ProcessingNodeTestCase, PortalTestCase):
"""Mixin class for ERP5 based tests. """Mixin class for ERP5 based tests.
""" """
...@@ -1003,6 +1018,11 @@ class ERP5TypeCommandLineTestCase(ERP5TypeTestCaseMixin): ...@@ -1003,6 +1018,11 @@ class ERP5TypeCommandLineTestCase(ERP5TypeTestCaseMixin):
'Assignor', 'Author', 'Auditor', 'Associate'], []) 'Assignor', 'Author', 'Auditor', 'Associate'], [])
user = uf.getUserById('ERP5TypeTestCase').__of__(uf) user = uf.getUserById('ERP5TypeTestCase').__of__(uf)
newSecurityManager(None, user) newSecurityManager(None, user)
# bt5s contain ZODB Components which can be only installed if the
# user has Developer Role
addUserToDeveloperRole('ERP5TypeTestCase')
# Add ERP5 Site # Add ERP5 Site
reindex = 1 reindex = 1
if hot_reindexing: if hot_reindexing:
......
...@@ -1244,31 +1244,7 @@ from Products.ERP5Type.mixin.component import ComponentMixin ...@@ -1244,31 +1244,7 @@ from Products.ERP5Type.mixin.component import ComponentMixin
from Products.ERP5Type.tests.SecurityTestCase import SecurityTestCase from Products.ERP5Type.tests.SecurityTestCase import SecurityTestCase
from App.config import getConfiguration from App.config import getConfiguration
class TestDeveloperMixin: class _TestZodbComponent(SecurityTestCase):
def login(self, user_name='ERP5TypeTestCase', quiet=0):
"""
Make sure that the test user has Developer Role, otherwise the user cannot
do anything on Components...
"""
config = getConfiguration()
product_config = getattr(config, 'product_config', None)
if product_config is None:
product_config = config.product_config = {}
if product_config.get('erp5') is None:
class DummyDeveloperConfig(object):
pass
dummy_developer_config = DummyDeveloperConfig()
dummy_developer_config.developer_list = [user_name]
product_config['erp5'] = dummy_developer_config
elif user_name not in product_config['erp5'].developer_list:
product_config['erp5'].developer_list.append(user_name)
return ERP5TypeTestCase.login(self, user_name, quiet)
class _TestZodbComponent(TestDeveloperMixin, SecurityTestCase):
""" """
Abstract class which defined convenient methods used by any Component Test Abstract class which defined convenient methods used by any Component Test
and tests ran for all Component Test classes and tests ran for all Component Test classes
......
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