Commit c4d478fa authored by Rafael Monnerat's avatar Rafael Monnerat

Reimplement SlapOSMachineAuthenticationPlugin and SlapOSShadowAuthenticationPlugin

The reimplementation make both complaint with ERP5LoginUserManager

  Include custom ERP5Type_asSecurityGroupId (Required for Computer and Software Instance usage of user_id)
  machine_login was renamed to external_login to be complaint with ERP5LoginUserManager

  On SlapOSShadowAuthenticationPlugin, the enumerateUsers contains a huge copied code from
       ERP5LoginUserManager, which could be be factoried in a sense in future.

  Update related tests and code to:

   - Add ERP5 Login in person, Computer and Software Instance
   - Set user id while create or clone objects
   - Update ROLES and logins (for tests) to use User ID instead reference.
   - Login is defined by ERP5 Login and not by object reference.
parent a4e218ee
...@@ -7,28 +7,8 @@ ...@@ -7,28 +7,8 @@
import transaction import transaction
from Products.SlapOS.tests.testSlapOSMixin import \ from Products.SlapOS.tests.testSlapOSMixin import \
testSlapOSMixin, withAbort testSlapOSMixin, withAbort, simulate
from zExceptions import Unauthorized from zExceptions import Unauthorized
from functools import wraps
from Products.ERP5Type.tests.utils import createZODBPythonScript
def simulate(script_id, params_string, code_string):
def upperWrap(f):
@wraps(f)
def decorated(self, *args, **kw):
if script_id in self.portal.portal_skins.custom.objectIds():
raise ValueError('Precondition failed: %s exists in custom' % script_id)
createZODBPythonScript(self.portal.portal_skins.custom,
script_id, params_string, code_string)
try:
result = f(self, *args, **kw)
finally:
if script_id in self.portal.portal_skins.custom.objectIds():
self.portal.portal_skins.custom.manage_delObjects(script_id)
transaction.commit()
return result
return decorated
return upperWrap
class TestSlapOSComputer_reportComputerConsumption(testSlapOSMixin): class TestSlapOSComputer_reportComputerConsumption(testSlapOSMixin):
......
...@@ -13,10 +13,10 @@ class Person(ERP5Person): ...@@ -13,10 +13,10 @@ class Person(ERP5Person):
# in ERP5 user has no SetOwnPassword permission on Person document # in ERP5 user has no SetOwnPassword permission on Person document
# referring himself, so implement "security" by checking that currently # referring himself, so implement "security" by checking that currently
# logged in user is trying to get/revoke his own certificate # logged in user is trying to get/revoke his own certificate
reference = self.getReference() user_id = self.getUserId()
if not reference: if not user_id:
raise raise
if getSecurityManager().getUser().getId() != reference: if getSecurityManager().getUser().getId() != user_id:
raise raise
def _getCertificate(self): def _getCertificate(self):
......
...@@ -6,10 +6,22 @@ ...@@ -6,10 +6,22 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>Person</string> </value> <value> <string>Person</string> </value>
</item> </item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>document.erp5.Person</string> </value> <value> <string>document.erp5.Person</string> </value>
...@@ -43,13 +55,28 @@ ...@@ -43,13 +55,28 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -62,7 +89,7 @@ ...@@ -62,7 +89,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -71,7 +98,7 @@ ...@@ -71,7 +98,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="3" aka="AAAAAAAAAAM="> <record id="4" aka="AAAAAAAAAAQ=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle> </pickle>
......
...@@ -43,10 +43,12 @@ def SoftwareInstance_bangAsSelf(self, relative_url=None, reference=None, ...@@ -43,10 +43,12 @@ def SoftwareInstance_bangAsSelf(self, relative_url=None, reference=None,
if (software_instance.getPortalType() == "Slave Instance") and \ if (software_instance.getPortalType() == "Slave Instance") and \
(software_instance.getReference() == reference): (software_instance.getReference() == reference):
# XXX There is no account for Slave Instance # XXX There is no account for Slave Instance
reference = ERP5Security.SUPER_USER user_id = ERP5Security.SUPER_USER
else:
user_id = software_instance.getUserId()
newSecurityManager(None, self.getPortalObject().acl_users.getUserById( newSecurityManager(None, self.getPortalObject().acl_users.getUserById(
reference)) user_id))
try: try:
software_instance.bang(bang_tree=True, comment=comment) software_instance.bang(bang_tree=True, comment=comment)
finally: finally:
......
...@@ -30,7 +30,7 @@ from AccessControl.SecurityManagement import getSecurityManager, \ ...@@ -30,7 +30,7 @@ from AccessControl.SecurityManagement import getSecurityManager, \
setSecurityManager, newSecurityManager setSecurityManager, newSecurityManager
from AccessControl import Unauthorized from AccessControl import Unauthorized
def getComputerSecurityCategory(self, base_category_list, user_name, def getComputerSecurityCategory(self, base_category_list, user_name,
object, portal_type): object, portal_type):
""" """
This script returns a list of dictionaries which represent This script returns a list of dictionaries which represent
...@@ -39,8 +39,8 @@ def getComputerSecurityCategory(self, base_category_list, user_name, ...@@ -39,8 +39,8 @@ def getComputerSecurityCategory(self, base_category_list, user_name,
category_list = [] category_list = []
computer_list = self.portal_catalog.unrestrictedSearchResults( computer_list = self.portal_catalog.unrestrictedSearchResults(
portal_type='Computer', portal_type='Computer',
reference=user_name, user_id=user_name,
validation_state="validated", validation_state="validated",
limit=2, limit=2,
) )
...@@ -51,12 +51,12 @@ def getComputerSecurityCategory(self, base_category_list, user_name, ...@@ -51,12 +51,12 @@ def getComputerSecurityCategory(self, base_category_list, user_name,
category_list.append( category_list.append(
{base_category: ['role/computer']}) {base_category: ['role/computer']})
elif len(computer_list) > 1: elif len(computer_list) > 1:
raise ConsistencyError, "Error: There is more than one Computer " \ raise ConsistencyError("Error: There is more than one Computer " \
"with reference '%s'" % user_name "with reference '%s'" % user_name)
return category_list return category_list
def getSoftwareInstanceSecurityCategory(self, base_category_list, user_name, def getSoftwareInstanceSecurityCategory(self, base_category_list, user_name,
object, portal_type): object, portal_type):
""" """
This script returns a list of dictionaries which represent This script returns a list of dictionaries which represent
...@@ -65,8 +65,8 @@ def getSoftwareInstanceSecurityCategory(self, base_category_list, user_name, ...@@ -65,8 +65,8 @@ def getSoftwareInstanceSecurityCategory(self, base_category_list, user_name,
category_list = [] category_list = []
software_instance_list = self.portal_catalog.unrestrictedSearchResults( software_instance_list = self.portal_catalog.unrestrictedSearchResults(
portal_type='Software Instance', portal_type='Software Instance',
reference=user_name, user_id=user_name,
validation_state="validated", validation_state="validated",
limit=2, limit=2,
) )
...@@ -83,8 +83,8 @@ def getSoftwareInstanceSecurityCategory(self, base_category_list, user_name, ...@@ -83,8 +83,8 @@ def getSoftwareInstanceSecurityCategory(self, base_category_list, user_name,
category_dict.setdefault(base_category, []).append(hosting_item.getRelativeUrl()) category_dict.setdefault(base_category, []).append(hosting_item.getRelativeUrl())
category_list.append(category_dict) category_list.append(category_dict)
elif len(software_instance_list) > 1: elif len(software_instance_list) > 1:
raise ConsistencyError, "Error: There is more than one Software Instance " \ raise ConsistencyError("Error: There is more than one Software Instance " \
"with reference %r" % user_name "with reference %r" % user_name)
return category_list return category_list
...@@ -109,14 +109,14 @@ def restrictMethodAsShadowUser(self, shadow_document=None, callable_object=None, ...@@ -109,14 +109,14 @@ def restrictMethodAsShadowUser(self, shadow_document=None, callable_object=None,
# Switch to the shadow user temporarily, so that the behavior would not # Switch to the shadow user temporarily, so that the behavior would not
# change even if this method is invoked by random users. # change even if this method is invoked by random users.
acl_users = shadow_document.getPortalObject().acl_users acl_users = shadow_document.getPortalObject().acl_users
reference = shadow_document.getReference() user_id = shadow_document.getUserId()
if reference is None: if user_id is None:
raise Unauthorized('%r is not configured' % relative_url) raise Unauthorized('%r is not configured' % relative_url)
real_user = acl_users.getUserById(reference) real_user = acl_users.getUserById(user_id)
if real_user is None: if real_user is None:
raise Unauthorized('%s is not loggable user' % relative_url) raise Unauthorized('%s is not loggable user' % relative_url)
sm = getSecurityManager() sm = getSecurityManager()
shadow_user = acl_users.getUserById('SHADOW-' + reference) shadow_user = acl_users.getUserById('SHADOW-' + user_id)
if shadow_user is None: if shadow_user is None:
raise Unauthorized('Shadow of %s is not loggable user' % relative_url) raise Unauthorized('Shadow of %s is not loggable user' % relative_url)
newSecurityManager(None, shadow_user) newSecurityManager(None, shadow_user)
......
...@@ -6,10 +6,22 @@ ...@@ -6,10 +6,22 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>SlapOSSecurity</string> </value> <value> <string>SlapOSSecurity</string> </value>
</item> </item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>extension.erp5.SlapOSSecurity</string> </value> <value> <string>extension.erp5.SlapOSSecurity</string> </value>
...@@ -35,9 +47,7 @@ ...@@ -35,9 +47,7 @@
<value> <value>
<tuple> <tuple>
<string>W: 34, 32: Redefining built-in \'object\' (redefined-builtin)</string> <string>W: 34, 32: Redefining built-in \'object\' (redefined-builtin)</string>
<string>W: 54, 4: Use raise ErrorClass(args) instead of raise ErrorClass, args. (old-raise-syntax)</string>
<string>W: 60, 32: Redefining built-in \'object\' (redefined-builtin)</string> <string>W: 60, 32: Redefining built-in \'object\' (redefined-builtin)</string>
<string>W: 86, 4: Use raise ErrorClass(args) instead of raise ErrorClass, args. (old-raise-syntax)</string>
</tuple> </tuple>
</value> </value>
</item> </item>
...@@ -48,13 +58,28 @@ ...@@ -48,13 +58,28 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -67,7 +92,7 @@ ...@@ -67,7 +92,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -76,7 +101,7 @@ ...@@ -76,7 +101,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="3" aka="AAAAAAAAAAM="> <record id="4" aka="AAAAAAAAAAQ=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle> </pickle>
......
<allowed_content_type_list> <allowed_content_type_list>
<portal_type id="Computer">
<item>ERP5 Login</item>
</portal_type>
<portal_type id="Hosting Subscription Module"> <portal_type id="Hosting Subscription Module">
<item>Hosting Subscription</item> <item>Hosting Subscription</item>
</portal_type> </portal_type>
<portal_type id="Software Installation Module"> <portal_type id="Software Installation Module">
<item>Software Installation</item> <item>Software Installation</item>
</portal_type> </portal_type>
<portal_type id="Software Instance">
<item>ERP5 Login</item>
</portal_type>
<portal_type id="Software Instance Module"> <portal_type id="Software Instance Module">
<item>Slave Instance</item> <item>Slave Instance</item>
<item>Software Instance</item> <item>Software Instance</item>
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
<item>SlaposAssignmentConstraint</item> <item>SlaposAssignmentConstraint</item>
</portal_type> </portal_type>
<portal_type id="Computer"> <portal_type id="Computer">
<item>ERP5User</item>
<item>SlaposCapacity</item> <item>SlaposCapacity</item>
<item>SlaposComputerConstraint</item> <item>SlaposComputerConstraint</item>
<item>Url</item> <item>Url</item>
...@@ -42,6 +43,7 @@ ...@@ -42,6 +43,7 @@
<item>VariationRange</item> <item>VariationRange</item>
</portal_type> </portal_type>
<portal_type id="Software Instance"> <portal_type id="Software Instance">
<item>ERP5User</item>
<item>HostingSubscription</item> <item>HostingSubscription</item>
<item>Reference</item> <item>Reference</item>
<item>SoftwareInstance</item> <item>SoftwareInstance</item>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Base Type" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_property_domain_dict</string> </key>
<value>
<dictionary>
<item>
<key> <string>short_title</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>acquire_local_roles</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>content_icon</string> </key>
<value> <string>document_icon.gif</string> </value>
</item>
<item>
<key> <string>content_meta_type</string> </key>
<value> <string>ERP5 Computer</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Computer represents a computer like personal computer, printer, router.</string> </value>
</item>
<item>
<key> <string>factory</string> </key>
<value> <string>addComputer</string> </value>
</item>
<item>
<key> <string>filter_content_types</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<tuple>
<string>item</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Computer</string> </value>
</item>
<item>
<key> <string>init_script</string> </key>
<value> <string>Computer_init</string> </value>
</item>
<item>
<key> <string>permission</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Computer</string> </value>
</item>
<item>
<key> <string>type_class</string> </key>
<value> <string>Computer</string> </value>
</item>
<item>
<key> <string>type_interface</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>type_mixin</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<tuple>
<global name="TranslationInformation" module="Products.ERP5Type.TranslationProviderBase"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>domain_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>property_name</string> </key>
<value> <string>short_title</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<tuple>
<global name="TranslationInformation" module="Products.ERP5Type.TranslationProviderBase"/>
<tuple/>
</tuple>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>domain_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>property_name</string> </key>
<value> <string>title</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -59,9 +59,7 @@ ...@@ -59,9 +59,7 @@
</item> </item>
<item> <item>
<key> <string>init_script</string> </key> <key> <string>init_script</string> </key>
<value> <value> <string>SoftwareInstance_init</string> </value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>meta_type</string> </key> <key> <string>meta_type</string> </key>
......
"""Hook called when a computer object is closed.
We want to reset reference, which is the user login in ERP5Security.
One exception is when a person object is installed from business template.
"""
if context.getPortalType() != "Computer":
return
context.setUserId(None)
context.Computer_initUserId()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Computer_afterClone</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Guard" module="Products.DCWorkflow.Guard"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>roles</string> </key>
<value>
<tuple>
<string>Owner</string>
</tuple>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -50,11 +50,11 @@ ...@@ -50,11 +50,11 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>promise_dict, tag, fixit=False, **kw</string> </value> <value> <string>**kw</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>Alarm_checkPromiseSlapOSPASBase</string> </value> <value> <string>Computer_init</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
if not context.hasUserId():
context.setUserId(
'C%i' % (
context.getPortalObject().portal_ids.generateNewId(
id_group='user_id',
id_generator='non_continuous_integer_increasing',
),
),
)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Computer_initUserId</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Guard" module="Products.DCWorkflow.Guard"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>roles</string> </key>
<value>
<tuple>
<string>Owner</string>
</tuple>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
"""
This script is used to convert a list of categories into an security
identifier (security ID). It is invoked by two classes in ERP5:
- ERP5Type.py to convert security definitions made of
multiple categories into security ID strings
- ERP5GroupManager.py to convert an assignment definition
into a single security ID string. It should be noted here
that ERP5GroupManager.py also tries to invoke ERP5Type_asSecurityGroupIdList
(DEPRECATED) in order associate a user to multiple security groups.
In this case ERP5Type_asSecurityGroupId is not invoked.
The script takes the following parameters:
category_order - list of base_categories we want to use to generate the group id
kw - keys should be base categories, values should be value
of corresponding relative urls (obtained by getBaseCategory())
Example call:
context.ERP5TypeSecurity_asGroupId(category_order=('site', 'group', 'function'),
site='france/lille', group='nexedi', function='accounting/accountant')
This will generate a string like 'LIL_NXD_ACT' where "LIL", "NXD" and "ACT" are
the codification of respecively "france/lille", "nexedi" and "accounting/accountant" categories
If the category points to a document portal type (ex. trade condition, project, etc.),
and if no codification property is defined for this type of object,
the security ID group is generated by considering the object reference or
the object ID.
ERP5Type_asSecurityGroupId can also return a list of users whenever a category points
to a Person instance. This is useful to implement user based local role assignments
instead of abstract security based local roles.
"""
portal = context.getPortalObject()
getCategoryValue = portal.portal_categories.getCategoryValue
# sort the category list lexicographically
# this prevents us to choose the exact order we want,
# but also prevents some human mistake to break everything by creating site_function instead of function_site
if category_order not in (None, ''):
category_order = list(category_order)
category_order.sort()
else:
category_order = []
# Prepare a cartesian product
from Products.ERP5Type.Utils import cartesianProduct
list_of_list = []
user_list = []
for base_category in category_order:
# It is acceptable for a category not to be defined
try:
category_list = kw[base_category]
except KeyError:
continue
associative_list = []
if isinstance(category_list, str):
category_list = [category_list]
for category in category_list:
if category[-1] == '*':
category = category[:-1]
is_child_category = 1
else:
is_child_category = 0
category_path = '%s/%s' % (base_category, category)
category_object = getCategoryValue(category_path)
if category_object is None:
raise RuntimeError("Security definition error (category %r not found)" % (category_path,))
portal_type = category_object.getPortalType()
if portal_type in ['Person', 'Computer', 'Software Instance']:
# We define a person here
user_name = category_object.Person_getUserId()
if user_name is not None:
user_list.append(user_name)
else:
category_code = (category_object.getProperty('codification') or
category_object.getProperty('reference') or
category_object.getId())
if is_child_category:
category_code += '*'
associative_list.append(category_code)
# Prevent making a cartesian product with an empty set
if associative_list:
list_of_list.append(associative_list)
# Return a list of users if any was defined
if user_list:
return user_list
# Compute the cartesian product and return the codes
# return filter(lambda x: x, map(lambda x: '_'.join(x), cartesianProduct(list_of_list)))
return ['_'.join(x) for x in cartesianProduct(list_of_list) if x]
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>category_order, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Type_asSecurityGroupId</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
# Google and Facebook should be included too.
return len(context.contentValues(portal_type="ERP5 Login"))
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Person_hasLogin</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
"""Hook called when a computer object is closed.
We want to reset reference, which is the user login in ERP5Security.
One exception is when a person object is installed from business template.
"""
# Slave Instance don't have user id to be set.
if context.getPortalType() == "Slave Instance":
return
context.setUserId(None)
context.SoftwareInstance_initUserId()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SoftwareInstance_afterClone</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Guard" module="Products.DCWorkflow.Guard"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>roles</string> </key>
<value>
<tuple>
<string>Owner</string>
</tuple>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SoftwareInstance_init</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
if not context.hasUserId():
context.setUserId(
'SI%i' % (
context.getPortalObject().portal_ids.generateNewId(
id_group='user_id',
id_generator='non_continuous_integer_increasing',
),
),
)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SoftwareInstance_initUserId</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Guard" module="Products.DCWorkflow.Guard"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>roles</string> </key>
<value>
<tuple>
<string>Owner</string>
</tuple>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -3,16 +3,10 @@ promise_dict = { ...@@ -3,16 +3,10 @@ promise_dict = {
'SlapOS Machine Authentication Plugin', 'SlapOS Machine Authentication Plugin',
'ERP5 Access Token Extraction Plugin', 'ERP5 Access Token Extraction Plugin',
], ],
'IAuthenticationPlugin': [
'SlapOS Machine Authentication Plugin',
'SlapOS Shadow Authentication Plugin',
],
'IGroupsPlugin': [ 'IGroupsPlugin': [
'SlapOS Machine Authentication Plugin',
'SlapOS Shadow Authentication Plugin', 'SlapOS Shadow Authentication Plugin',
], ],
'IUserEnumerationPlugin': [ 'IUserEnumerationPlugin': [
'SlapOS Machine Authentication Plugin',
'SlapOS Shadow Authentication Plugin', 'SlapOS Shadow Authentication Plugin',
] ]
} }
......
# Copyright (c) 2002-2012 Nexedi SA and Contributors. All Rights Reserved. # Copyright (c) 2002-2012 Nexedi SA and Contributors. All Rights Reserved.
import transaction import transaction
from Products.SlapOS.tests.testSlapOSMixin import \ from Products.SlapOS.tests.testSlapOSMixin import \
testSlapOSMixin testSlapOSMixin, simulate
from Products.ERP5Type.tests.utils import createZODBPythonScript from Products.ERP5Type.tests.utils import createZODBPythonScript
from unittest import skip from unittest import skip
import json import json
...@@ -10,25 +10,7 @@ from zExceptions import Unauthorized ...@@ -10,25 +10,7 @@ from zExceptions import Unauthorized
from DateTime import DateTime from DateTime import DateTime
from Products.ERP5Type.DateUtils import addToDate from Products.ERP5Type.DateUtils import addToDate
from App.Common import rfc1123_date from App.Common import rfc1123_date
from functools import wraps
def simulate(script_id, params_string, code_string):
def upperWrap(f):
@wraps(f)
def decorated(self, *args, **kw):
if script_id in self.portal.portal_skins.custom.objectIds():
raise ValueError('Precondition failed: %s exists in custom' % script_id)
createZODBPythonScript(self.portal.portal_skins.custom,
script_id, params_string, code_string)
try:
result = f(self, *args, **kw)
finally:
if script_id in self.portal.portal_skins.custom.objectIds():
self.portal.portal_skins.custom.manage_delObjects(script_id)
transaction.commit()
return result
return decorated
return upperWrap
class TestSlapOSCorePromiseSlapOSModuleIdGeneratorAlarm(testSlapOSMixin): class TestSlapOSCorePromiseSlapOSModuleIdGeneratorAlarm(testSlapOSMixin):
......
...@@ -30,96 +30,110 @@ import unittest ...@@ -30,96 +30,110 @@ import unittest
import random import random
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from Products.SlapOS.tests.testSlapOSMixin import testSlapOSMixin from Products.SlapOS.tests.testSlapOSMixin import testSlapOSMixin
from Products.PluggableAuthService.interfaces.plugins import\
IAuthenticationPlugin
class TestSlapOSSecurityMixin(testSlapOSMixin): class TestSlapOSSecurityMixin(testSlapOSMixin):
def _generateRandomUniqueReference(self, portal_type):
reference = None def _generateRandomUniqueUserId(self, portal_type, search_key="user_id"):
while reference is None: user_id = None
random_reference = "test_%s" % random.random() while user_id is None:
random_user_id = "test_%s_%s" % (
portal_type.replace(" ", "_").lower(), random.random())
result_list = self.portal.portal_catalog( result_list = self.portal.portal_catalog(
portal_type=portal_type, portal_type=portal_type,
reference=random_reference, **{search_key: random_user_id}
) )
if not len(result_list): if not len(result_list):
reference = random_reference user_id = random_user_id
return reference return user_id
def _assertUserExists(self, login, password): def _generateRandomUniqueReference(self, portal_type):
return self._generateRandomUniqueUserId(portal_type, "reference")
def _assertUserExists(self, user_id, login, password):
"""Checks that a user with login and password exists and can log in to the """Checks that a user with login and password exists and can log in to the
system. system.
""" """
from Products.PluggableAuthService.interfaces.plugins import\
IAuthenticationPlugin
uf = self.getUserFolder() uf = self.getUserFolder()
self.assertNotEquals(uf.getUserById(login, None), None) self.assertNotEquals(uf.getUserById(user_id, None), None)
for plugin_name, plugin in uf._getOb('plugins').listPlugins( for _, plugin in uf._getOb('plugins').listPlugins(
IAuthenticationPlugin ): IAuthenticationPlugin ):
if plugin.authenticateCredentials( if plugin.authenticateCredentials(
{'login':login, {'login_portal_type': 'ERP5 Login',
'password':password, 'external_login': login}) is not None:
'machine_login': login}) is not None:
break break
else: else:
self.fail("No plugin could authenticate '%s' with password '%s'" % self.fail("No plugin could authenticate '%s' with password '%s'" %
(login, password)) (login, password))
def _assertUserDoesNotExists(self, login, password): def _assertUserDoesNotExists(self, user_id, login, password):
"""Checks that a user with login and password does not exists and cannot """Checks that a user with login and password does not exists and cannot
log in to the system. log in to the system.
""" """
from Products.PluggableAuthService.interfaces.plugins import\
IAuthenticationPlugin
uf = self.getUserFolder() uf = self.getUserFolder()
for plugin_name, plugin in uf._getOb('plugins').listPlugins( for plugin_name, plugin in uf._getOb('plugins').listPlugins(
IAuthenticationPlugin ): IAuthenticationPlugin ):
if plugin.authenticateCredentials( if plugin.authenticateCredentials(
{'login':login, {'login_portal_type': 'ERP5 Login',
'password':password, 'external_login': login}) is not None:
'machine_login': login}) is not None:
self.fail( self.fail(
"Plugin %s should not have authenticated '%s' with password '%s'" % "Plugin %s should not have authenticated '%s' with password '%s'" %
(plugin_name, login, password)) (plugin_name, login, password))
class TestSlapOSComputerSecurity(TestSlapOSSecurityMixin): class TestSlapOSComputerSecurity(TestSlapOSSecurityMixin):
def test_active(self): def test_active(self):
user_id = self._generateRandomUniqueUserId('Computer')
reference = self._generateRandomUniqueReference('Computer') reference = self._generateRandomUniqueReference('Computer')
computer = self.portal.computer_module.newContent(portal_type='Computer', computer = self.portal.computer_module.newContent(
reference=reference) portal_type='Computer', reference=reference)
computer.setUserId(user_id)
computer.validate() computer.validate()
computer.newContent(portal_type='ERP5 Login',
reference=reference).validate()
computer.recursiveImmediateReindexObject() computer.recursiveImmediateReindexObject()
self._assertUserExists(reference, None) self._assertUserExists(user_id, reference, None)
self.login(reference) self.login(user_id)
user = getSecurityManager().getUser() user = getSecurityManager().getUser()
self.assertTrue('Authenticated' in user.getRoles()) self.assertTrue('Authenticated' in user.getRoles())
self.assertSameSet(['R-COMPUTER'], self.assertSameSet(['R-COMPUTER'],
user.getGroups()) user.getGroups())
def test_inactive(self): def test_inactive(self):
user_id = self._generateRandomUniqueUserId('Computer')
reference = self._generateRandomUniqueReference('Computer') reference = self._generateRandomUniqueReference('Computer')
computer = self.portal.computer_module.newContent(portal_type='Computer', computer = self.portal.computer_module.newContent(
reference=reference) portal_type='Computer', reference=reference)
computer.setUserId(user_id)
computer.newContent(portal_type='ERP5 Login',
reference=reference)
computer.recursiveImmediateReindexObject() computer.recursiveImmediateReindexObject()
self._assertUserDoesNotExists(reference, None) self._assertUserDoesNotExists(user_id, reference, None)
class TestSlapOSSoftwareInstanceSecurity(TestSlapOSSecurityMixin): class TestSlapOSSoftwareInstanceSecurity(TestSlapOSSecurityMixin):
portal_type = 'Software Instance' portal_type = 'Software Instance'
def test_active(self): def test_active(self):
user_id = self._generateRandomUniqueUserId(self.portal_type)
reference = self._generateRandomUniqueReference(self.portal_type) reference = self._generateRandomUniqueReference(self.portal_type)
instance = self.portal.getDefaultModule(portal_type=self.portal_type)\ instance = self.portal.getDefaultModule(portal_type=self.portal_type)\
.newContent(portal_type=self.portal_type, reference=reference) .newContent(portal_type=self.portal_type, reference=reference)
instance.setUserId(user_id)
instance.validate() instance.validate()
instance.newContent(portal_type='ERP5 Login',
reference=reference).validate()
instance.recursiveImmediateReindexObject() instance.recursiveImmediateReindexObject()
self._assertUserExists(reference, None) self._assertUserExists(user_id, reference, None)
# instance w/o subscription is loggable and it has some roles # instance w/o subscription is loggable and it has some roles
self.login(reference) self.login(user_id)
user = getSecurityManager().getUser() user = getSecurityManager().getUser()
self.assertTrue('Authenticated' in user.getRoles()) self.assertTrue('Authenticated' in user.getRoles())
self.assertSameSet(['R-INSTANCE'], self.assertSameSet(['R-INSTANCE'],
...@@ -129,7 +143,8 @@ class TestSlapOSSoftwareInstanceSecurity(TestSlapOSSecurityMixin): ...@@ -129,7 +143,8 @@ class TestSlapOSSoftwareInstanceSecurity(TestSlapOSSecurityMixin):
subscription_reference = self._generateRandomUniqueReference( subscription_reference = self._generateRandomUniqueReference(
'Hosting Suscription') 'Hosting Suscription')
subscription = self.portal.hosting_subscription_module.newContent( subscription = self.portal.hosting_subscription_module.newContent(
portal_type='Hosting Subscription', reference=subscription_reference) portal_type='Hosting Subscription',
reference=subscription_reference)
subscription.validate() subscription.validate()
instance.setSpecialise(subscription.getRelativeUrl()) instance.setSpecialise(subscription.getRelativeUrl())
subscription.recursiveImmediateReindexObject() subscription.recursiveImmediateReindexObject()
...@@ -137,33 +152,42 @@ class TestSlapOSSoftwareInstanceSecurity(TestSlapOSSecurityMixin): ...@@ -137,33 +152,42 @@ class TestSlapOSSoftwareInstanceSecurity(TestSlapOSSecurityMixin):
# clear cache in order to reset calculation # clear cache in order to reset calculation
self.portal.portal_caches.clearAllCache() self.portal.portal_caches.clearAllCache()
self.login(reference) self.login(user_id)
user = getSecurityManager().getUser() user = getSecurityManager().getUser()
self.assertTrue('Authenticated' in user.getRoles()) self.assertTrue('Authenticated' in user.getRoles())
self.assertSameSet(['R-INSTANCE', subscription_reference], self.assertSameSet(['R-INSTANCE', subscription_reference],
user.getGroups()) user.getGroups())
def test_inactive(self): def test_inactive(self):
user_id = self._generateRandomUniqueUserId(self.portal_type)
reference = self._generateRandomUniqueReference(self.portal_type) reference = self._generateRandomUniqueReference(self.portal_type)
instance = self.portal.getDefaultModule(portal_type=self.portal_type)\ instance = self.portal.getDefaultModule(portal_type=self.portal_type)\
.newContent(portal_type=self.portal_type, reference=reference) .newContent(portal_type=self.portal_type, reference=reference)
instance.setUserId(user_id)
instance.recursiveImmediateReindexObject() instance.recursiveImmediateReindexObject()
self._assertUserDoesNotExists(reference, None) self._assertUserDoesNotExists(user_id, reference, None)
class TestSlapOSPersonSecurity(TestSlapOSSecurityMixin): class TestSlapOSPersonSecurity(TestSlapOSSecurityMixin):
def test_active(self): def test_active(self):
password = str(random.random()) password = str(random.random())
reference = self._generateRandomUniqueReference('Person') reference = self._generateRandomUniqueReference('Person')
person = self.portal.person_module.newContent(portal_type='Person', user_id = self._generateRandomUniqueUserId('Person')
person = self.portal.person_module.newContent(
portal_type='Person',
reference=reference, password=password) reference=reference, password=password)
person.setUserId(user_id)
person.newContent(portal_type='Assignment').open() person.newContent(portal_type='Assignment').open()
person.newContent(portal_type='ERP5 Login',
reference=reference, password=password).validate()
self.commit() self.commit()
person.recursiveImmediateReindexObject() person.recursiveImmediateReindexObject()
self._assertUserExists(reference, password) self._assertUserExists(user_id, reference, password)
self.login(person.getUserId()) self.login(person.getUserId())
user = getSecurityManager().getUser() user = getSecurityManager().getUser()
...@@ -177,7 +201,6 @@ class TestSlapOSPersonSecurity(TestSlapOSSecurityMixin): ...@@ -177,7 +201,6 @@ class TestSlapOSPersonSecurity(TestSlapOSSecurityMixin):
self.commit() self.commit()
person.recursiveImmediateReindexObject() person.recursiveImmediateReindexObject()
self.tic() self.tic()
self.portal.portal_caches.clearAllCache() self.portal.portal_caches.clearAllCache()
self.login(person.getUserId()) self.login(person.getUserId())
...@@ -199,13 +222,15 @@ class TestSlapOSPersonSecurity(TestSlapOSSecurityMixin): ...@@ -199,13 +222,15 @@ class TestSlapOSPersonSecurity(TestSlapOSSecurityMixin):
def test_inactive(self): def test_inactive(self):
password = str(random.random()) password = str(random.random())
reference = self._generateRandomUniqueReference('Person') reference = self._generateRandomUniqueReference('Person')
user_id = self._generateRandomUniqueReference('Person')
person = self.portal.person_module.newContent(portal_type='Person', person = self.portal.person_module.newContent(portal_type='Person',
reference=reference, password=password) reference=reference, password=password)
self.commit() self.commit()
person.recursiveImmediateReindexObject() person.recursiveImmediateReindexObject()
self._assertUserDoesNotExists(reference, password) self._assertUserDoesNotExists(user_id, reference, password)
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
......
...@@ -6,10 +6,22 @@ ...@@ -6,10 +6,22 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>testSlapOSCloudSecurityGroup</string> </value> <value> <string>testSlapOSCloudSecurityGroup</string> </value>
</item> </item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>test.erp5.testSlapOSCloudSecurityGroup</string> </value> <value> <string>test.erp5.testSlapOSCloudSecurityGroup</string> </value>
...@@ -33,9 +45,7 @@ ...@@ -33,9 +45,7 @@
<item> <item>
<key> <string>text_content_warning_message</string> </key> <key> <string>text_content_warning_message</string> </key>
<value> <value>
<tuple> <tuple/>
<string>W: 56, 8: Unused variable \'plugin_name\' (unused-variable)</string>
</tuple>
</value> </value>
</item> </item>
<item> <item>
...@@ -45,13 +55,28 @@ ...@@ -45,13 +55,28 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -64,7 +89,7 @@ ...@@ -64,7 +89,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -73,7 +98,7 @@ ...@@ -73,7 +98,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="3" aka="AAAAAAAAAAM="> <record id="4" aka="AAAAAAAAAAQ=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle> </pickle>
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
import unittest import unittest
import random import random
import transaction
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from erp5.component.test.testSlapOSCloudSecurityGroup import TestSlapOSSecurityMixin from erp5.component.test.testSlapOSCloudSecurityGroup import TestSlapOSSecurityMixin
...@@ -36,96 +35,125 @@ class TestSlapOSShadowPerson(TestSlapOSSecurityMixin): ...@@ -36,96 +35,125 @@ class TestSlapOSShadowPerson(TestSlapOSSecurityMixin):
def test_active(self): def test_active(self):
password = str(random.random()) password = str(random.random())
reference = self._generateRandomUniqueReference('Person') reference = self._generateRandomUniqueReference('Person')
shadow_reference = 'SHADOW-%s' % reference user_id = self._generateRandomUniqueUserId('Person')
person = self.portal.person_module.newContent(portal_type='Person', shadow_user_id = 'SHADOW-%s' % user_id
reference=reference, password=password)
person = self.portal.person_module.newContent(
portal_type='Person')
person.setUserId(user_id)
person.newContent(portal_type='Assignment').open() person.newContent(portal_type='Assignment').open()
transaction.commit() person.newContent(portal_type='ERP5 Login',
reference=reference, password=password).validate()
self.commit()
person.recursiveImmediateReindexObject() person.recursiveImmediateReindexObject()
self._assertUserExists(reference, password) self._assertUserExists(user_id, reference, password)
self._assertUserExists(shadow_reference, None)
self.login(shadow_reference) # XXX shadow user cannot login himself.
self._assertUserExists(shadow_user_id, reference, None)
self.login(shadow_user_id)
user = getSecurityManager().getUser() user = getSecurityManager().getUser()
self.assertTrue('Authenticated' in user.getRoles()) self.assertTrue('Authenticated' in user.getRoles())
self.assertSameSet(['R-SHADOW-PERSON', 'SHADOW-%s' % reference], self.assertSameSet(['R-SHADOW-PERSON', 'SHADOW-%s' % user_id],
user.getGroups()) user.getGroups())
def test_inactive(self): def test_inactive(self):
password = str(random.random()) password = str(random.random())
reference = self._generateRandomUniqueReference('Person') reference = self._generateRandomUniqueReference('Person')
shadow_reference = 'SHADOW-%s' % reference user_id = self._generateRandomUniqueUserId('Person')
person = self.portal.person_module.newContent(portal_type='Person',
reference=reference, password=password)
transaction.commit() shadow_user_id = 'SHADOW-%s' % user_id
person = self.portal.person_module.newContent(
portal_type='Person')
person.setUserId(user_id)
self.commit()
person.recursiveImmediateReindexObject() person.recursiveImmediateReindexObject()
self._assertUserDoesNotExists(reference, password) self._assertUserDoesNotExists(user_id, reference, password)
self._assertUserDoesNotExists(shadow_reference, None) self._assertUserDoesNotExists(shadow_user_id, reference, None)
class TestSlapOSShadowComputer(TestSlapOSSecurityMixin): class TestSlapOSShadowComputer(TestSlapOSSecurityMixin):
def test_active(self): def test_active(self):
reference = self._generateRandomUniqueReference('Computer') reference = self._generateRandomUniqueReference('Computer')
shadow_reference = 'SHADOW-%s' % reference user_id = self._generateRandomUniqueUserId('Computer')
shadow_user_id = 'SHADOW-%s' % user_id
computer = self.portal.computer_module.newContent(portal_type='Computer', computer = self.portal.computer_module.newContent(portal_type='Computer',
reference=reference) reference=reference)
computer.setUserId(user_id)
computer.newContent(portal_type='ERP5 Login',
reference=reference).validate()
computer.validate() computer.validate()
computer.recursiveImmediateReindexObject() computer.recursiveImmediateReindexObject()
self._assertUserExists(reference, None) self._assertUserExists(user_id, reference, None)
self._assertUserExists(shadow_reference, None) self._assertUserExists(shadow_user_id, reference, None)
self.login(shadow_reference) self.login(shadow_user_id)
user = getSecurityManager().getUser() user = getSecurityManager().getUser()
self.assertTrue('Authenticated' in user.getRoles()) self.assertTrue('Authenticated' in user.getRoles())
self.assertSameSet(['R-SHADOW-COMPUTER', 'SHADOW-%s' % reference], self.assertSameSet(['R-SHADOW-COMPUTER', 'SHADOW-%s' % user_id],
user.getGroups()) user.getGroups())
def test_inactive(self): def test_inactive(self):
reference = self._generateRandomUniqueReference('Computer') reference = self._generateRandomUniqueReference('Computer')
user_id = self._generateRandomUniqueUserId('Computer')
shadow_reference = 'SHADOW-%s' % reference shadow_reference = 'SHADOW-%s' % reference
computer = self.portal.computer_module.newContent(portal_type='Computer', computer = self.portal.computer_module.newContent(portal_type='Computer',
reference=reference) reference=reference)
computer.setUserId(user_id)
computer.recursiveImmediateReindexObject() computer.recursiveImmediateReindexObject()
self._assertUserDoesNotExists(reference, None) self._assertUserDoesNotExists(user_id, reference, None)
self._assertUserDoesNotExists(shadow_reference, None) self._assertUserDoesNotExists(user_id, shadow_reference, None)
class TestSlapOSShadowSoftwareInstance(TestSlapOSSecurityMixin): class TestSlapOSShadowSoftwareInstance(TestSlapOSSecurityMixin):
portal_type = 'Software Instance' portal_type = 'Software Instance'
def test_active(self): def test_active(self):
reference = self._generateRandomUniqueReference(self.portal_type) reference = self._generateRandomUniqueReference(self.portal_type)
shadow_reference = 'SHADOW-%s' % reference user_id = self._generateRandomUniqueUserId(self.portal_type)
shadow_user_id = 'SHADOW-%s' % user_id
instance = self.portal.getDefaultModule(portal_type=self.portal_type)\ instance = self.portal.getDefaultModule(portal_type=self.portal_type)\
.newContent(portal_type=self.portal_type, reference=reference) .newContent(portal_type=self.portal_type, reference=reference)
instance.setUserId(user_id)
instance.newContent(portal_type='ERP5 Login',
reference=reference).validate()
instance.validate() instance.validate()
instance.recursiveImmediateReindexObject() instance.recursiveImmediateReindexObject()
self._assertUserExists(reference, None) self._assertUserExists(user_id, reference, None)
self._assertUserExists(shadow_reference, None) self._assertUserExists(shadow_user_id, reference, None)
self.login(shadow_reference) self.login(shadow_user_id)
user = getSecurityManager().getUser() user = getSecurityManager().getUser()
self.assertTrue('Authenticated' in user.getRoles()) self.assertTrue('Authenticated' in user.getRoles())
self.assertSameSet(['R-SHADOW-SOFTWAREINSTANCE', 'SHADOW-%s' % reference], self.assertSameSet(['R-SHADOW-SOFTWAREINSTANCE', 'SHADOW-%s' % user_id],
user.getGroups()) user.getGroups())
def test_inactive(self): def test_inactive(self):
reference = self._generateRandomUniqueReference(self.portal_type) reference = self._generateRandomUniqueReference(self.portal_type)
user_id = self._generateRandomUniqueUserId(self.portal_type)
shadow_reference = 'SHADOW-%s' % reference shadow_reference = 'SHADOW-%s' % reference
instance = self.portal.getDefaultModule(portal_type=self.portal_type)\ instance = self.portal.getDefaultModule(portal_type=self.portal_type)\
.newContent(portal_type=self.portal_type, reference=reference) .newContent(portal_type=self.portal_type, reference=reference)
instance.setUserId(user_id)
instance.recursiveImmediateReindexObject() instance.recursiveImmediateReindexObject()
self._assertUserDoesNotExists(reference, None) self._assertUserDoesNotExists(user_id, reference, None)
self._assertUserDoesNotExists(shadow_reference, None) self._assertUserDoesNotExists(user_id, shadow_reference, None)
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
......
...@@ -6,10 +6,22 @@ ...@@ -6,10 +6,22 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>testSlapOSCloudShadow</string> </value> <value> <string>testSlapOSCloudShadow</string> </value>
</item> </item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>test.erp5.testSlapOSCloudShadow</string> </value> <value> <string>test.erp5.testSlapOSCloudShadow</string> </value>
...@@ -27,9 +39,7 @@ ...@@ -27,9 +39,7 @@
<item> <item>
<key> <string>text_content_error_message</string> </key> <key> <string>text_content_error_message</string> </key>
<value> <value>
<tuple> <tuple/>
<string>F: 33, 0: Unable to import \'testSlapOSCloudSecurityGroup\' (import-error)</string>
</tuple>
</value> </value>
</item> </item>
<item> <item>
...@@ -45,13 +55,28 @@ ...@@ -45,13 +55,28 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -64,7 +89,7 @@ ...@@ -64,7 +89,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -73,7 +98,7 @@ ...@@ -73,7 +98,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="3" aka="AAAAAAAAAAM="> <record id="4" aka="AAAAAAAAAAQ=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle> </pickle>
......
...@@ -5,4 +5,11 @@ computer.edit( ...@@ -5,4 +5,11 @@ computer.edit(
allocation_scope='open/personal', allocation_scope='open/personal',
source_administration_value=person, source_administration_value=person,
) )
erp5_login = computer.newContent(
portal_type="ERP5 Login",
reference=computer.getReference()
)
erp5_login.validate()
portal.portal_workflow.doActionFor(computer, 'validate_action') portal.portal_workflow.doActionFor(computer, 'validate_action')
...@@ -98,8 +98,14 @@ if (request_software_instance is None): ...@@ -98,8 +98,14 @@ if (request_software_instance is None):
activate_kw={'tag': tag}, activate_kw={'tag': tag},
**new_content_kw **new_content_kw
) )
# request_software_instance.portal_workflow.doActionFor(request_software_instance, 'validate_action')
request_software_instance.validate() request_software_instance.validate()
if software_instance_portal_type == "Software Instance":
# Include ERP5 Login so Instance become a User
erp5_login = request_software_instance.newContent(
portal_type="ERP5 Login",
reference=request_software_instance.getReference())
erp5_login = erp5_login.validate()
graph[request_software_instance.getUid()] = [] graph[request_software_instance.getUid()] = []
else: else:
......
Computer | ERP5 Login
Hosting Subscription Module | Hosting Subscription Hosting Subscription Module | Hosting Subscription
Software Installation Module | Software Installation Software Installation Module | Software Installation
Software Instance Module | Slave Instance Software Instance Module | Slave Instance
Software Instance Module | Software Instance Software Instance Module | Software Instance
\ No newline at end of file Software Instance | ERP5 Login
\ No newline at end of file
Computer
Hosting Subscription Hosting Subscription
Hosting Subscription Module Hosting Subscription Module
Slave Instance Slave Instance
......
...@@ -2,6 +2,7 @@ Assignment | SlaposAssignmentConstraint ...@@ -2,6 +2,7 @@ Assignment | SlaposAssignmentConstraint
Computer Model | SlaposCapacity Computer Model | SlaposCapacity
Computer Partition | ComputerPartition Computer Partition | ComputerPartition
Computer Partition | SlaposComputerPartitionConstraint Computer Partition | SlaposComputerPartitionConstraint
Computer | ERP5User
Computer | SlaposCapacity Computer | SlaposCapacity
Computer | SlaposComputerConstraint Computer | SlaposComputerConstraint
Computer | Url Computer | Url
...@@ -22,6 +23,7 @@ Slave Instance | Url ...@@ -22,6 +23,7 @@ Slave Instance | Url
Slave Instance | VariationRange Slave Instance | VariationRange
Software Installation | Url Software Installation | Url
Software Installation | VariationRange Software Installation | VariationRange
Software Instance | ERP5User
Software Instance | HostingSubscription Software Instance | HostingSubscription
Software Instance | Reference Software Instance | Reference
Software Instance | SoftwareInstance Software Instance | SoftwareInstance
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
</role> </role>
<role id='Assignor'> <role id='Assignor'>
<property id='title'>Self Computer</property> <property id='title'>Self Computer</property>
<property id='condition'>python: context.getReference("") != ""</property> <property id='condition'>python: context.getUserId("") != ""</property>
<property id='base_category_script'>ERP5Type_getSecurityCategoryFromSelf</property> <property id='base_category_script'>ERP5Type_getSecurityCategoryFromSelf</property>
<multi_property id='base_category'>destination_decision</multi_property> <multi_property id='base_category'>destination_decision</multi_property>
</role> </role>
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
if obj is None: if obj is None:
return [] return []
portal = obj.getPortalObject()
computer = obj computer = obj
category_list = [] category_list = []
...@@ -22,10 +21,10 @@ if scope == 'open/public': ...@@ -22,10 +21,10 @@ if scope == 'open/public':
elif scope == 'open/personal': elif scope == 'open/personal':
person = computer.getSourceAdministrationValue(portal_type="Person") person = computer.getSourceAdministrationValue(portal_type="Person")
if person is not None: if person is not None:
return {"Auditor": ["SHADOW-%s" % person.getReference()]} return {"Auditor": ["SHADOW-%s" % person.getUserId()]}
elif scope == 'open/friend': elif scope == 'open/friend':
person_list = computer.getDestinationSectionValueList(portal_type="Person") person_list = computer.getDestinationSectionValueList(portal_type="Person")
if person_list: if person_list:
return {"Auditor": ["SHADOW-%s" % x.getReference() for x in person_list]} return {"Auditor": ["SHADOW-%s" % x.getUserId() for x in person_list]}
return category_list return category_list
...@@ -33,6 +33,6 @@ if obj is None: ...@@ -33,6 +33,6 @@ if obj is None:
person = obj.getDestinationSectionValue(portal_type="Person") person = obj.getDestinationSectionValue(portal_type="Person")
if person is not None: if person is not None:
for base_category in base_category_list: for base_category in base_category_list:
return {"Auditor": ["SHADOW-%s" % person.getReference()]} return {"Auditor": ["SHADOW-%s" % person.getUserId()]}
return category_list return category_list
...@@ -33,6 +33,6 @@ if obj is None: ...@@ -33,6 +33,6 @@ if obj is None:
person = obj.getDestinationSectionValue(portal_type="Person") person = obj.getDestinationSectionValue(portal_type="Person")
if person is not None: if person is not None:
for base_category in base_category_list: for base_category in base_category_list:
return {"Assignee": ["SHADOW-%s" % person.getReference()]} return {"Assignee": ["SHADOW-%s" % person.getUserId()]}
return category_list return category_list
...@@ -5,7 +5,7 @@ the categories from the current content and associates ...@@ -5,7 +5,7 @@ the categories from the current content and associates
it to a given base_category. It is useful in the it to a given base_category. It is useful in the
following cases: following cases:
- calculate a security group based current object - calculate a security group based current object
in the context of a base category (ex. source_project). in the context of a base category (ex. source_project).
This is used for example in ERP5 DMS to calculate This is used for example in ERP5 DMS to calculate
project security. project security.
...@@ -20,9 +20,7 @@ The parameters are ...@@ -20,9 +20,7 @@ The parameters are
NOTE: for now, this script requires proxy manager NOTE: for now, this script requires proxy manager
""" """
category_list = []
if obj is None: if obj is None:
return [] return []
return {'Auditor': ['SHADOW-%s' % obj.getReference()]} return {'Auditor': ['SHADOW-%s' % obj.getUserId()]}
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
############################################################################## ##############################################################################
from erp5.component.test.testSlapOSCloudSecurityGroup import TestSlapOSSecurityMixin from erp5.component.test.testSlapOSCloudSecurityGroup import TestSlapOSSecurityMixin
from Products.SlapOS.tests.testSlapOSMixin import changeSkin
import re import re
import xml_marshaller import xml_marshaller
from AccessControl.SecurityManagement import getSecurityManager, \ from AccessControl.SecurityManagement import getSecurityManager, \
...@@ -13,21 +14,6 @@ from AccessControl.SecurityManagement import getSecurityManager, \ ...@@ -13,21 +14,6 @@ from AccessControl.SecurityManagement import getSecurityManager, \
from DateTime import DateTime from DateTime import DateTime
import json import json
def changeSkin(skin_name):
def decorator(func):
def wrapped(self, *args, **kwargs):
default_skin = self.portal.portal_skins.default_skin
self.portal.portal_skins.changeSkin(skin_name)
self.app.REQUEST.set('portal_skin', skin_name)
try:
v = func(self, *args, **kwargs)
finally:
self.portal.portal_skins.changeSkin(default_skin)
self.app.REQUEST.set('portal_skin', default_skin)
return v
return wrapped
return decorator
class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin): class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin):
def joinSlapOS(self, web_site, reference): def joinSlapOS(self, web_site, reference):
def findMessage(email, body): def findMessage(email, body):
...@@ -151,7 +137,7 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin): ...@@ -151,7 +137,7 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin):
)) ))
sm = getSecurityManager() sm = getSecurityManager()
try: try:
self.login(computer.getReference()) self.login(computer.getUserId())
self.portal.portal_slap.loadComputerConfigurationFromXML( self.portal.portal_slap.loadComputerConfigurationFromXML(
xml_marshaller.xml_marshaller.dumps(computer_dict)) xml_marshaller.xml_marshaller.dumps(computer_dict))
self.tic() self.tic()
...@@ -162,9 +148,9 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin): ...@@ -162,9 +148,9 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin):
def simulateSlapgridSR(self, computer): def simulateSlapgridSR(self, computer):
sm = getSecurityManager() sm = getSecurityManager()
computer_reference = computer.getReference() computer_user_id = computer.getUserId()
try: try:
self.login(computer_reference) self.login(computer_user_id)
computer_xml = self.portal.portal_slap.getFullComputerInformation( computer_xml = self.portal.portal_slap.getFullComputerInformation(
computer_id=computer.getReference()) computer_id=computer.getReference())
slap_computer = xml_marshaller.xml_marshaller.loads(computer_xml) slap_computer = xml_marshaller.xml_marshaller.loads(computer_xml)
...@@ -184,9 +170,9 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin): ...@@ -184,9 +170,9 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin):
def simulateSlapgridUR(self, computer): def simulateSlapgridUR(self, computer):
sm = getSecurityManager() sm = getSecurityManager()
computer_reference = computer.getReference() computer_user_id = computer.getUserId()
try: try:
self.login(computer_reference) self.login(computer_user_id)
computer_xml = self.portal.portal_slap.getFullComputerInformation( computer_xml = self.portal.portal_slap.getFullComputerInformation(
computer_id=computer.getReference()) computer_id=computer.getReference())
slap_computer = xml_marshaller.xml_marshaller.loads(computer_xml) slap_computer = xml_marshaller.xml_marshaller.loads(computer_xml)
...@@ -214,8 +200,9 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin): ...@@ -214,8 +200,9 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin):
def simulateSlapgridCP(self, computer): def simulateSlapgridCP(self, computer):
sm = getSecurityManager() sm = getSecurityManager()
computer_reference = computer.getReference() computer_reference = computer.getReference()
computer_user_id = computer.getUserId()
try: try:
self.login(computer_reference) self.login(computer_user_id)
computer_xml = self.portal.portal_slap.getFullComputerInformation( computer_xml = self.portal.portal_slap.getFullComputerInformation(
computer_id=computer.getReference()) computer_id=computer.getReference())
slap_computer = xml_marshaller.xml_marshaller.loads(computer_xml) slap_computer = xml_marshaller.xml_marshaller.loads(computer_xml)
...@@ -229,9 +216,13 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin): ...@@ -229,9 +216,13 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin):
url_1 = 'http://%s/' % ip_list[0][1], url_1 = 'http://%s/' % ip_list[0][1],
url_2 = 'http://%s/' % ip_list[1][1], url_2 = 'http://%s/' % ip_list[1][1],
)) ))
self.login()
instance_user_id = self.portal.portal_catalog.getResultValue(
reference=instance_reference, portal_type="Software Instance").getUserId()
oldsm = getSecurityManager() oldsm = getSecurityManager()
try: try:
self.login(instance_reference) self.login(instance_user_id)
self.portal.portal_slap.setComputerPartitionConnectionXml( self.portal.portal_slap.setComputerPartitionConnectionXml(
computer_id=computer_reference, computer_id=computer_reference,
computer_partition_id=partition._partition_id, computer_partition_id=partition._partition_id,
...@@ -314,10 +305,11 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin): ...@@ -314,10 +305,11 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin):
portal_type='Internet Protocol Address')], portal_type='Internet Protocol Address')],
connection_dict.values()) connection_dict.values())
def checkSlaveInstanceUnallocation(self, person_reference, instance_title, def checkSlaveInstanceUnallocation(self, person_user_id,
person_reference, instance_title,
software_release, software_type, server): software_release, software_type, server):
self.login(person_reference) self.login(person_user_id)
self.personRequestInstanceNotReady( self.personRequestInstanceNotReady(
software_release=software_release, software_release=software_release,
software_type=software_type, software_type=software_type,
...@@ -333,10 +325,11 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin): ...@@ -333,10 +325,11 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin):
self.assertEqual(0, len(hosting_subscription_list)) self.assertEqual(0, len(hosting_subscription_list))
def checkInstanceUnallocation(self, person_reference, instance_title, def checkInstanceUnallocation(self, person_user_id,
person_reference, instance_title,
software_release, software_type, server): software_release, software_type, server):
self.login(person_reference) self.login(person_user_id)
self.personRequestInstanceNotReady( self.personRequestInstanceNotReady(
software_release=software_release, software_release=software_release,
software_type=software_type, software_type=software_type,
...@@ -723,19 +716,21 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin): ...@@ -723,19 +716,21 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin):
friend_instance_type, friend_server) friend_instance_type, friend_server)
# now deallocate the slaves # now deallocate the slaves
self.checkSlaveInstanceUnallocation(public_reference, self.checkSlaveInstanceUnallocation(public_person.getUserId(),
public_slave_instance_title, friend_server_software, public_reference, public_slave_instance_title, friend_server_software,
friend_instance_type, friend_server) friend_instance_type, friend_server)
self.checkSlaveInstanceUnallocation(friend_reference, self.checkSlaveInstanceUnallocation(friend_person.getUserId(),
friend_slave_instance_title, public_server_software, friend_reference, friend_slave_instance_title, public_server_software,
public_instance_type, public_server) public_instance_type, public_server)
# and the instances # and the instances
self.checkInstanceUnallocation(public_reference, public_instance_title, self.checkInstanceUnallocation(public_person.getUserId(),
public_reference, public_instance_title,
public_server_software, public_instance_type, public_server) public_server_software, public_instance_type, public_server)
self.checkInstanceUnallocation(friend_reference, friend_instance_title, self.checkInstanceUnallocation(friend_person.getUserId(),
friend_reference, friend_instance_title,
friend_server_software, friend_instance_type, friend_server) friend_server_software, friend_instance_type, friend_server)
# and uninstall some software on them # and uninstall some software on them
......
...@@ -46,8 +46,8 @@ ...@@ -46,8 +46,8 @@
<key> <string>text_content_warning_message</string> </key> <key> <string>text_content_warning_message</string> </key>
<value> <value>
<tuple> <tuple>
<string>W: 38, 4: Unused variable \'credential_request_form\' (unused-variable)</string> <string>W: 24, 4: Unused variable \'credential_request_form\' (unused-variable)</string>
<string>W:872, 4: Unused variable \'credential_request_form\' (unused-variable)</string> <string>W:859, 4: Unused variable \'credential_request_form\' (unused-variable)</string>
</tuple> </tuple>
</value> </value>
</item> </item>
......
# Copyright (c) 2012 Nexedi SA and Contributors. All Rights Reserved. # Copyright (c) 2012 Nexedi SA and Contributors. All Rights Reserved.
from Products.SlapOS.tests.testSlapOSMixin import testSlapOSMixin from Products.SlapOS.tests.testSlapOSMixin import testSlapOSMixin
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
import transaction
class TestSlapOSGroupRoleSecurityMixin(testSlapOSMixin): class TestSlapOSGroupRoleSecurityMixin(testSlapOSMixin):
abort_transaction = 1
def afterSetUp(self): def afterSetUp(self):
super(TestSlapOSGroupRoleSecurityMixin, self).afterSetUp() super(TestSlapOSGroupRoleSecurityMixin, self).afterSetUp()
self.user_id = getSecurityManager().getUser().getId() self.user_id = getSecurityManager().getUser().getId()
def beforeTearDown(self):
transaction.abort()
def changeOwnership(self, document): def changeOwnership(self, document):
""" Change the ownership of the document to the right and """ Change the ownership of the document to the right and
expected user. Normally the user which setups the site. expected user. Normally the user which setups the site.
...@@ -71,9 +69,10 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin): ...@@ -71,9 +69,10 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin):
computer = self.portal.computer_module.newContent(portal_type='Computer') computer = self.portal.computer_module.newContent(portal_type='Computer')
computer.updateLocalRolesOnSecurityGroups() computer.updateLocalRolesOnSecurityGroups()
self.assertSecurityGroup(computer, self.assertSecurityGroup(computer,
['G-COMPANY', self.user_id], False) ['G-COMPANY', self.user_id, computer.getUserId()], False)
self.assertRoles(computer, 'G-COMPANY', ['Assignor']) self.assertRoles(computer, 'G-COMPANY', ['Assignor'])
self.assertRoles(computer, self.user_id, ['Owner']) self.assertRoles(computer, self.user_id, ['Owner'])
self.assertRoles(computer, computer.getUserId(), ['Assignor'])
def test_ComputerAgent(self): def test_ComputerAgent(self):
reference = 'TESTPERSON-%s' % self.generateNewId() reference = 'TESTPERSON-%s' % self.generateNewId()
...@@ -83,9 +82,10 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin): ...@@ -83,9 +82,10 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin):
source_administration=person.getRelativeUrl()) source_administration=person.getRelativeUrl())
computer.updateLocalRolesOnSecurityGroups() computer.updateLocalRolesOnSecurityGroups()
self.assertSecurityGroup(computer, self.assertSecurityGroup(computer,
[self.user_id, 'G-COMPANY', person.getUserId()], False) [self.user_id, 'G-COMPANY', person.getUserId(), computer.getUserId()], False)
self.assertRoles(computer, person.getUserId(), ['Assignee']) self.assertRoles(computer, person.getUserId(), ['Assignee'])
self.assertRoles(computer, self.user_id, ['Owner']) self.assertRoles(computer, self.user_id, ['Owner'])
self.assertRoles(computer, computer.getUserId(), ['Assignor'])
def test_AllocationScope(self): def test_AllocationScope(self):
computer = self.portal.computer_module.newContent(portal_type='Computer') computer = self.portal.computer_module.newContent(portal_type='Computer')
...@@ -94,9 +94,10 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin): ...@@ -94,9 +94,10 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin):
computer.edit(allocation_scope='open/public') computer.edit(allocation_scope='open/public')
computer.updateLocalRolesOnSecurityGroups() computer.updateLocalRolesOnSecurityGroups()
self.assertSecurityGroup(computer, self.assertSecurityGroup(computer,
[self.user_id, 'G-COMPANY', 'R-SHADOW-PERSON'], False) [self.user_id, 'G-COMPANY', 'R-SHADOW-PERSON', computer.getUserId()], False)
self.assertRoles(computer, 'R-SHADOW-PERSON', ['Auditor']) self.assertRoles(computer, 'R-SHADOW-PERSON', ['Auditor'])
self.assertRoles(computer, self.user_id, ['Owner']) self.assertRoles(computer, self.user_id, ['Owner'])
self.assertRoles(computer, computer.getUserId(), ['Assignor'])
# open/personal # open/personal
reference = 'TESTPERSON-%s' % self.generateNewId() reference = 'TESTPERSON-%s' % self.generateNewId()
...@@ -106,11 +107,14 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin): ...@@ -106,11 +107,14 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin):
source_administration=person.getRelativeUrl() source_administration=person.getRelativeUrl()
) )
computer.updateLocalRolesOnSecurityGroups() computer.updateLocalRolesOnSecurityGroups()
shadow_reference = 'SHADOW-%s' % reference shadow_user_id = 'SHADOW-%s' % person.getUserId()
self.assertSecurityGroup(computer, self.assertSecurityGroup(computer,
[self.user_id, 'G-COMPANY', shadow_reference, person.getUserId()], False) [self.user_id, 'G-COMPANY', shadow_user_id,
self.assertRoles(computer, shadow_reference, ['Auditor']) person.getUserId(), computer.getUserId()], False)
self.assertRoles(computer, shadow_user_id, ['Auditor'])
self.assertRoles(computer, self.user_id, ['Owner']) self.assertRoles(computer, self.user_id, ['Owner'])
self.assertRoles(computer, computer.getUserId(), ['Assignor'])
# open/friend # open/friend
friend_reference = 'TESTPERSON-%s' % self.generateNewId() friend_reference = 'TESTPERSON-%s' % self.generateNewId()
...@@ -120,11 +124,14 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin): ...@@ -120,11 +124,14 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin):
destination_section=friend_person.getRelativeUrl() destination_section=friend_person.getRelativeUrl()
) )
computer.updateLocalRolesOnSecurityGroups() computer.updateLocalRolesOnSecurityGroups()
shadow_friend_reference = 'SHADOW-%s' % friend_reference shadow_friend_user_id = 'SHADOW-%s' % friend_person.getUserId()
self.assertSecurityGroup(computer, self.assertSecurityGroup(computer,
[self.user_id, 'G-COMPANY', shadow_friend_reference, person.getUserId()], False) [self.user_id, 'G-COMPANY', shadow_friend_user_id,
self.assertRoles(computer, shadow_friend_reference, ['Auditor']) person.getUserId(), computer.getUserId()], False)
self.assertRoles(computer, shadow_friend_user_id, ['Auditor'])
self.assertRoles(computer, self.user_id, ['Owner']) self.assertRoles(computer, self.user_id, ['Owner'])
self.assertRoles(computer, computer.getUserId(), ['Assignor'])
def test_selfComputer(self): def test_selfComputer(self):
reference = 'TESTCOMP-%s' % self.generateNewId() reference = 'TESTCOMP-%s' % self.generateNewId()
...@@ -132,8 +139,8 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin): ...@@ -132,8 +139,8 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin):
reference=reference) reference=reference)
computer.updateLocalRolesOnSecurityGroups() computer.updateLocalRolesOnSecurityGroups()
self.assertSecurityGroup(computer, self.assertSecurityGroup(computer,
[self.user_id, 'G-COMPANY', reference], False) [self.user_id, 'G-COMPANY', computer.getUserId()], False)
self.assertRoles(computer, reference, ['Assignor']) self.assertRoles(computer, computer.getUserId(), ['Assignor'])
self.assertRoles(computer, self.user_id, ['Owner']) self.assertRoles(computer, self.user_id, ['Owner'])
class TestComputerModel(TestSlapOSGroupRoleSecurityMixin): class TestComputerModel(TestSlapOSGroupRoleSecurityMixin):
...@@ -602,11 +609,11 @@ class TestSlaveInstance(TestSlapOSGroupRoleSecurityMixin): ...@@ -602,11 +609,11 @@ class TestSlaveInstance(TestSlapOSGroupRoleSecurityMixin):
portal_type='Slave Instance', aggregate=partition.getRelativeUrl()) portal_type='Slave Instance', aggregate=partition.getRelativeUrl())
instance.updateLocalRolesOnSecurityGroups() instance.updateLocalRolesOnSecurityGroups()
self.assertSecurityGroup(instance, ['G-COMPANY', provider_reference, self.assertSecurityGroup(instance, ['G-COMPANY', provider.getUserId(),
computer_reference, self.user_id], False) computer.getUserId(), self.user_id], False)
self.assertRoles(instance, 'G-COMPANY', ['Assignor']) self.assertRoles(instance, 'G-COMPANY', ['Assignor'])
self.assertRoles(instance, provider_reference, ['Assignor']) self.assertRoles(instance, provider.getUserId(), ['Assignor'])
self.assertRoles(instance, computer_reference, ['Assignor']) self.assertRoles(instance, computer.getUserId(), ['Assignor'])
self.assertRoles(instance, self.user_id, ['Owner', 'Assignee']) self.assertRoles(instance, self.user_id, ['Owner', 'Assignee'])
test_Computer = test_SoftwareInstanceWhichProvidesThisSlaveInstance test_Computer = test_SoftwareInstanceWhichProvidesThisSlaveInstance
...@@ -636,9 +643,9 @@ class TestSoftwareInstallation(TestSlapOSGroupRoleSecurityMixin): ...@@ -636,9 +643,9 @@ class TestSoftwareInstallation(TestSlapOSGroupRoleSecurityMixin):
installation.updateLocalRolesOnSecurityGroups() installation.updateLocalRolesOnSecurityGroups()
self.assertSecurityGroup(installation, [self.user_id, self.assertSecurityGroup(installation, [self.user_id,
'G-COMPANY', computer_reference], False) 'G-COMPANY', computer.getUserId()], False)
self.assertRoles(installation, 'G-COMPANY', ['Assignor']) self.assertRoles(installation, 'G-COMPANY', ['Assignor'])
self.assertRoles(installation, computer_reference, ['Assignor']) self.assertRoles(installation, computer.getUserId(), ['Assignor'])
self.assertRoles(installation, self.user_id, ['Owner', 'Assignee']) self.assertRoles(installation, self.user_id, ['Owner', 'Assignee'])
def test_ProviderOfTheInstallation(self): def test_ProviderOfTheInstallation(self):
...@@ -717,10 +724,10 @@ class TestSoftwareInstance(TestSlapOSGroupRoleSecurityMixin): ...@@ -717,10 +724,10 @@ class TestSoftwareInstance(TestSlapOSGroupRoleSecurityMixin):
portal_type='Software Instance', aggregate=partition.getRelativeUrl()) portal_type='Software Instance', aggregate=partition.getRelativeUrl())
instance.updateLocalRolesOnSecurityGroups() instance.updateLocalRolesOnSecurityGroups()
self.assertSecurityGroup(instance, ['G-COMPANY', computer_reference, self.assertSecurityGroup(instance, ['G-COMPANY', computer.getUserId(),
self.user_id], False) self.user_id], False)
self.assertRoles(instance, 'G-COMPANY', ['Assignor']) self.assertRoles(instance, 'G-COMPANY', ['Assignor'])
self.assertRoles(instance, computer_reference, ['Assignor']) self.assertRoles(instance, computer.getUserId(), ['Assignor'])
self.assertRoles(instance, self.user_id, ['Owner', 'Assignee']) self.assertRoles(instance, self.user_id, ['Owner', 'Assignee'])
class TestSoftwareInstanceModule(TestSlapOSGroupRoleSecurityMixin): class TestSoftwareInstanceModule(TestSlapOSGroupRoleSecurityMixin):
...@@ -970,11 +977,11 @@ class TestPaymentTransaction(TestSlapOSGroupRoleSecurityMixin): ...@@ -970,11 +977,11 @@ class TestPaymentTransaction(TestSlapOSGroupRoleSecurityMixin):
destination_section_value=person, destination_section_value=person,
) )
product.updateLocalRolesOnSecurityGroups() product.updateLocalRolesOnSecurityGroups()
shadow_reference = 'SHADOW-%s' % reference shadow_user_id = 'SHADOW-%s' % person.getUserId()
self.assertSecurityGroup(product, self.assertSecurityGroup(product,
['G-COMPANY', self.user_id, person.getUserId(), shadow_reference], False) ['G-COMPANY', self.user_id, person.getUserId(), shadow_user_id], False)
self.assertRoles(product, 'G-COMPANY', ['Assignor']) self.assertRoles(product, 'G-COMPANY', ['Assignor'])
self.assertRoles(product, shadow_reference, ['Auditor']) self.assertRoles(product, shadow_user_id, ['Auditor'])
self.assertRoles(product, person.getUserId(), ['Auditor']) self.assertRoles(product, person.getUserId(), ['Auditor'])
self.assertRoles(product, self.user_id, ['Owner']) self.assertRoles(product, self.user_id, ['Owner'])
...@@ -988,11 +995,11 @@ class TestPaymentTransaction(TestSlapOSGroupRoleSecurityMixin): ...@@ -988,11 +995,11 @@ class TestPaymentTransaction(TestSlapOSGroupRoleSecurityMixin):
destination_section_value=person, destination_section_value=person,
) )
product.updateLocalRolesOnSecurityGroups() product.updateLocalRolesOnSecurityGroups()
shadow_reference = 'SHADOW-%s' % reference shadow_user_id = 'SHADOW-%s' % person.getUserId()
self.assertSecurityGroup(product, self.assertSecurityGroup(product,
['G-COMPANY', self.user_id, person.getUserId(), shadow_reference], False) ['G-COMPANY', self.user_id, person.getUserId(), shadow_user_id], False)
self.assertRoles(product, 'G-COMPANY', ['Assignor']) self.assertRoles(product, 'G-COMPANY', ['Assignor'])
self.assertRoles(product, shadow_reference, ['Auditor']) self.assertRoles(product, shadow_user_id, ['Auditor'])
self.assertRoles(product, person.getUserId(), ['Auditor']) self.assertRoles(product, person.getUserId(), ['Auditor'])
self.assertRoles(product, self.user_id, ['Owner']) self.assertRoles(product, self.user_id, ['Owner'])
...@@ -1973,11 +1980,11 @@ class TestPayzenEvent(TestSlapOSGroupRoleSecurityMixin): ...@@ -1973,11 +1980,11 @@ class TestPayzenEvent(TestSlapOSGroupRoleSecurityMixin):
destination_section_value=person, destination_section_value=person,
) )
product.updateLocalRolesOnSecurityGroups() product.updateLocalRolesOnSecurityGroups()
shadow_reference = 'SHADOW-%s' % reference shadow_user_id = 'SHADOW-%s' % person.getUserId()
self.assertSecurityGroup(product, self.assertSecurityGroup(product,
['G-COMPANY', self.user_id, shadow_reference], False) ['G-COMPANY', self.user_id, shadow_user_id], False)
self.assertRoles(product, 'G-COMPANY', ['Assignor']) self.assertRoles(product, 'G-COMPANY', ['Assignor'])
self.assertRoles(product, shadow_reference, ['Assignee']) self.assertRoles(product, shadow_user_id, ['Assignee'])
self.assertRoles(product, self.user_id, ['Owner']) self.assertRoles(product, self.user_id, ['Owner'])
class TestSecurePaymentTool(TestSlapOSGroupRoleSecurityMixin): class TestSecurePaymentTool(TestSlapOSGroupRoleSecurityMixin):
......
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
<key> <string>method_id</string> </key> <key> <string>method_id</string> </key>
<value> <value>
<list> <list>
<string>_setReference</string> <string>_setUserId.*</string>
<string>_setSourceAdministration.*</string> <string>_setSourceAdministration.*</string>
<string>_setAllocationScope.*</string> <string>_setAllocationScope.*</string>
<string>_setDestinationSection.*</string> <string>_setDestinationSection.*</string>
...@@ -75,6 +75,12 @@ ...@@ -75,6 +75,12 @@
</list> </list>
</value> </value>
</item> </item>
<item>
<key> <string>portal_type_group_filter</string> </key>
<value>
<none/>
</value>
</item>
<item> <item>
<key> <string>script_name</string> </key> <key> <string>script_name</string> </key>
<value> <value>
......
...@@ -2,11 +2,9 @@ ...@@ -2,11 +2,9 @@
# Copyright (c) 2002-2013 Nexedi SA and Contributors. All Rights Reserved. # Copyright (c) 2002-2013 Nexedi SA and Contributors. All Rights Reserved.
import transaction import transaction
from Products.SlapOS.tests.testSlapOSMixin import \ from Products.SlapOS.tests.testSlapOSMixin import \
testSlapOSMixin testSlapOSMixin, changeSkin, simulate
from zExceptions import Unauthorized from zExceptions import Unauthorized
from Products.ERP5Type.tests.utils import createZODBPythonScript
from unittest import skip from unittest import skip
from functools import wraps
from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPRequest import HTTPRequest
from ZPublisher.HTTPResponse import HTTPResponse from ZPublisher.HTTPResponse import HTTPResponse
...@@ -14,40 +12,6 @@ from ZPublisher.HTTPResponse import HTTPResponse ...@@ -14,40 +12,6 @@ from ZPublisher.HTTPResponse import HTTPResponse
import json import json
import StringIO import StringIO
def changeSkin(skin_name):
def decorator(func):
def wrapped(self, *args, **kwargs):
default_skin = self.portal.portal_skins.default_skin
self.portal.portal_skins.changeSkin(skin_name)
self.app.REQUEST.set('portal_skin', skin_name)
try:
v = func(self, *args, **kwargs)
finally:
self.portal.portal_skins.changeSkin(default_skin)
self.app.REQUEST.set('portal_skin', default_skin)
return v
return wrapped
return decorator
def simulate(script_id, params_string, code_string):
def upperWrap(f):
@wraps(f)
def decorated(self, *args, **kw):
if script_id in self.portal.portal_skins.custom.objectIds():
raise ValueError('Precondition failed: %s exists in custom' % script_id)
createZODBPythonScript(self.portal.portal_skins.custom,
script_id, params_string, code_string)
transaction.commit()
try:
result = f(self, *args, **kw)
finally:
if script_id in self.portal.portal_skins.custom.objectIds():
self.portal.portal_skins.custom.manage_delObjects(script_id)
transaction.commit()
return result
return decorated
return upperWrap
def do_fake_request(request_method, headers={}): def do_fake_request(request_method, headers={}):
__version__ = "0.1" __version__ = "0.1"
env={} env={}
...@@ -177,18 +141,7 @@ class TestSlapOSHypermediaMixin(testSlapOSMixin): ...@@ -177,18 +141,7 @@ class TestSlapOSHypermediaMixin(testSlapOSMixin):
transaction.abort() transaction.abort()
def _makePerson(self): def _makePerson(self):
new_id = self.generateNewId() person_user = self.makePerson()
person_user = self.portal.person_module.template_member.\
Base_createCloneDocument(batch_mode=1)
person_user.edit(
title="live_test_%s" % new_id,
reference="live_test_%s" % new_id,
default_email_text="live_test_%s@example.org" % new_id,
)
person_user.validate()
for assignment in person_user.contentValues(portal_type="Assignment"):
assignment.open()
self.tic() self.tic()
self.changeSkin('Hal') self.changeSkin('Hal')
return person_user return person_user
...@@ -368,7 +321,7 @@ class TestSlapOSBase_getHateoasMaster(TestSlapOSHypermediaMixin): ...@@ -368,7 +321,7 @@ class TestSlapOSBase_getHateoasMaster(TestSlapOSHypermediaMixin):
@changeSkin('Hal') @changeSkin('Hal')
def test_getHateoasMaster_instance_result(self): def test_getHateoasMaster_instance_result(self):
self._makeTree() self._makeTree()
self.login(self.software_instance.getReference()) self.login(self.software_instance.getUserId())
self.changeSkin('Hal') self.changeSkin('Hal')
fake_request = do_fake_request("GET") fake_request = do_fake_request("GET")
result = self.portal.Base_getHateoasMaster(REQUEST=fake_request) result = self.portal.Base_getHateoasMaster(REQUEST=fake_request)
...@@ -716,6 +669,7 @@ class TestSlapOSInstance_getHateoasNews(TestSlapOSHypermediaMixin): ...@@ -716,6 +669,7 @@ class TestSlapOSInstance_getHateoasNews(TestSlapOSHypermediaMixin):
sla_xml=self.generateSafeXml(), sla_xml=self.generateSafeXml(),
connection_xml=self.generateSafeXml(), connection_xml=self.generateSafeXml(),
) )
self._addERP5Login(instance)
self.tic() self.tic()
return instance return instance
...@@ -803,6 +757,7 @@ class TestSlapOSInstance_getHateoasRelatedHostingSubscription(TestSlapOSHypermed ...@@ -803,6 +757,7 @@ class TestSlapOSInstance_getHateoasRelatedHostingSubscription(TestSlapOSHypermed
sla_xml=self.generateSafeXml(), sla_xml=self.generateSafeXml(),
connection_xml=self.generateSafeXml(), connection_xml=self.generateSafeXml(),
) )
self._addERP5Login(instance)
self.tic() self.tic()
return instance return instance
...@@ -893,6 +848,7 @@ class TestSlapOSInstance_getHateoasInformation(TestSlapOSHypermediaMixin): ...@@ -893,6 +848,7 @@ class TestSlapOSInstance_getHateoasInformation(TestSlapOSHypermediaMixin):
sla_xml=self.generateSafeXml(), sla_xml=self.generateSafeXml(),
connection_xml=self.generateSafeXml(), connection_xml=self.generateSafeXml(),
) )
self._addERP5Login(instance)
self.tic() self.tic()
return instance return instance
......
...@@ -27,28 +27,9 @@ ...@@ -27,28 +27,9 @@
############################################################################## ##############################################################################
import transaction import transaction
from functools import wraps from Products.SlapOS.tests.testSlapOSMixin import testSlapOSMixin, simulate
from Products.SlapOS.tests.testSlapOSMixin import testSlapOSMixin
from Products.ERP5Type.tests.utils import createZODBPythonScript
from DateTime import DateTime from DateTime import DateTime
def simulate(script_id, params_string, code_string):
def upperWrap(f):
@wraps(f)
def decorated(self, *args, **kw):
if script_id in self.portal.portal_skins.custom.objectIds():
raise ValueError('Precondition failed: %s exists in custom' % script_id)
createZODBPythonScript(self.portal.portal_skins.custom,
script_id, params_string, code_string)
try:
result = f(self, *args, **kw)
finally:
if script_id in self.portal.portal_skins.custom.objectIds():
self.portal.portal_skins.custom.manage_delObjects(script_id)
transaction.commit()
return result
return decorated
return upperWrap
class TestSlapOSPDMSkins(testSlapOSMixin): class TestSlapOSPDMSkins(testSlapOSMixin):
def afterSetUp(self): def afterSetUp(self):
...@@ -77,20 +58,7 @@ class TestSlapOSPDMSkins(testSlapOSMixin): ...@@ -77,20 +58,7 @@ class TestSlapOSPDMSkins(testSlapOSMixin):
def _makePerson(self): def _makePerson(self):
# Clone person document person_user = self.makePerson(new_id=self.new_id)
person_user = self.portal.person_module.template_member.\
Base_createCloneDocument(batch_mode=1)
person_user.edit(
title="live_test_%s" % self.new_id,
reference="live_test_%s" % self.new_id,
default_email_text="live_test_%s@example.org" % self.new_id,
)
person_user.validate()
for assignment in person_user.contentValues(portal_type="Assignment"):
assignment.open()
transaction.commit()
return person_user return person_user
def _makeComputer(self): def _makeComputer(self):
......
...@@ -3,7 +3,7 @@ from AccessControl.SecurityManagement import getSecurityManager, \ ...@@ -3,7 +3,7 @@ from AccessControl.SecurityManagement import getSecurityManager, \
setSecurityManager, newSecurityManager setSecurityManager, newSecurityManager
@UnrestrictedMethod @UnrestrictedMethod
def getComputerReference(item): def getComputerReferenceAndUserId(item):
portal_type = item.getPortalType() portal_type = item.getPortalType()
computer = None computer = None
...@@ -17,20 +17,28 @@ def getComputerReference(item): ...@@ -17,20 +17,28 @@ def getComputerReference(item):
computer = partition.getParentValue() computer = partition.getParentValue()
if computer is not None and computer.getValidationState() == 'validated': if computer is not None and computer.getValidationState() == 'validated':
return computer.getReference() return computer.getReference(), computer.getUserId()
return None return None, None
def Item_activateFillComputerInformationCache(state_change): def Item_activateFillComputerInformationCache(state_change):
item = state_change['object'] item = state_change['object']
portal = item.getPortalObject() portal = item.getPortalObject()
computer_reference = getComputerReference(item) computer_reference, user_id = getComputerReferenceAndUserId(item)
if computer_reference is None: if computer_reference is None:
return None return None
if user_id is None:
return None
user = portal.acl_users.getUserById(user_id)
if user is None:
raise ValueError("User %s not found" % user_id)
sm = getSecurityManager() sm = getSecurityManager()
try: try:
newSecurityManager(None, newSecurityManager(None, user)
portal.acl_users.getUserById(computer_reference))
portal.portal_slap._activateFillComputerInformationCache( portal.portal_slap._activateFillComputerInformationCache(
computer_reference, computer_reference) computer_reference, computer_reference)
finally: finally:
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Property Sheet" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_count</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_mt_index</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>_tree</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SlapOSHateoasSystemPreference</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Property Sheet</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Length" module="BTrees.Length"/>
</pickle>
<pickle> <int>0</int> </pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Standard Property" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_local_properties</string> </key>
<value>
<tuple>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>mode</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>string</string> </value>
</item>
</dictionary>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>elementary_type/string</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Stores token server URL</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>preferred_hateoas_url_property</string> </value>
</item>
<item>
<key> <string>mode</string> </key>
<value> <string>w</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Standard Property</string> </value>
</item>
<item>
<key> <string>preference</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>property_default</string> </key>
<value> <string>python: \'\'</string> </value>
</item>
<item>
<key> <string>read_permission</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>write_permission</string> </key>
<value> <string>Manage properties</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -48,22 +48,22 @@ ...@@ -48,22 +48,22 @@
<tuple> <tuple>
<string>W: 29, 10: Use of eval (eval-used)</string> <string>W: 29, 10: Use of eval (eval-used)</string>
<string>W: 38, 2: Arguments number differs from overridden \'afterSetUp\' method (arguments-differ)</string> <string>W: 38, 2: Arguments number differs from overridden \'afterSetUp\' method (arguments-differ)</string>
<string>W:517, 13: Use of eval (eval-used)</string> <string>W:519, 13: Use of eval (eval-used)</string>
<string>W:568, 13: Use of eval (eval-used)</string> <string>W:570, 13: Use of eval (eval-used)</string>
<string>W:793, 13: Use of eval (eval-used)</string> <string>W:795, 13: Use of eval (eval-used)</string>
<string>W:1401, 13: Use of eval (eval-used)</string> <string>W:1403, 13: Use of eval (eval-used)</string>
<string>W:1514, 13: Use of eval (eval-used)</string> <string>W:1516, 13: Use of eval (eval-used)</string>
<string>W:1568, 13: Use of eval (eval-used)</string> <string>W:1570, 13: Use of eval (eval-used)</string>
<string>W:1608, 13: Use of eval (eval-used)</string> <string>W:1610, 13: Use of eval (eval-used)</string>
<string>W:2132, 2: Arguments number differs from overridden \'afterSetUp\' method (arguments-differ)</string> <string>W:2134, 2: Arguments number differs from overridden \'afterSetUp\' method (arguments-differ)</string>
<string>W:2229, 13: Use of eval (eval-used)</string> <string>W:2231, 13: Use of eval (eval-used)</string>
<string>W:2614, 13: Use of eval (eval-used)</string> <string>W:2616, 13: Use of eval (eval-used)</string>
<string>W:2668, 13: Use of eval (eval-used)</string> <string>W:2670, 13: Use of eval (eval-used)</string>
<string>W:2695, 13: Use of eval (eval-used)</string> <string>W:2697, 13: Use of eval (eval-used)</string>
<string>W:2850, 13: Use of eval (eval-used)</string> <string>W:2852, 13: Use of eval (eval-used)</string>
<string>W:2878, 13: Use of eval (eval-used)</string> <string>W:2880, 13: Use of eval (eval-used)</string>
<string>W:2927, 13: Use of eval (eval-used)</string> <string>W:2929, 13: Use of eval (eval-used)</string>
<string>W:2974, 13: Use of eval (eval-used)</string> <string>W:2976, 13: Use of eval (eval-used)</string>
</tuple> </tuple>
</value> </value>
</item> </item>
......
SlapOSHateoasSystemPreference
\ No newline at end of file
from Products.CMFActivity.ActiveResult import ActiveResult
portal = context.getPortalObject()
def mergePASDictDifference(portal, d, fixit):
plugins = portal.acl_users.plugins
error_list = []
plugin_type_info = plugins.listPluginTypeInfo()
for plugin, active_list in d.iteritems():
plugin_info = [q for q in plugin_type_info if q['id'] == plugin][0]
found_list = plugins.listPlugins(plugin_info['interface'])
meta_type_list = [q[1].meta_type for q in found_list]
for expected in active_list:
if expected not in meta_type_list:
error = 'Plugin %s missing %s.' % (plugin, expected)
if fixit:
existing = [q for q in portal.acl_users.objectValues() if q.meta_type == expected]
if len(existing) == 0:
error_list.append('%s not found' % expected)
else:
plugins.activatePlugin(plugin_info['interface'], existing[0].getId())
error += ' Fixed.'
error_list.append(error)
return error_list
pas_difference = mergePASDictDifference(portal, promise_dict, fixit)
if len(pas_difference) != 0:
if fixit:
severity = 0
else:
severity = 1
summary = "PAS not configured as expected"
if fixit:
summary += ' (fixed)'
detail = "Difference:\n%s" % ('\n'.join(pas_difference), )
else:
severity = 0
summary = "Nothing to do."
detail = ""
active_result = ActiveResult()
active_result.edit(
summary=summary,
severity=severity,
detail=detail)
context.newActiveProcess().postResult(active_result)
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