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 @@
import transaction
from Products.SlapOS.tests.testSlapOSMixin import \
testSlapOSMixin, withAbort
testSlapOSMixin, withAbort, simulate
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):
......
......@@ -13,10 +13,10 @@ class Person(ERP5Person):
# in ERP5 user has no SetOwnPassword permission on Person document
# referring himself, so implement "security" by checking that currently
# logged in user is trying to get/revoke his own certificate
reference = self.getReference()
if not reference:
user_id = self.getUserId()
if not user_id:
raise
if getSecurityManager().getUser().getId() != reference:
if getSecurityManager().getUser().getId() != user_id:
raise
def _getCertificate(self):
......
......@@ -6,10 +6,22 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>Person</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>document.erp5.Person</string> </value>
......@@ -43,13 +55,28 @@
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......@@ -62,7 +89,7 @@
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -71,7 +98,7 @@
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
......
......@@ -43,10 +43,12 @@ def SoftwareInstance_bangAsSelf(self, relative_url=None, reference=None,
if (software_instance.getPortalType() == "Slave Instance") and \
(software_instance.getReference() == reference):
# 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(
reference))
user_id))
try:
software_instance.bang(bang_tree=True, comment=comment)
finally:
......
......@@ -40,7 +40,7 @@ def getComputerSecurityCategory(self, base_category_list, user_name,
computer_list = self.portal_catalog.unrestrictedSearchResults(
portal_type='Computer',
reference=user_name,
user_id=user_name,
validation_state="validated",
limit=2,
)
......@@ -51,8 +51,8 @@ def getComputerSecurityCategory(self, base_category_list, user_name,
category_list.append(
{base_category: ['role/computer']})
elif len(computer_list) > 1:
raise ConsistencyError, "Error: There is more than one Computer " \
"with reference '%s'" % user_name
raise ConsistencyError("Error: There is more than one Computer " \
"with reference '%s'" % user_name)
return category_list
......@@ -66,7 +66,7 @@ def getSoftwareInstanceSecurityCategory(self, base_category_list, user_name,
software_instance_list = self.portal_catalog.unrestrictedSearchResults(
portal_type='Software Instance',
reference=user_name,
user_id=user_name,
validation_state="validated",
limit=2,
)
......@@ -83,8 +83,8 @@ def getSoftwareInstanceSecurityCategory(self, base_category_list, user_name,
category_dict.setdefault(base_category, []).append(hosting_item.getRelativeUrl())
category_list.append(category_dict)
elif len(software_instance_list) > 1:
raise ConsistencyError, "Error: There is more than one Software Instance " \
"with reference %r" % user_name
raise ConsistencyError("Error: There is more than one Software Instance " \
"with reference %r" % user_name)
return category_list
......@@ -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
# change even if this method is invoked by random users.
acl_users = shadow_document.getPortalObject().acl_users
reference = shadow_document.getReference()
if reference is None:
user_id = shadow_document.getUserId()
if user_id is None:
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:
raise Unauthorized('%s is not loggable user' % relative_url)
sm = getSecurityManager()
shadow_user = acl_users.getUserById('SHADOW-' + reference)
shadow_user = acl_users.getUserById('SHADOW-' + user_id)
if shadow_user is None:
raise Unauthorized('Shadow of %s is not loggable user' % relative_url)
newSecurityManager(None, shadow_user)
......
......@@ -6,10 +6,22 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>SlapOSSecurity</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>extension.erp5.SlapOSSecurity</string> </value>
......@@ -35,9 +47,7 @@
<value>
<tuple>
<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: 86, 4: Use raise ErrorClass(args) instead of raise ErrorClass, args. (old-raise-syntax)</string>
</tuple>
</value>
</item>
......@@ -48,13 +58,28 @@
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......@@ -67,7 +92,7 @@
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -76,7 +101,7 @@
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
......
<allowed_content_type_list>
<portal_type id="Computer">
<item>ERP5 Login</item>
</portal_type>
<portal_type id="Hosting Subscription Module">
<item>Hosting Subscription</item>
</portal_type>
<portal_type id="Software Installation Module">
<item>Software Installation</item>
</portal_type>
<portal_type id="Software Instance">
<item>ERP5 Login</item>
</portal_type>
<portal_type id="Software Instance Module">
<item>Slave Instance</item>
<item>Software Instance</item>
......
......@@ -3,6 +3,7 @@
<item>SlaposAssignmentConstraint</item>
</portal_type>
<portal_type id="Computer">
<item>ERP5User</item>
<item>SlaposCapacity</item>
<item>SlaposComputerConstraint</item>
<item>Url</item>
......@@ -42,6 +43,7 @@
<item>VariationRange</item>
</portal_type>
<portal_type id="Software Instance">
<item>ERP5User</item>
<item>HostingSubscription</item>
<item>Reference</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 @@
</item>
<item>
<key> <string>init_script</string> </key>
<value>
<none/>
</value>
<value> <string>SoftwareInstance_init</string> </value>
</item>
<item>
<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 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>promise_dict, tag, fixit=False, **kw</string> </value>
<value> <string>**kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Alarm_checkPromiseSlapOSPASBase</string> </value>
<value> <string>Computer_init</string> </value>
</item>
</dictionary>
</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 = {
'SlapOS Machine Authentication Plugin',
'ERP5 Access Token Extraction Plugin',
],
'IAuthenticationPlugin': [
'SlapOS Machine Authentication Plugin',
'SlapOS Shadow Authentication Plugin',
],
'IGroupsPlugin': [
'SlapOS Machine Authentication Plugin',
'SlapOS Shadow Authentication Plugin',
],
'IUserEnumerationPlugin': [
'SlapOS Machine Authentication Plugin',
'SlapOS Shadow Authentication Plugin',
]
}
......
# Copyright (c) 2002-2012 Nexedi SA and Contributors. All Rights Reserved.
import transaction
from Products.SlapOS.tests.testSlapOSMixin import \
testSlapOSMixin
testSlapOSMixin, simulate
from Products.ERP5Type.tests.utils import createZODBPythonScript
from unittest import skip
import json
......@@ -10,25 +10,7 @@ from zExceptions import Unauthorized
from DateTime import DateTime
from Products.ERP5Type.DateUtils import addToDate
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):
......
......@@ -30,96 +30,110 @@ import unittest
import random
from AccessControl import getSecurityManager
from Products.SlapOS.tests.testSlapOSMixin import testSlapOSMixin
from Products.PluggableAuthService.interfaces.plugins import\
IAuthenticationPlugin
class TestSlapOSSecurityMixin(testSlapOSMixin):
def _generateRandomUniqueReference(self, portal_type):
reference = None
while reference is None:
random_reference = "test_%s" % random.random()
def _generateRandomUniqueUserId(self, portal_type, search_key="user_id"):
user_id = None
while user_id is None:
random_user_id = "test_%s_%s" % (
portal_type.replace(" ", "_").lower(), random.random())
result_list = self.portal.portal_catalog(
portal_type=portal_type,
reference=random_reference,
**{search_key: random_user_id}
)
if not len(result_list):
reference = random_reference
return reference
user_id = random_user_id
return user_id
def _generateRandomUniqueReference(self, portal_type):
return self._generateRandomUniqueUserId(portal_type, "reference")
def _assertUserExists(self, login, password):
def _assertUserExists(self, user_id, login, password):
"""Checks that a user with login and password exists and can log in to the
system.
"""
from Products.PluggableAuthService.interfaces.plugins import\
IAuthenticationPlugin
uf = self.getUserFolder()
self.assertNotEquals(uf.getUserById(login, None), None)
for plugin_name, plugin in uf._getOb('plugins').listPlugins(
self.assertNotEquals(uf.getUserById(user_id, None), None)
for _, plugin in uf._getOb('plugins').listPlugins(
IAuthenticationPlugin ):
if plugin.authenticateCredentials(
{'login':login,
'password':password,
'machine_login': login}) is not None:
{'login_portal_type': 'ERP5 Login',
'external_login': login}) is not None:
break
else:
self.fail("No plugin could authenticate '%s' with password '%s'" %
(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
log in to the system.
"""
from Products.PluggableAuthService.interfaces.plugins import\
IAuthenticationPlugin
uf = self.getUserFolder()
for plugin_name, plugin in uf._getOb('plugins').listPlugins(
IAuthenticationPlugin ):
if plugin.authenticateCredentials(
{'login':login,
'password':password,
'machine_login': login}) is not None:
{'login_portal_type': 'ERP5 Login',
'external_login': login}) is not None:
self.fail(
"Plugin %s should not have authenticated '%s' with password '%s'" %
(plugin_name, login, password))
class TestSlapOSComputerSecurity(TestSlapOSSecurityMixin):
def test_active(self):
user_id = self._generateRandomUniqueUserId('Computer')
reference = self._generateRandomUniqueReference('Computer')
computer = self.portal.computer_module.newContent(portal_type='Computer',
reference=reference)
computer = self.portal.computer_module.newContent(
portal_type='Computer', reference=reference)
computer.setUserId(user_id)
computer.validate()
computer.newContent(portal_type='ERP5 Login',
reference=reference).validate()
computer.recursiveImmediateReindexObject()
self._assertUserExists(reference, None)
self._assertUserExists(user_id, reference, None)
self.login(reference)
self.login(user_id)
user = getSecurityManager().getUser()
self.assertTrue('Authenticated' in user.getRoles())
self.assertSameSet(['R-COMPUTER'],
user.getGroups())
def test_inactive(self):
user_id = self._generateRandomUniqueUserId('Computer')
reference = self._generateRandomUniqueReference('Computer')
computer = self.portal.computer_module.newContent(portal_type='Computer',
computer = self.portal.computer_module.newContent(
portal_type='Computer', reference=reference)
computer.setUserId(user_id)
computer.newContent(portal_type='ERP5 Login',
reference=reference)
computer.recursiveImmediateReindexObject()
self._assertUserDoesNotExists(reference, None)
self._assertUserDoesNotExists(user_id, reference, None)
class TestSlapOSSoftwareInstanceSecurity(TestSlapOSSecurityMixin):
portal_type = 'Software Instance'
def test_active(self):
user_id = self._generateRandomUniqueUserId(self.portal_type)
reference = self._generateRandomUniqueReference(self.portal_type)
instance = self.portal.getDefaultModule(portal_type=self.portal_type)\
.newContent(portal_type=self.portal_type, reference=reference)
instance.setUserId(user_id)
instance.validate()
instance.newContent(portal_type='ERP5 Login',
reference=reference).validate()
instance.recursiveImmediateReindexObject()
self._assertUserExists(reference, None)
self._assertUserExists(user_id, reference, None)
# instance w/o subscription is loggable and it has some roles
self.login(reference)
self.login(user_id)
user = getSecurityManager().getUser()
self.assertTrue('Authenticated' in user.getRoles())
self.assertSameSet(['R-INSTANCE'],
......@@ -129,7 +143,8 @@ class TestSlapOSSoftwareInstanceSecurity(TestSlapOSSecurityMixin):
subscription_reference = self._generateRandomUniqueReference(
'Hosting Suscription')
subscription = self.portal.hosting_subscription_module.newContent(
portal_type='Hosting Subscription', reference=subscription_reference)
portal_type='Hosting Subscription',
reference=subscription_reference)
subscription.validate()
instance.setSpecialise(subscription.getRelativeUrl())
subscription.recursiveImmediateReindexObject()
......@@ -137,33 +152,42 @@ class TestSlapOSSoftwareInstanceSecurity(TestSlapOSSecurityMixin):
# clear cache in order to reset calculation
self.portal.portal_caches.clearAllCache()
self.login(reference)
self.login(user_id)
user = getSecurityManager().getUser()
self.assertTrue('Authenticated' in user.getRoles())
self.assertSameSet(['R-INSTANCE', subscription_reference],
user.getGroups())
def test_inactive(self):
user_id = self._generateRandomUniqueUserId(self.portal_type)
reference = self._generateRandomUniqueReference(self.portal_type)
instance = self.portal.getDefaultModule(portal_type=self.portal_type)\
.newContent(portal_type=self.portal_type, reference=reference)
instance.setUserId(user_id)
instance.recursiveImmediateReindexObject()
self._assertUserDoesNotExists(reference, None)
self._assertUserDoesNotExists(user_id, reference, None)
class TestSlapOSPersonSecurity(TestSlapOSSecurityMixin):
def test_active(self):
password = str(random.random())
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)
person.setUserId(user_id)
person.newContent(portal_type='Assignment').open()
person.newContent(portal_type='ERP5 Login',
reference=reference, password=password).validate()
self.commit()
person.recursiveImmediateReindexObject()
self._assertUserExists(reference, password)
self._assertUserExists(user_id, reference, password)
self.login(person.getUserId())
user = getSecurityManager().getUser()
......@@ -177,7 +201,6 @@ class TestSlapOSPersonSecurity(TestSlapOSSecurityMixin):
self.commit()
person.recursiveImmediateReindexObject()
self.tic()
self.portal.portal_caches.clearAllCache()
self.login(person.getUserId())
......@@ -199,13 +222,15 @@ class TestSlapOSPersonSecurity(TestSlapOSSecurityMixin):
def test_inactive(self):
password = str(random.random())
reference = self._generateRandomUniqueReference('Person')
user_id = self._generateRandomUniqueReference('Person')
person = self.portal.person_module.newContent(portal_type='Person',
reference=reference, password=password)
self.commit()
person.recursiveImmediateReindexObject()
self._assertUserDoesNotExists(reference, password)
self._assertUserDoesNotExists(user_id, reference, password)
def test_suite():
suite = unittest.TestSuite()
......
......@@ -6,10 +6,22 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testSlapOSCloudSecurityGroup</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test.erp5.testSlapOSCloudSecurityGroup</string> </value>
......@@ -33,9 +45,7 @@
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple>
<string>W: 56, 8: Unused variable \'plugin_name\' (unused-variable)</string>
</tuple>
<tuple/>
</value>
</item>
<item>
......@@ -45,13 +55,28 @@
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......@@ -64,7 +89,7 @@
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -73,7 +98,7 @@
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
......
......@@ -28,7 +28,6 @@
import unittest
import random
import transaction
from AccessControl import getSecurityManager
from erp5.component.test.testSlapOSCloudSecurityGroup import TestSlapOSSecurityMixin
......@@ -36,96 +35,125 @@ class TestSlapOSShadowPerson(TestSlapOSSecurityMixin):
def test_active(self):
password = str(random.random())
reference = self._generateRandomUniqueReference('Person')
shadow_reference = 'SHADOW-%s' % reference
person = self.portal.person_module.newContent(portal_type='Person',
reference=reference, password=password)
user_id = self._generateRandomUniqueUserId('Person')
shadow_user_id = 'SHADOW-%s' % user_id
person = self.portal.person_module.newContent(
portal_type='Person')
person.setUserId(user_id)
person.newContent(portal_type='Assignment').open()
transaction.commit()
person.newContent(portal_type='ERP5 Login',
reference=reference, password=password).validate()
self.commit()
person.recursiveImmediateReindexObject()
self._assertUserExists(reference, password)
self._assertUserExists(shadow_reference, None)
self._assertUserExists(user_id, reference, password)
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()
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())
def test_inactive(self):
password = str(random.random())
reference = self._generateRandomUniqueReference('Person')
shadow_reference = 'SHADOW-%s' % reference
person = self.portal.person_module.newContent(portal_type='Person',
reference=reference, password=password)
user_id = self._generateRandomUniqueUserId('Person')
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()
self._assertUserDoesNotExists(reference, password)
self._assertUserDoesNotExists(shadow_reference, None)
self._assertUserDoesNotExists(user_id, reference, password)
self._assertUserDoesNotExists(shadow_user_id, reference, None)
class TestSlapOSShadowComputer(TestSlapOSSecurityMixin):
def test_active(self):
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',
reference=reference)
computer.setUserId(user_id)
computer.newContent(portal_type='ERP5 Login',
reference=reference).validate()
computer.validate()
computer.recursiveImmediateReindexObject()
self._assertUserExists(reference, None)
self._assertUserExists(shadow_reference, None)
self._assertUserExists(user_id, reference, None)
self._assertUserExists(shadow_user_id, reference, None)
self.login(shadow_reference)
self.login(shadow_user_id)
user = getSecurityManager().getUser()
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())
def test_inactive(self):
reference = self._generateRandomUniqueReference('Computer')
user_id = self._generateRandomUniqueUserId('Computer')
shadow_reference = 'SHADOW-%s' % reference
computer = self.portal.computer_module.newContent(portal_type='Computer',
reference=reference)
computer.setUserId(user_id)
computer.recursiveImmediateReindexObject()
self._assertUserDoesNotExists(reference, None)
self._assertUserDoesNotExists(shadow_reference, None)
self._assertUserDoesNotExists(user_id, reference, None)
self._assertUserDoesNotExists(user_id, shadow_reference, None)
class TestSlapOSShadowSoftwareInstance(TestSlapOSSecurityMixin):
portal_type = 'Software Instance'
def test_active(self):
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)\
.newContent(portal_type=self.portal_type, reference=reference)
instance.setUserId(user_id)
instance.newContent(portal_type='ERP5 Login',
reference=reference).validate()
instance.validate()
instance.recursiveImmediateReindexObject()
self._assertUserExists(reference, None)
self._assertUserExists(shadow_reference, None)
self._assertUserExists(user_id, reference, None)
self._assertUserExists(shadow_user_id, reference, None)
self.login(shadow_reference)
self.login(shadow_user_id)
user = getSecurityManager().getUser()
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())
def test_inactive(self):
reference = self._generateRandomUniqueReference(self.portal_type)
user_id = self._generateRandomUniqueUserId(self.portal_type)
shadow_reference = 'SHADOW-%s' % reference
instance = self.portal.getDefaultModule(portal_type=self.portal_type)\
.newContent(portal_type=self.portal_type, reference=reference)
instance.setUserId(user_id)
instance.recursiveImmediateReindexObject()
self._assertUserDoesNotExists(reference, None)
self._assertUserDoesNotExists(shadow_reference, None)
self._assertUserDoesNotExists(user_id, reference, None)
self._assertUserDoesNotExists(user_id, shadow_reference, None)
def test_suite():
suite = unittest.TestSuite()
......
......@@ -6,10 +6,22 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testSlapOSCloudShadow</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test.erp5.testSlapOSCloudShadow</string> </value>
......@@ -27,9 +39,7 @@
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple>
<string>F: 33, 0: Unable to import \'testSlapOSCloudSecurityGroup\' (import-error)</string>
</tuple>
<tuple/>
</value>
</item>
<item>
......@@ -45,13 +55,28 @@
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......@@ -64,7 +89,7 @@
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -73,7 +98,7 @@
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
......
......@@ -10,18 +10,23 @@ from AccessControl.SecurityManagement import getSecurityManager, \
class TestSlapOSCoreComputerPartitionSlapInterfaceWorkflow(testSlapOSMixin):
def afterSetUp(self):
self.login()
super(TestSlapOSCoreComputerPartitionSlapInterfaceWorkflow, self).afterSetUp()
# Clone computer document
self.computer = self.portal.computer_module.template_computer\
.Base_createCloneDocument(batch_mode=1)
new_id = self.generateNewId()
self.computer.edit(
title="computer %s" % (new_id, ),
reference="TESTCOMP-%s" % (new_id, ),
title="computer %s" % (self.new_id, ),
reference="TESTCOMP-%s" % (self.new_id, ),
allocation_scope='open/personal',
capacity_scope='open',
)
self.computer.validate()
login = self.computer.newContent(
portal_type="ERP5 Login",
reference=self.computer.getReference()
)
login.validate()
# install an software release
self.software_installation = self.portal.software_installation_module\
......@@ -32,9 +37,9 @@ class TestSlapOSCoreComputerPartitionSlapInterfaceWorkflow(testSlapOSMixin):
self.software_installation.requestStart()
self.tic()
self.login(self.computer.getUserId())
def test_markFree(self):
self.login(self.computer.getReference())
partition = self.computer.newContent(portal_type='Computer Partition',
reference='PART-%s' % self.generateNewId())
partition.validate()
......@@ -44,7 +49,6 @@ class TestSlapOSCoreComputerPartitionSlapInterfaceWorkflow(testSlapOSMixin):
parent_uid=self.computer.getUid(), free_for_request=1)[0][0])
def test_markFree_markBusy(self):
self.login(self.computer.getReference())
partition = self.computer.newContent(portal_type='Computer Partition',
reference='PART-%s' % self.generateNewId())
partition.validate()
......@@ -58,7 +62,6 @@ class TestSlapOSCoreComputerPartitionSlapInterfaceWorkflow(testSlapOSMixin):
parent_uid=self.computer.getUid(), free_for_request=1)[0][0])
def test_markFree_markBusy_markFree(self):
self.login(self.computer.getReference())
partition = self.computer.newContent(portal_type='Computer Partition',
reference='PART-%s' % self.generateNewId())
partition.validate()
......@@ -76,7 +79,6 @@ class TestSlapOSCoreComputerPartitionSlapInterfaceWorkflow(testSlapOSMixin):
parent_uid=self.computer.getUid(), free_for_request=1)[0][0])
def test_markInactive(self):
self.login(self.computer.getReference())
partition = self.computer.newContent(portal_type='Computer Partition',
reference='PART-%s' % self.generateNewId())
partition.validate()
......@@ -86,7 +88,6 @@ class TestSlapOSCoreComputerPartitionSlapInterfaceWorkflow(testSlapOSMixin):
parent_uid=self.computer.getUid(), free_for_request=1)[0][0])
def test_markInactive_markFree(self):
self.login(self.computer.getReference())
partition = self.computer.newContent(portal_type='Computer Partition',
reference='PART-%s' % self.generateNewId())
partition.validate()
......@@ -113,28 +114,13 @@ class TestSlapOSCoreComputerSlapInterfaceWorkflow(testSlapOSMixin):
self.computer.validate()
self.tic()
def _makePerson(self):
new_id = self.generateNewId()
self.person_user = self.portal.person_module.template_member.\
Base_createCloneDocument(batch_mode=1)
self.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,
)
self.person_user.validate()
for assignment in self.person_user.contentValues(portal_type="Assignment"):
assignment.open()
self.tic()
def beforeTearDown(self):
super(TestSlapOSCoreComputerSlapInterfaceWorkflow, self).beforeTearDown()
self.portal.REQUEST['computer_key'] = None
self.portal.REQUEST['computer_certificate'] = None
def test_generateCertificate(self):
self.login(self.computer.getReference())
self.login(self.computer.getUserId())
self.computer.generateCertificate()
computer_key = self.portal.REQUEST.get('computer_key')
computer_certificate = self.portal.REQUEST.get('computer_certificate')
......@@ -146,7 +132,7 @@ class TestSlapOSCoreComputerSlapInterfaceWorkflow(testSlapOSMixin):
self.assertTrue(self.computer.getReference() in computer_certificate.decode('string_escape'))
def test_generateCertificate_twice(self):
self.login(self.computer.getReference())
self.login(self.computer.getUserId())
self.computer.generateCertificate()
computer_key = self.portal.REQUEST.get('computer_key')
computer_certificate = self.portal.REQUEST.get('computer_certificate')
......@@ -162,12 +148,11 @@ class TestSlapOSCoreComputerSlapInterfaceWorkflow(testSlapOSMixin):
self.assertEqual(None, self.portal.REQUEST.get('computer_certificate'))
def test_approveComputerRegistration(self):
self._makePerson()
self.person_user = self.makePerson()
self.login(self.person_user.getUserId())
new_id = self.generateNewId()
computer = self.portal.computer_module.newContent(portal_type='Computer',
title="Computer %s for %s" % (new_id, self.person_user.getReference()),
reference="TESTCOMP-%s" % new_id)
title="Computer %s for %s" % (self.new_id, self.person_user.getReference()),
reference="TESTCOMP-%s" % self.new_id)
computer.requestComputerRegistration()
computer.approveComputerRegistration()
self.assertEqual('open/personal', computer.getAllocationScope())
......@@ -187,7 +172,7 @@ class TestSlapOSCoreComputerSlapInterfaceWorkflow(testSlapOSMixin):
def test_reportComputerBang(self):
self._makeComplexComputer()
self.login(self.computer.getReference())
self.login(self.computer.getUserId())
comment = 'Bang from computer'
started_instance = self.computer.partition1.getAggregateRelatedValue(
portal_type='Software Instance')
......@@ -230,7 +215,7 @@ class TestSlapOSCoreComputerSlapInterfaceWorkflow(testSlapOSMixin):
self._countInstanceBang(destroyed_instance2, comment))
def test_requestSoftwareRelease_software_release_url_required(self):
self._makePerson()
self.person_user = self.makePerson()
self.computer.edit(source_administration=self.person_user.getRelativeUrl())
self.tic()
self.login(self.person_user.getUserId())
......@@ -239,7 +224,7 @@ class TestSlapOSCoreComputerSlapInterfaceWorkflow(testSlapOSMixin):
transaction.abort()
def test_requestSoftwareRelease_state_required(self):
self._makePerson()
self.person_user = self.makePerson()
self.computer.edit(source_administration=self.person_user.getRelativeUrl())
self.tic()
self.login(self.person_user.getUserId())
......@@ -249,7 +234,7 @@ class TestSlapOSCoreComputerSlapInterfaceWorkflow(testSlapOSMixin):
transaction.abort()
def test_requestSoftwareRelease_available(self):
self._makePerson()
self.person_user = self.makePerson()
self.computer.edit(source_administration=self.person_user.getRelativeUrl())
self.tic()
self.login(self.person_user.getUserId())
......@@ -265,7 +250,7 @@ class TestSlapOSCoreComputerSlapInterfaceWorkflow(testSlapOSMixin):
self.assertEqual('validated', software_installation.getValidationState())
def test_requestSoftwareRelease_destroyed(self):
self._makePerson()
self.person_user = self.makePerson()
self.computer.edit(source_administration=self.person_user.getRelativeUrl())
self.tic()
self.login(self.person_user.getUserId())
......@@ -279,7 +264,7 @@ class TestSlapOSCoreComputerSlapInterfaceWorkflow(testSlapOSMixin):
self.assertEqual(None, software_installation)
def test_requestSoftwareRelease_available_destroyed(self):
self._makePerson()
self.person_user = self.makePerson()
self.computer.edit(source_administration=self.person_user.getRelativeUrl())
self.tic()
self.login(self.person_user.getUserId())
......@@ -307,7 +292,7 @@ class TestSlapOSCoreComputerSlapInterfaceWorkflow(testSlapOSMixin):
self.assertEqual('validated', software_installation.getValidationState())
def test_requestSoftwareRelease_not_indexed(self):
self._makePerson()
self.person_user = self.makePerson()
self.computer.edit(source_administration=self.person_user.getRelativeUrl())
self.tic()
self.login(self.person_user.getUserId())
......@@ -322,7 +307,7 @@ class TestSlapOSCoreComputerSlapInterfaceWorkflow(testSlapOSMixin):
@expectedFailure
def test_requestSoftwareRelease_same_transaction(self):
self._makePerson()
self.person_user = self.makePerson()
self.computer.edit(source_administration=self.person_user.getRelativeUrl())
self.tic()
self.login(self.person_user.getUserId())
......@@ -335,7 +320,7 @@ class TestSlapOSCoreComputerSlapInterfaceWorkflow(testSlapOSMixin):
transaction.abort()
def test_revokeCertificate(self):
self.login(self.computer.getReference())
self.login(self.computer.getUserId())
self.computer.generateCertificate()
computer_key = self.portal.REQUEST.get('computer_key')
computer_certificate = self.portal.REQUEST.get('computer_certificate')
......@@ -353,14 +338,14 @@ class TestSlapOSCoreComputerSlapInterfaceWorkflow(testSlapOSMixin):
self.assertEqual(None, self.computer.getDestinationReference())
def test_revokeCertificateNoCertificate(self):
self.login(self.computer.getReference())
self.login(self.computer.getUserId())
self.assertRaises(ValueError, self.computer.revokeCertificate)
self.assertEqual(None, self.portal.REQUEST.get('computer_key'))
self.assertEqual(None, self.portal.REQUEST.get('computer_certificate'))
self.assertEqual(None, self.computer.getDestinationReference())
def test_revokeCertificate_twice(self):
self.login(self.computer.getReference())
self.login(self.computer.getUserId())
self.computer.generateCertificate()
computer_key = self.portal.REQUEST.get('computer_key')
computer_certificate = self.portal.REQUEST.get('computer_certificate')
......@@ -387,32 +372,21 @@ class TestSlapOSCorePersonComputerSupply(testSlapOSMixin):
def afterSetUp(self):
super(TestSlapOSCorePersonComputerSupply, self).afterSetUp()
portal = self.getPortalObject()
new_id = self.generateNewId()
# Clone computer document
computer = portal.computer_module.template_computer\
.Base_createCloneDocument(batch_mode=1)
# Clone person document
person_user = 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 = self.makePerson(new_id=self.new_id, index=0)
computer.edit(
title="Computer %s for %s" % (new_id, person_user.getReference()),
reference="TESTCOMP-%s" % new_id,
title="Computer %s for %s" % (self.new_id, person_user.getReference()),
reference="TESTCOMP-%s" % self.new_id,
source_administration=person_user.getRelativeUrl()
)
computer.validate()
self.computer = computer
person_user.validate()
for assignment in person_user.contentValues(portal_type="Assignment"):
assignment.open()
transaction.commit()
# XXX Tic is needed to reindex the created open order
self.tic()
# Login as new user
......@@ -735,33 +709,33 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(testSlapOSMixin):
q['comment'] == comment])
def test_bang_required_comment(self):
self.login(self.instance.getReference())
self.login(self.instance.getUserId())
self.assertRaises(KeyError, self.instance.bang, bang_tree=0)
transaction.abort()
def test_bang_required_bang_tree(self):
self.login(self.instance.getReference())
comment = 'Comment %s' % self.generateNewId()
self.login(self.instance.getUserId())
comment = 'Comment %s' % self.new_id
self.assertRaises(KeyError, self.instance.bang, comment=comment)
transaction.abort()
def test_bang(self):
self.login(self.instance.getReference())
comment = 'Comment %s' % self.generateNewId()
self.login(self.instance.getUserId())
comment = 'Comment %s' % self.new_id
count = self._countInstanceBang(self.instance, comment)
self.instance.bang(bang_tree=0, comment=comment)
self.assertEqual(count+1, self._countInstanceBang(self.instance, comment))
def test_bang_tree(self):
self.login(self.instance.getReference())
self.login(self.instance.getUserId())
request_kw = self.request_kw.copy()
request_kw['software_title'] = 'New %s' % self.generateNewId()
request_kw['software_title'] = 'New %s' % self.new_id
self.instance.requestInstance(**request_kw)
request_instance = self.instance.REQUEST['request_instance']
self.instance.REQUEST['request_instance'] = None
self.tic()
comment = 'Comment %s' % self.generateNewId()
comment = 'Comment %s' % self.new_id
count1 = self._countInstanceBang(self.instance, comment)
count2 = self._countInstanceBang(request_instance, comment)
self.instance.bang(bang_tree=1, comment=comment)
......@@ -772,7 +746,7 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(testSlapOSMixin):
comment))
def test_allocatePartition_computer_partition_url_required(self):
self.login(self.instance.getReference())
self.login(self.instance.getUserId())
self.assertRaises(TypeError, self.instance.allocatePartition)
def test_allocatePartition(self):
......@@ -821,19 +795,19 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(testSlapOSMixin):
self.assertRaises(AssertionError, self.instance.unallocatePartition)
def test_rename_new_name_required(self):
self.login(self.instance.getReference())
self.login(self.instance.getUserId())
self.assertRaises(KeyError, self.instance.rename)
def test_rename(self):
new_name = 'New %s' % self.generateNewId()
self.login(self.instance.getReference())
self.login(self.instance.getUserId())
self.instance.rename(new_name=new_name)
self.assertEqual(new_name, self.instance.getTitle())
transaction.abort()
def test_rename_twice_not_indexed(self):
new_name = 'New %s' % self.generateNewId()
self.login(self.instance.getReference())
self.login(self.instance.getUserId())
self.instance.rename(new_name=new_name)
self.assertEqual(new_name, self.instance.getTitle())
transaction.commit()
......@@ -844,7 +818,7 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(testSlapOSMixin):
@expectedFailure
def test_rename_twice_same_transaction(self):
new_name = 'New %s' % self.generateNewId()
self.login(self.instance.getReference())
self.login(self.instance.getUserId())
self.instance.rename(new_name=new_name)
self.assertEqual(new_name, self.instance.getTitle())
self.assertRaises(NotImplementedError, self.instance.rename,
......@@ -853,7 +827,7 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(testSlapOSMixin):
def test_rename_existing(self):
new_name = 'New %s' % self.generateNewId()
self.login(self.instance.getReference())
self.login(self.instance.getUserId())
request_kw = self.request_kw.copy()
request_kw['software_title'] = new_name
......@@ -869,7 +843,7 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(testSlapOSMixin):
transaction.abort()
def test_requestDestroy(self):
self.login(self.instance.getReference())
self.login(self.instance.getUserId())
request_kw = self.request_kw.copy()
self.instance.requestDestroy(**request_kw)
......@@ -877,7 +851,7 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(testSlapOSMixin):
transaction.abort()
def test_requestDestroy_required(self):
self.login(self.instance.getReference())
self.login(self.instance.getUserId())
software_release=self.request_kw['software_release']
software_type=self.request_kw['software_type']
......@@ -934,7 +908,7 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(testSlapOSMixin):
transaction.abort()
def test_requestStop(self):
self.login(self.instance.getReference())
self.login(self.instance.getUserId())
request_kw = self.request_kw.copy()
self.instance.requestStop(**request_kw)
......@@ -942,7 +916,7 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(testSlapOSMixin):
transaction.abort()
def test_requestStop_required(self):
self.login(self.instance.getReference())
self.login(self.instance.getUserId())
software_release=self.request_kw['software_release']
software_type=self.request_kw['software_type']
......@@ -999,7 +973,7 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(testSlapOSMixin):
transaction.abort()
def test_requestStart(self):
self.login(self.instance.getReference())
self.login(self.instance.getUserId())
request_kw = self.request_kw.copy()
self.instance.requestStop(**request_kw)
......@@ -1008,7 +982,7 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(testSlapOSMixin):
transaction.abort()
def test_requestStart_required(self):
self.login(self.instance.getReference())
self.login(self.instance.getUserId())
self.instance.requestStop(**self.request_kw)
......@@ -1067,7 +1041,7 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(testSlapOSMixin):
transaction.abort()
def test_updateConnection(self):
self.login(self.instance.getReference())
self.login(self.instance.getUserId())
request_kw = self.request_kw.copy()
self.instance.requestStop(**request_kw)
......@@ -1077,7 +1051,7 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(testSlapOSMixin):
transaction.abort()
def test_updateConnectionRequired(self):
self.login(self.instance.getReference())
self.login(self.instance.getUserId())
request_kw = self.request_kw.copy()
self.instance.requestStop(**request_kw)
......@@ -1087,7 +1061,7 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(testSlapOSMixin):
transaction.abort()
def test_updateConnectionBrokenXml(self):
self.login(self.instance.getReference())
self.login(self.instance.getUserId())
request_kw = self.request_kw.copy()
self.instance.requestStop(**request_kw)
......@@ -1099,6 +1073,7 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(testSlapOSMixin):
class TestSlapOSCoreSoftwareInstanceRequest(testSlapOSMixin):
"""Tests instance.requestInstance"""
def afterSetUp(self):
super(TestSlapOSCoreSoftwareInstanceRequest, self).afterSetUp()
portal = self.getPortalObject()
......@@ -1147,7 +1122,7 @@ class TestSlapOSCoreSoftwareInstanceRequest(testSlapOSMixin):
self.tic()
# Login as new Software Instance
self.login(self.software_instance.getReference())
self.login(self.software_instance.getUserId())
def beforeTearDown(self):
transaction.abort()
......@@ -1938,27 +1913,13 @@ class TestSlapOSCorePersonRequest(testSlapOSMixin):
def afterSetUp(self):
super(TestSlapOSCorePersonRequest, self).afterSetUp()
portal = self.getPortalObject()
new_id = self.generateNewId()
# Clone person document
person_user = 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()
transaction.commit()
# XXX Tic is needed to reindex the created open order
person_user = self.makePerson()
self.tic()
# Login as new user
self.login(person_user.getUserId())
new_person = self.getPortalObject().ERP5Site_getAuthenticatedMemberPersonValue()
self.assertEquals(person_user.getRelativeUrl(), new_person.getRelativeUrl())
......@@ -2501,27 +2462,13 @@ class TestSlapOSCorePersonRequestComputer(testSlapOSMixin):
def afterSetUp(self):
super(TestSlapOSCorePersonRequestComputer, self).afterSetUp()
portal = self.getPortalObject()
new_id = self.generateNewId()
# Clone person document
person_user = 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()
transaction.commit()
# XXX Tic is needed to reindex the created open order
person_user = self.makePerson()
self.tic()
# Login as new user
self.login(person_user.getUserId())
new_person = self.getPortalObject().ERP5Site_getAuthenticatedMemberPersonValue()
new_person = portal.ERP5Site_getAuthenticatedMemberPersonValue()
self.assertEquals(person_user.getRelativeUrl(), new_person.getRelativeUrl())
def beforeTearDown(self):
......@@ -2709,23 +2656,8 @@ class TestSlapOSCorePersonRequestComputer(testSlapOSMixin):
class TestSlapOSCoreSlapOSCloudInteractionWorkflow(testSlapOSMixin):
def _makePerson(self):
new_id = self.generateNewId()
self.person_user = self.portal.person_module.template_member.\
Base_createCloneDocument(batch_mode=1)
self.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,
)
self.person_user.validate()
for assignment in self.person_user.contentValues(portal_type="Assignment"):
assignment.open()
self.tic()
def test_Computer_setSubjectList(self):
self._makePerson()
self.person_user = self.makePerson()
self.login(self.person_user.getUserId())
new_id = self.generateNewId()
......@@ -2742,15 +2674,20 @@ class TestSlapOSCoreSlapOSCloudInteractionWorkflow(testSlapOSMixin):
self.person_user.getRelativeUrl()
def check_Instance_validate(self, portal_type):
self._makePerson()
self.person_user = self.makePerson()
self.login(self.person_user.getUserId())
new_id = self.generateNewId()
instance = self.portal.software_instance_module.newContent(
portal_type=portal_type,
title="Instance %s for %s" % (new_id, self.person_user.getReference()),
reference="TESTINST-%s" % new_id)
if portal_type == "Software Instance":
self._addERP5Login(instance)
self.tic()
def verify_activeSense_call(self):
if self.getRelativeUrl() == 'portal_alarms/slapos_allocate_instance':
instance.portal_workflow.doActionFor(instance, action='edit_action',
......@@ -2758,13 +2695,12 @@ class TestSlapOSCoreSlapOSCloudInteractionWorkflow(testSlapOSMixin):
else:
return self.activeSense_call()
# Replace activeSense by a dummy method
from Products.ERP5Type.Document.Alarm import Alarm
Alarm.activeSense_call = Alarm.activeSense
Alarm.activeSense = verify_activeSense_call
try:
instance.validate()
instance.portal_alarms.slapos_allocate_instance.activeSense()
self.tic()
finally:
Alarm.activeSense = Alarm.activeSense_call
......@@ -2779,14 +2715,14 @@ class TestSlapOSCoreSlapOSCloudInteractionWorkflow(testSlapOSMixin):
return self.check_Instance_validate("Slave Instance")
def test_SlaveInstance_requestDestroy(self):
self._makePerson()
self.person_user = self.makePerson()
self.login(self.person_user.getUserId())
new_id = self.generateNewId()
instance = self.portal.software_instance_module.newContent(
portal_type='Slave Instance',
title="Instance %s for %s" % (new_id, self.person_user.getReference()),
reference="TESTINST-%s" % new_id,
destination_reference="TESTINST-%s" % new_id,
title="Instance %s for %s" % (self.new_id, self.person_user.getReference()),
reference="TESTINST-%s" % self.new_id,
destination_reference="TESTINST-%s" % self.new_id,
)
request_kw = dict(
software_release='http://example.org',
......@@ -2803,16 +2739,17 @@ class TestSlapOSCoreSlapOSCloudInteractionWorkflow(testSlapOSMixin):
self.assertEqual(instance.getValidationState(), 'invalidated')
def check_SoftwareInstallation_changeState(self, method_id):
self._makePerson()
self.person_user = self.makePerson()
self.login(self.person_user.getUserId())
new_id = self.generateNewId()
computer = self.portal.computer_module.newContent(
portal_type='Computer',
title="Computer %s for %s" % (new_id, self.person_user.getReference()),
reference="TESTCOMP-%s" % new_id)
title="Computer %s for %s" % (self.new_id, self.person_user.getReference()),
reference="TESTCOMP-%s" % self.new_id)
self._addERP5Login(computer)
installation = self.portal.software_installation_module.newContent(
portal_type='Software Installation',
title="Installation %s for %s" % (new_id, self.person_user.getReference()),
title="Installation %s for %s" % (self.new_id, self.person_user.getReference()),
aggregate_value=computer,
)
self.tic()
......@@ -2824,7 +2761,6 @@ class TestSlapOSCoreSlapOSCloudInteractionWorkflow(testSlapOSMixin):
else:
return self.reindexObject_call(*args, **kw)
# Replace activeSense by a dummy method
from Products.ERP5Type.Base import Base
Base.reindexObject_call = Base.reindexObject
Base.reindexObject = verify_reindexObject_call
......@@ -2844,7 +2780,7 @@ class TestSlapOSCoreSlapOSCloudInteractionWorkflow(testSlapOSMixin):
return self.check_SoftwareInstallation_changeState('requestDestroy')
def check_SoftwareInstance_changeState(self, method_id):
self._makePerson()
self.person_user = self.makePerson()
self.login(self.person_user.getUserId())
new_id = self.generateNewId()
......@@ -2852,6 +2788,7 @@ class TestSlapOSCoreSlapOSCloudInteractionWorkflow(testSlapOSMixin):
portal_type='Computer',
title="Computer %s for %s" % (new_id, self.person_user.getReference()),
reference="TESTCOMP-%s" % new_id)
self._addERP5Login(computer)
partition = computer.newContent(
portal_type='Computer Partition',
title="Partition Computer %s for %s" % (new_id,
......@@ -2908,15 +2845,14 @@ class TestSlapOSCoreSlapOSCloudInteractionWorkflow(testSlapOSMixin):
return self.check_SoftwareInstance_changeState("requestDestroy")
def check_change_instance_parameter(self, portal_type, method_id):
self._makePerson()
self.person_user = self.makePerson()
self.login(self.person_user.getUserId())
new_id = self.generateNewId()
instance = self.portal.software_instance_module.newContent(
portal_type=portal_type,
title="Instance %s for %s" % (new_id, self.person_user.getReference()),
reference="TESTINST-%s" % new_id,
destination_reference="TESTINST-%s" % new_id,
title="Instance %s for %s" % (self.new_id, self.person_user.getReference()),
reference="TESTINST-%s" % self.new_id,
destination_reference="TESTINST-%s" % self.new_id,
ssl_certificate="foo",
ssl_key="bar",
)
......@@ -2965,7 +2901,7 @@ class TestSlapOSCoreSlapOSCloudInteractionWorkflow(testSlapOSMixin):
def test_SoftwareInstance_setPredecessorList(self):
portal_type = "Software Instance"
self._makePerson()
self.person_user = self.makePerson()
self.login(self.person_user.getUserId())
new_id = self.generateNewId()
......
......@@ -5,4 +5,11 @@ computer.edit(
allocation_scope='open/personal',
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')
......@@ -98,8 +98,14 @@ if (request_software_instance is None):
activate_kw={'tag': tag},
**new_content_kw
)
# request_software_instance.portal_workflow.doActionFor(request_software_instance, 'validate_action')
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()] = []
else:
......
Computer | ERP5 Login
Hosting Subscription Module | Hosting Subscription
Software Installation Module | Software Installation
Software Instance Module | Slave Instance
Software Instance Module | Software Instance
Software Instance | ERP5 Login
\ No newline at end of file
Computer
Hosting Subscription
Hosting Subscription Module
Slave Instance
......
......@@ -2,6 +2,7 @@ Assignment | SlaposAssignmentConstraint
Computer Model | SlaposCapacity
Computer Partition | ComputerPartition
Computer Partition | SlaposComputerPartitionConstraint
Computer | ERP5User
Computer | SlaposCapacity
Computer | SlaposComputerConstraint
Computer | Url
......@@ -22,6 +23,7 @@ Slave Instance | Url
Slave Instance | VariationRange
Software Installation | Url
Software Installation | VariationRange
Software Instance | ERP5User
Software Instance | HostingSubscription
Software Instance | Reference
Software Instance | SoftwareInstance
......
# Copyright (c) 2013 Nexedi SA and Contributors. All Rights Reserved.
import transaction
from Products.SlapOS.tests.testSlapOSMixin import \
testSlapOSMixin
testSlapOSMixin, simulate
from zExceptions import Unauthorized
from DateTime import DateTime
from functools import wraps
from Products.ERP5Type.tests.utils import createZODBPythonScript
import difflib
import json
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
def getFakeSlapState():
return "destroy_requested"
class TestSlapOSFolder_getOpenTicketList(testSlapOSMixin):
class TestCRMSkinsMixin(testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
abort_transaction = 1
def afterSetUp(self):
super(TestSlapOSFolder_getOpenTicketList, self).afterSetUp()
self.new_id = self.generateNewId()
self.person = self.portal.person_module.newContent(
portal_type='Person',
title="Person %s" % self.new_id,
reference="TESTPERS-%s" % self.new_id,
default_email_text="live_test_%s@example.org" % self.new_id,
)
super(TestCRMSkinsMixin, self).afterSetUp()
self.person = self.makePerson(new_id=self.new_id, index=0, user=0)
def _cancelTestSupportRequestList(self, title="%"):
for support_request in self.portal.portal_catalog(
portal_type="Support Request",
title=title,
simulation_state=["validated", "suspended"]):
support_request.invalidate()
self.tic()
def _updatePersonAssignment(self, person, role='role/member'):
for assignment in person.contentValues(portal_type="Assignment"):
assignment.cancel()
assignment = person.newContent(portal_type='Assignment')
assignment.setRole(role)
assignment.setStartDate(DateTime())
assignment.open()
return assignment
class TestSlapOSFolder_getOpenTicketList(TestCRMSkinsMixin):
def _test_ticket(self, ticket, expected_amount):
module = ticket.getParentValue()
......@@ -156,13 +148,7 @@ class TestSlapOSFolder_getOpenTicketList(testSlapOSMixin):
ticket = newUpgradeDecision()
self._test_upgrade_decision(ticket, 2)
class TestSlapOSTicketEvent(testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
def afterSetUp(self):
super(TestSlapOSTicketEvent, self).afterSetUp()
class TestSlapOSTicketEvent(TestCRMSkinsMixin):
def _test_event(self, ticket):
......@@ -231,19 +217,6 @@ class TestSlapOSTicketEvent(testSlapOSMixin):
class TestSlapOSEvent_getRSSTextContent(TestSlapOSTicketEvent):
def afterSetUp(self):
super(TestSlapOSEvent_getRSSTextContent, self).afterSetUp()
self.new_id = self.generateNewId()
self.person = self.portal.person_module.newContent(
portal_type='Person',
title="Person %s" % self.new_id,
reference="TESTPERS-%s" % self.new_id,
default_email_text="live_test_%s@example.org" % self.new_id,
)
def beforeTearDown(self):
transaction.abort()
def test_Event_getRSSTextContent(self):
source = self.person
......@@ -311,19 +284,6 @@ class TestSlapOSEvent_getRSSTextContent(TestSlapOSTicketEvent):
class TestSlapOSTicket_getLatestEvent(TestSlapOSTicketEvent):
def beforeTearDown(self):
transaction.abort()
def afterSetUp(self):
super(TestSlapOSTicket_getLatestEvent, self).afterSetUp()
self.new_id = self.generateNewId()
self.person = self.portal.person_module.newContent(
portal_type='Person',
title="Person %s" % self.new_id,
reference="TESTPERS-%s" % self.new_id,
default_email_text="live_test_%s@example.org" % self.new_id,
)
def test_support_request(self):
ticket = self.portal.support_request_module.newContent(\
title="Test Support Request %s" % self.new_id,
......@@ -357,17 +317,7 @@ class TestSlapOSTicket_getLatestEvent(TestSlapOSTicketEvent):
class TestSlapOSPerson_checkToCreateRegularisationRequest(testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
def createPerson(self):
new_id = self.generateNewId()
return self.portal.person_module.newContent(
portal_type='Person',
title="Person %s" % new_id,
reference="TESTPERS-%s" % new_id,
default_email_text="live_test_%s@example.org" % new_id,
)
abort_transaction = 1
@simulate('Entity_statBalance', '*args, **kwargs', 'return "1"')
def test_addRegularisationRequest_payment_requested(self):
......@@ -377,7 +327,7 @@ class TestSlapOSPerson_checkToCreateRegularisationRequest(testSlapOSMixin):
if preference.getPreferenceState() == 'global':
preference.setPreferredSlaposWebSiteUrl('http://foobar.org/')
person = self.createPerson()
person = self.makePerson(index=0, user=0)
before_date = DateTime()
ticket, event = person.Person_checkToCreateRegularisationRequest()
after_date = DateTime()
......@@ -431,7 +381,7 @@ The slapos team
if preference.getPreferenceState() == 'global':
preference.setPreferredSlaposWebSiteUrl('http://foobar.org/')
person = self.createPerson()
person = self.makePerson(index=0, user=0)
new_id = self.generateNewId()
notification_message = self.portal.notification_message_module.newContent(
portal_type="Notification Message",
......@@ -484,7 +434,7 @@ The slapos team
@simulate('Entity_statBalance', '*args, **kwargs', 'return "1"')
def test_addRegularisationRequest_do_not_duplicate_ticket_if_not_reindexed(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket, event = person.Person_checkToCreateRegularisationRequest()
transaction.commit()
ticket2, event2 = person.Person_checkToCreateRegularisationRequest()
......@@ -498,14 +448,14 @@ The slapos team
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
def test_addRegularisationRequest_balance_ok(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket, event = person.Person_checkToCreateRegularisationRequest()
self.assertEquals(ticket, None)
self.assertEquals(event, None)
@simulate('Entity_statBalance', '*args, **kwargs', 'return "1"')
def test_addRegularisationRequest_existing_suspended_ticket(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket, event = person.Person_checkToCreateRegularisationRequest()
transaction.commit()
self.tic()
......@@ -517,7 +467,7 @@ The slapos team
@simulate('Entity_statBalance', '*args, **kwargs', 'return "1"')
def test_addRegularisationRequest_existing_validated_ticket(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket, event = person.Person_checkToCreateRegularisationRequest()
ticket.validate()
transaction.commit()
......@@ -530,7 +480,7 @@ The slapos team
@simulate('Entity_statBalance', '*args, **kwargs', 'return "1"')
def test_addRegularisationRequest_existing_invalidated_ticket(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = person.Person_checkToCreateRegularisationRequest()[0]
ticket.invalidate()
transaction.commit()
......@@ -540,7 +490,7 @@ The slapos team
self.assertNotEquals(event2, None)
def test_addRegularisationRequest_REQUEST_disallowed(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
self.assertRaises(
Unauthorized,
person.Person_checkToCreateRegularisationRequest,
......@@ -550,16 +500,7 @@ The slapos team
class TestSlapOSRegularisationRequest_invalidateIfPersonBalanceIsOk(
testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
def createPerson(self):
new_id = self.generateNewId()
return self.portal.person_module.newContent(
portal_type='Person',
title="Person %s" % new_id,
reference="TESTPERS-%s" % new_id,
)
abort_transaction = 1
def createRegularisationRequest(self):
new_id = self.generateNewId()
......@@ -578,7 +519,7 @@ class TestSlapOSRegularisationRequest_invalidateIfPersonBalanceIsOk(
@simulate('Entity_statBalance', '*args, **kwargs', 'return "0"')
def test_invalidateIfPersonBalanceIsOk_matching_case(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(source_project_value=person)
ticket.validate()
......@@ -588,7 +529,7 @@ class TestSlapOSRegularisationRequest_invalidateIfPersonBalanceIsOk(
@simulate('Entity_statBalance', '*args, **kwargs', 'return "0"')
def test_invalidateIfPersonBalanceIsOk_not_suspended(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(source_project_value=person)
ticket.validate()
......@@ -605,7 +546,7 @@ class TestSlapOSRegularisationRequest_invalidateIfPersonBalanceIsOk(
@simulate('Entity_statBalance', '*args, **kwargs', 'return "1"')
def test_invalidateIfPersonBalanceIsOk_wrong_balance(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(source_project_value=person)
ticket.validate()
......@@ -615,17 +556,7 @@ class TestSlapOSRegularisationRequest_invalidateIfPersonBalanceIsOk(
class TestSlapOSRegularisationRequest_checkToSendUniqEvent(testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
def createPerson(self):
new_id = self.generateNewId()
return self.portal.person_module.newContent(
portal_type='Person',
title="Person %s" % new_id,
reference="TESTPERS-%s" % new_id,
default_email_text="live_test_%s@example.org" % new_id,
)
abort_transaction = 1
def createRegularisationRequest(self):
new_id = self.generateNewId()
......@@ -637,7 +568,7 @@ class TestSlapOSRegularisationRequest_checkToSendUniqEvent(testSlapOSMixin):
)
def test_checkToSendUniqEvent_no_event(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(
source='organisation_module/slapos',
......@@ -673,7 +604,7 @@ class TestSlapOSRegularisationRequest_checkToSendUniqEvent(testSlapOSMixin):
)
def test_checkToSendUniqEvent_call_twice_with_tic(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(
source='organisation_module/slapos',
......@@ -692,7 +623,7 @@ class TestSlapOSRegularisationRequest_checkToSendUniqEvent(testSlapOSMixin):
self.assertEquals(event.getRelativeUrl(), event2.getRelativeUrl())
def test_checkToSendUniqEvent_manual_event(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(
source='organisation_module/slapos',
......@@ -717,7 +648,7 @@ class TestSlapOSRegularisationRequest_checkToSendUniqEvent(testSlapOSMixin):
self.assertEquals(event.getRelativeUrl(), event2.getRelativeUrl())
def test_checkToSendUniqEvent_not_suspended(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(
source='organisation_module/slapos',
......@@ -730,7 +661,7 @@ class TestSlapOSRegularisationRequest_checkToSendUniqEvent(testSlapOSMixin):
self.assertEquals(event, None)
def test_checkToSendUniqEvent_event_not_reindexed(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(
source='organisation_module/slapos',
......@@ -757,17 +688,7 @@ class TestSlapOSRegularisationRequest_checkToSendUniqEvent(testSlapOSMixin):
class TestSlapOSRegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty(
testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
def createPerson(self):
new_id = self.generateNewId()
return self.portal.person_module.newContent(
portal_type='Person',
title="Person %s" % new_id,
reference="TESTPERS-%s" % new_id,
default_email_text="live_test_%s@example.org" % new_id,
)
abort_transaction = 1
def createRegularisationRequest(self):
new_id = self.generateNewId()
......@@ -822,7 +743,7 @@ class TestSlapOSRegularisationRequest_cancelInvoiceIfPersonOpenOrderIsEmpty(
'%s %s %s %s" % (service_relative_url, title, text_content, comment))\n' \
'return "fooevent"')
def test_cancelInvoiceIfPersonOpenOrderIsEmpty_invoice_to_cancel(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(
destination_value=person,
......@@ -885,7 +806,7 @@ The slapos team
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
def test_cancelInvoiceIfPersonOpenOrderIsEmpty_not_suspended_ticket(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(
destination_value=person,
......@@ -922,7 +843,7 @@ The slapos team
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
def test_cancelInvoiceIfPersonOpenOrderIsEmpty_no_open_order(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(
destination_value=person,
......@@ -943,7 +864,7 @@ The slapos team
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
def test_cancelInvoiceIfPersonOpenOrderIsEmpty_with_open_order_line(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(
destination_value=person,
......@@ -974,7 +895,7 @@ The slapos team
'%s %s %s %s" % (service_relative_url, title, text_content, comment))\n' \
'return "fooevent"')
def test_cancelInvoiceIfPersonOpenOrderIsEmpty_no_invoice(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
ticket.edit(
destination_value=person,
......@@ -996,8 +917,7 @@ The slapos team
class TestSlapOSRegularisationRequest_checkToTriggerNextEscalationStep(
testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
abort_transaction = 1
def createRegularisationRequest(self):
new_id = self.generateNewId()
......@@ -1194,8 +1114,7 @@ class TestSlapOSRegularisationRequest_checkToTriggerNextEscalationStep(
class TestSlapOSRegularisationRequest_triggerAcknowledgmentEscalation(
testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
abort_transaction = 1
def createRegularisationRequest(self):
new_id = self.generateNewId()
......@@ -1280,8 +1199,7 @@ The slapos team
class TestSlapOSRegularisationRequest_triggerStopReminderEscalation(
testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
abort_transaction = 1
def createRegularisationRequest(self):
new_id = self.generateNewId()
......@@ -1366,8 +1284,7 @@ The slapos team
class TestSlapOSRegularisationRequest_triggerStopAcknowledgmentEscalation(
testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
abort_transaction = 1
def createRegularisationRequest(self):
new_id = self.generateNewId()
......@@ -1452,8 +1369,7 @@ The slapos team
class TestSlapOSRegularisationRequest_triggerDeleteReminderEscalation(
testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
abort_transaction = 1
def createRegularisationRequest(self):
new_id = self.generateNewId()
......@@ -1538,8 +1454,7 @@ The slapos team
class TestSlapOSRegularisationRequest_stopHostingSubscriptionList(
testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
abort_transaction = 1
def createRegularisationRequest(self):
new_id = self.generateNewId()
......@@ -1550,20 +1465,6 @@ class TestSlapOSRegularisationRequest_stopHostingSubscriptionList(
resource='foo/bar',
)
def createPerson(self):
new_id = self.generateNewId()
person = self.portal.person_module.template_member.\
Base_createCloneDocument(batch_mode=1)
person.edit(
title="Person %s" % new_id,
reference="TESTPERS-%s" % new_id,
default_email_text="live_test_%s@example.org" % new_id,
)
person.manage_delObjects(
[x.getId() for x in person.contentValues(portal_type="Assignment")]
)
return person
def createHostingSubscription(self):
new_id = self.generateNewId()
hosting_subscription = self.portal.hosting_subscription_module\
......@@ -1591,7 +1492,7 @@ class TestSlapOSRegularisationRequest_stopHostingSubscriptionList(
'comment="Visited by HostingSubscription_stopFromRegularisationRequest ' \
'%s" % (person))')
def test_stopHostingSubscriptionList_matching_subscription(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
hosting_subscription = self.createHostingSubscription()
......@@ -1623,7 +1524,7 @@ class TestSlapOSRegularisationRequest_stopHostingSubscriptionList(
'comment="Visited by HostingSubscription_stopFromRegularisationRequest ' \
'%s" % (person))')
def test_stopHostingSubscriptionList_matching_subscription_2(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
hosting_subscription = self.createHostingSubscription()
......@@ -1652,7 +1553,7 @@ class TestSlapOSRegularisationRequest_stopHostingSubscriptionList(
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
def test_stopHostingSubscriptionList_other_subscription(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
self.createHostingSubscription()
......@@ -1675,7 +1576,6 @@ class TestSlapOSRegularisationRequest_stopHostingSubscriptionList(
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
def test_stopHostingSubscriptionList_no_person(self):
self.createPerson()
ticket = self.createRegularisationRequest()
ticket.edit(
......@@ -1696,7 +1596,7 @@ class TestSlapOSRegularisationRequest_stopHostingSubscriptionList(
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
def test_stopHostingSubscriptionList_not_suspended(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
self.createHostingSubscription()
......@@ -1718,7 +1618,7 @@ class TestSlapOSRegularisationRequest_stopHostingSubscriptionList(
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
def test_stopHostingSubscriptionList_other_resource(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
self.createHostingSubscription()
......@@ -1740,22 +1640,7 @@ class TestSlapOSRegularisationRequest_stopHostingSubscriptionList(
class TestSlapOSHostingSubscription_stopFromRegularisationRequest(
testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
def createPerson(self):
new_id = self.generateNewId()
person = self.portal.person_module.template_member.\
Base_createCloneDocument(batch_mode=1)
person.edit(
title="Person %s" % new_id,
reference="TESTPERS-%s" % new_id,
default_email_text="live_test_%s@example.org" % new_id,
)
person.manage_delObjects(
[x.getId() for x in person.contentValues(portal_type="Assignment")]
)
return person
abort_transaction = 1
def createHostingSubscription(self):
new_id = self.generateNewId()
......@@ -1777,7 +1662,7 @@ class TestSlapOSHostingSubscription_stopFromRegularisationRequest(
REQUEST={})
def test_stopFromRegularisationRequest_matching_subscription(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
hosting_subscription = self.createHostingSubscription()
hosting_subscription.edit(
destination_section=person.getRelativeUrl(),
......@@ -1805,7 +1690,7 @@ class TestSlapOSHostingSubscription_stopFromRegularisationRequest(
self.assertEquals(hosting_subscription.getSlapState(), "stop_requested")
def test_stopFromRegularisationRequest_stopped_subscription(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
hosting_subscription = self.createHostingSubscription()
hosting_subscription.edit(
destination_section=person.getRelativeUrl(),
......@@ -1828,22 +1713,7 @@ class TestSlapOSHostingSubscription_stopFromRegularisationRequest(
class TestSlapOSHostingSubscription_deleteFromRegularisationRequest(
testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
def createPerson(self):
new_id = self.generateNewId()
person = self.portal.person_module.template_member.\
Base_createCloneDocument(batch_mode=1)
person.edit(
title="Person %s" % new_id,
reference="TESTPERS-%s" % new_id,
default_email_text="live_test_%s@example.org" % new_id,
)
person.manage_delObjects(
[x.getId() for x in person.contentValues(portal_type="Assignment")]
)
return person
abort_transaction = 1
def createHostingSubscription(self):
new_id = self.generateNewId()
......@@ -1865,7 +1735,7 @@ class TestSlapOSHostingSubscription_deleteFromRegularisationRequest(
REQUEST={})
def test_deleteFromRegularisationRequest_started_subscription(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
hosting_subscription = self.createHostingSubscription()
hosting_subscription.edit(
destination_section=person.getRelativeUrl(),
......@@ -1893,7 +1763,7 @@ class TestSlapOSHostingSubscription_deleteFromRegularisationRequest(
self.assertEquals(hosting_subscription.getSlapState(), "destroy_requested")
def test_deleteFromRegularisationRequest_stopped_subscription(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
hosting_subscription = self.createHostingSubscription()
hosting_subscription.edit(
destination_section=person.getRelativeUrl(),
......@@ -1923,7 +1793,7 @@ class TestSlapOSHostingSubscription_deleteFromRegularisationRequest(
self.assertEquals(hosting_subscription.getSlapState(), "destroy_requested")
def test_deleteFromRegularisationRequest_destroyed_subscription(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
hosting_subscription = self.createHostingSubscription()
hosting_subscription.edit(
destination_section=person.getRelativeUrl(),
......@@ -1946,8 +1816,7 @@ class TestSlapOSHostingSubscription_deleteFromRegularisationRequest(
class TestSlapOSRegularisationRequest_deleteHostingSubscriptionList(
testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
abort_transaction = 1
def createRegularisationRequest(self):
new_id = self.generateNewId()
......@@ -1958,20 +1827,6 @@ class TestSlapOSRegularisationRequest_deleteHostingSubscriptionList(
resource='foo/bar',
)
def createPerson(self):
new_id = self.generateNewId()
person = self.portal.person_module.template_member.\
Base_createCloneDocument(batch_mode=1)
person.edit(
title="Person %s" % new_id,
reference="TESTPERS-%s" % new_id,
default_email_text="live_test_%s@example.org" % new_id,
)
person.manage_delObjects(
[x.getId() for x in person.contentValues(portal_type="Assignment")]
)
return person
def createHostingSubscription(self):
new_id = self.generateNewId()
hosting_subscription = self.portal.hosting_subscription_module\
......@@ -1999,7 +1854,7 @@ class TestSlapOSRegularisationRequest_deleteHostingSubscriptionList(
'comment="Visited by HostingSubscription_deleteFromRegularisationRequest ' \
'%s" % (person))')
def test_deleteHostingSubscriptionList_matching_subscription(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
hosting_subscription = self.createHostingSubscription()
......@@ -2028,7 +1883,7 @@ class TestSlapOSRegularisationRequest_deleteHostingSubscriptionList(
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
def test_deleteHostingSubscriptionList_other_subscription(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
self.createHostingSubscription()
......@@ -2051,7 +1906,6 @@ class TestSlapOSRegularisationRequest_deleteHostingSubscriptionList(
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
def test_deleteHostingSubscriptionList_no_person(self):
self.createPerson()
ticket = self.createRegularisationRequest()
ticket.edit(
......@@ -2072,7 +1926,7 @@ class TestSlapOSRegularisationRequest_deleteHostingSubscriptionList(
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
def test_deleteHostingSubscriptionList_not_suspended(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
self.createHostingSubscription()
......@@ -2094,7 +1948,7 @@ class TestSlapOSRegularisationRequest_deleteHostingSubscriptionList(
'*args, **kwargs',
'raise NotImplementedError, "Should not have been called"')
def test_deleteHostingSubscriptionList_other_resource(self):
person = self.createPerson()
person = self.makePerson(index=0, user=0)
ticket = self.createRegularisationRequest()
self.createHostingSubscription()
......@@ -2113,50 +1967,21 @@ class TestSlapOSRegularisationRequest_deleteHostingSubscriptionList(
self.tic()
class TestSlapOSComputer_notifyWrongAllocationScope(testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
class TestSlapOSComputer_notifyWrongAllocationScope(TestCRMSkinsMixin):
def afterSetUp(self):
super(TestSlapOSComputer_notifyWrongAllocationScope, self).afterSetUp()
self.new_id = self.generateNewId()
self._cancelTestSupportRequestList()
def _cancelTestSupportRequestList(self):
for support_request in self.portal.portal_catalog(
portal_type="Support Request",
title="%%TESTCOMPT-%",
simulation_state=["validated", "suspended"]):
support_request.invalidate()
self.tic()
self._cancelTestSupportRequestList(title="%%TESTCOMPT-%")
def _makeComputer(self):
super(TestSlapOSComputer_notifyWrongAllocationScope, self)._makeComputer()
# Clone computer document
self.computer.edit(
source_administration_value=self._makePerson()
source_administration_value=self.makePerson()
)
return self.computer
def _makePerson(self):
# Clone computer document
person = self.portal.person_module.template_member\
.Base_createCloneDocument(batch_mode=1)
person.edit(reference='TESTPERSON-%s' % (self.generateNewId(), ))
person.immediateReindexObject()
return person
def _updatePersonAssignment(self, person, role='role/member'):
for assignment in person.contentValues(portal_type="Assignment"):
assignment.cancel()
assignment = person.newContent(portal_type='Assignment')
assignment.setRole(role)
assignment.setStartDate(DateTime())
assignment.open()
return assignment
def _getGeneratedSupportRequest(self, computer):
request_title = '%%We have changed allocation scope for %s' % \
computer.getReference()
......@@ -2195,7 +2020,6 @@ class TestSlapOSComputer_notifyWrongAllocationScope(testSlapOSMixin):
def test_computerNotAllowedAllocationScope_OpenPublic(self):
computer = self._makeComputer()
person = computer.getSourceAdministrationValue()
self._updatePersonAssignment(person, 'role/member')
self.portal.REQUEST['test_computerNotAllowedAllocationScope_OpenPublic'] = \
self._makeNotificationMessage(computer.getReference())
......@@ -2232,12 +2056,11 @@ class TestSlapOSComputer_notifyWrongAllocationScope(testSlapOSMixin):
def test_computerNotAllowedAllocationScope_OpenFriend(self):
computer = self._makeComputer()
person = computer.getSourceAdministrationValue()
self._updatePersonAssignment(person, 'role/member')
self.portal.REQUEST['test_computerNotAllowedAllocationScope_OpenFriend'] = \
self._makeNotificationMessage(computer.getReference())
friend_person = self._makePerson()
friend_person = self.makePerson()
computer.edit(allocation_scope='open/friend',
destination_section=friend_person.getRelativeUrl())
ticket = computer.Computer_checkAndUpdateAllocationScope()
......@@ -2289,7 +2112,7 @@ class TestSlapOSComputer_notifyWrongAllocationScope(testSlapOSMixin):
def test_computerNormalAllocationScope_OpenPersonal(self):
computer = self._makeComputer()
person = computer.getSourceAdministrationValue()
self._updatePersonAssignment(person, 'role/member')
self._updatePersonAssignment(person, 'role/service_provider')
computer.edit(allocation_scope='open/personal')
computer.Computer_checkAndUpdateAllocationScope()
......@@ -2308,10 +2131,10 @@ class TestSlapOSComputer_notifyWrongAllocationScope(testSlapOSMixin):
def test_computerAllowedAllocationScope_OpenFriend(self):
computer = self._makeComputer()
friend_person = self.makePerson()
person = computer.getSourceAdministrationValue()
self._updatePersonAssignment(person, 'role/service_provider')
friend_person = self._makePerson()
computer.edit(allocation_scope='open/friend',
destination_section=friend_person.getRelativeUrl())
computer.Computer_checkAndUpdateAllocationScope()
......@@ -2321,11 +2144,7 @@ class TestSlapOSComputer_notifyWrongAllocationScope(testSlapOSMixin):
class TestComputer_hasContactedRecently(testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
def afterSetUp(self):
super(TestComputer_hasContactedRecently, self).afterSetUp()
abort_transaction = 1
def _makeComputer(self):
super(TestComputer_hasContactedRecently, self)._makeComputer()
......@@ -2422,11 +2241,7 @@ class TestComputer_hasContactedRecently(testSlapOSMixin):
class TestSlapOSPerson_isServiceProvider(testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
def afterSetUp(self):
super(TestSlapOSPerson_isServiceProvider, self).afterSetUp()
abort_transaction = 1
def test_Person_isServiceProvider(self):
person = self.portal.person_module.template_member\
......@@ -2450,35 +2265,16 @@ class TestSlapOSPerson_isServiceProvider(testSlapOSMixin):
self.assertTrue(person.Person_isServiceProvider())
class TestSlapOSisSupportRequestCreationClosed(testSlapOSMixin):
def beforeTearDown(self):
transaction.abort()
class TestSlapOSisSupportRequestCreationClosed(TestCRMSkinsMixin):
def afterSetUp(self):
super(TestSlapOSisSupportRequestCreationClosed, self).afterSetUp()
self.new_id = self.generateNewId()
self._cancelTestSupportRequestList()
def _cancelTestSupportRequestList(self):
for support_request in self.portal.portal_catalog(
portal_type="Support Request",
simulation_state=["validated", "suspended"]):
support_request.invalidate()
self.tic()
def _makePerson(self):
# Clone computer document
person = self.portal.person_module.template_member\
.Base_createCloneDocument(batch_mode=1)
person.edit(reference='TESTPERSON-%s' % (self.generateNewId(), ))
person.immediateReindexObject()
return person
def test_ERP5Site_isSupportRequestCreationClosed(self):
person = self._makePerson()
other_person = self._makePerson()
person = self.makePerson(user=0)
other_person = self.makePerson(user=0)
url = person.getRelativeUrl()
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed(url))
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed())
......@@ -2508,7 +2304,7 @@ class TestSlapOSisSupportRequestCreationClosed(testSlapOSMixin):
other_person.getRelativeUrl()))
def test_ERP5Site_isSupportRequestCreationClosed_suspended_state(self):
person = self._makePerson()
person = self.makePerson(user=0)
url = person.getRelativeUrl()
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed(url))
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed())
......@@ -2532,7 +2328,7 @@ class TestSlapOSisSupportRequestCreationClosed(testSlapOSMixin):
def test_ERP5Site_isSupportRequestCreationClosed_nonmonitoring(self):
person = self._makePerson()
person = self.makePerson(user=0)
url = person.getRelativeUrl()
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed(url))
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed())
......@@ -2555,19 +2351,13 @@ class TestSlapOSisSupportRequestCreationClosed(testSlapOSMixin):
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed())
class TestSlapOSGenerateSupportRequestForSlapOS(testSlapOSMixin):
class TestSlapOSGenerateSupportRequestForSlapOS(TestCRMSkinsMixin):
def afterSetUp(self):
super(TestSlapOSGenerateSupportRequestForSlapOS, self).afterSetUp()
self.tic()
self._cancelTestSupportRequestList()
def _cancelTestSupportRequestList(self):
for support_request in self.portal.portal_catalog(
portal_type="Support Request",
simulation_state=["validated", "suspended"]):
support_request.invalidate()
self.tic()
def _makeHostingSubscription(self):
person = self.portal.person_module.template_member\
......@@ -2604,18 +2394,10 @@ class TestSlapOSGenerateSupportRequestForSlapOS(testSlapOSMixin):
# Clone computer document
self.computer.edit(
source_administration_value=self._makePerson()
source_administration_value=self.makePerson(user=0)
)
return self.computer
def _makePerson(self):
# Clone computer document
person = self.portal.person_module.template_member\
.Base_createCloneDocument(batch_mode=1)
person.edit(reference='TESTPERSON-%s' % (self.generateNewId(), ))
person.immediateReindexObject()
return person
def _makeSoftwareInstallation(self):
self._makeComputer()
software_installation = self.portal\
......@@ -2808,7 +2590,7 @@ class TestSlapOSGenerateSupportRequestForSlapOS(testSlapOSMixin):
self.assertEqual(support_request.getRelativeUrl(), in_progress)
class TestSlapOSComputer_CheckState(testSlapOSMixin):
class TestSlapOSComputer_CheckState(TestCRMSkinsMixin):
def beforeTearDown(self):
self._cancelTestSupportRequestList()
......@@ -2816,8 +2598,7 @@ class TestSlapOSComputer_CheckState(testSlapOSMixin):
def afterSetUp(self):
super(TestSlapOSComputer_CheckState, self).afterSetUp()
self.new_id = self.generateNewId()
self._cancelTestSupportRequestList()
self._cancelTestSupportRequestList("% TESTCOMPT-%")
def _makeSupportRequest(self):
support_request = self.portal.\
......@@ -2826,14 +2607,6 @@ class TestSlapOSComputer_CheckState(testSlapOSMixin):
Base_createCloneDocument(batch_mode=1)
return support_request
def _cancelTestSupportRequestList(self):
for support_request in self.portal.portal_catalog(
portal_type="Support Request",
title="% TESTCOMPT-%",
simulation_state=["validated", "suspended"]):
support_request.invalidate()
self.tic()
def _makeNotificationMessage(self, reference):
notification_message = self.portal.notification_message_module.newContent(
portal_type="Notification Message",
......@@ -2858,18 +2631,10 @@ class TestSlapOSComputer_CheckState(testSlapOSMixin):
# Clone computer document
self.computer.edit(
source_administration_value=self._makePerson()
source_administration_value=self.makePerson(user=0)
)
return self.computer
def _makePerson(self):
# Clone computer document
person = self.portal.person_module.template_member\
.Base_createCloneDocument(batch_mode=1)
person.edit(reference='TESTPERSON-%s' % (self.generateNewId(), ))
person.immediateReindexObject()
return person
def _simulateBase_generateSupportRequestForSlapOS(self):
script_name = 'Base_generateSupportRequestForSlapOS'
if script_name in self.portal.portal_skins.custom.objectIds():
......@@ -3396,18 +3161,10 @@ class TestSupportRequestTrySendNotificationMessage(testSlapOSMixin):
# Clone computer document
self.computer.edit(
source_administration_value=self._makePerson()
source_administration_value=self.makePerson(user=0)
)
return self.computer
def _makePerson(self):
# Clone computer document
person = self.portal.person_module.template_member\
.Base_createCloneDocument(batch_mode=1)
person.edit(reference='TESTPERSON-%s' % (self.generateNewId(), ))
person.immediateReindexObject()
return person
def test_SupportRequest_trySendNotificationMessage(self):
self._makeComputer()
person = self.computer.getSourceAdministrationValue()
......@@ -3500,18 +3257,10 @@ class TestSupportRequestUpdateMonitoringState(testSlapOSMixin):
# Clone computer document
self.computer.edit(
source_administration_value=self._makePerson()
source_administration_value=self.makePerson(user=0)
)
return self.computer
def _makePerson(self):
# Clone computer document
person = self.portal.person_module.template_member\
.Base_createCloneDocument(batch_mode=1)
person.edit(reference='TESTPERSON-%s' % (self.generateNewId(), ))
person.immediateReindexObject()
return person
def _makeHostingSubscription(self):
person = self.portal.person_module.template_member\
.Base_createCloneDocument(batch_mode=1)
......@@ -3607,7 +3356,7 @@ class TestSupportRequestUpdateMonitoringState(testSlapOSMixin):
self.assertEquals(None,
support_request.SupportRequest_updateMonitoringComputerState())
support_request.setDestinationDecisionValue(self._makePerson())
support_request.setDestinationDecisionValue(self.makePerson(user=0))
expected_text = """Visited by SupportRequest_trySendNotificationMessage Computer is contacting again Suspending this ticket as the computer contacted again. %s""" % support_request.getDestinationDecision()
self.assertEquals(expected_text,
support_request.SupportRequest_updateMonitoringComputerState())
......@@ -3633,7 +3382,7 @@ class TestSupportRequestUpdateMonitoringState(testSlapOSMixin):
self.assertEquals(None,
support_request.SupportRequest_updateMonitoringHostingSubscriptionState())
support_request.setDestinationDecisionValue(self._makePerson())
support_request.setDestinationDecisionValue(self.makePerson(user=0))
self.assertEquals("Visited by SupportRequest_trySendNotificationMessage Suspending this ticket as the problem is not present anymore Suspending this ticket as the problem is not present anymore. %s" % \
support_request.getDestinationDecision(),
......@@ -3665,7 +3414,7 @@ class TestSupportRequestUpdateMonitoringState(testSlapOSMixin):
hs.getSlapState = getFakeSlapState
self.commit()
support_request.setDestinationDecisionValue(self._makePerson())
support_request.setDestinationDecisionValue(self.makePerson(user=0))
expected_text = """Visited by SupportRequest_trySendNotificationMessage Hosting Subscription was destroyed was destroyed by the user Closing this ticket as the Hosting Subscription was destroyed by the user.
%s""" % support_request.getDestinationDecision()
self.assertEquals(expected_text,
......
......@@ -18,7 +18,7 @@
</role>
<role id='Assignor'>
<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>
<multi_property id='base_category'>destination_decision</multi_property>
</role>
......
......@@ -11,7 +11,6 @@
if obj is None:
return []
portal = obj.getPortalObject()
computer = obj
category_list = []
......@@ -22,10 +21,10 @@ if scope == 'open/public':
elif scope == 'open/personal':
person = computer.getSourceAdministrationValue(portal_type="Person")
if person is not None:
return {"Auditor": ["SHADOW-%s" % person.getReference()]}
return {"Auditor": ["SHADOW-%s" % person.getUserId()]}
elif scope == 'open/friend':
person_list = computer.getDestinationSectionValueList(portal_type="Person")
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
......@@ -33,6 +33,6 @@ if obj is None:
person = obj.getDestinationSectionValue(portal_type="Person")
if person is not None:
for base_category in base_category_list:
return {"Auditor": ["SHADOW-%s" % person.getReference()]}
return {"Auditor": ["SHADOW-%s" % person.getUserId()]}
return category_list
......@@ -33,6 +33,6 @@ if obj is None:
person = obj.getDestinationSectionValue(portal_type="Person")
if person is not None:
for base_category in base_category_list:
return {"Assignee": ["SHADOW-%s" % person.getReference()]}
return {"Assignee": ["SHADOW-%s" % person.getUserId()]}
return category_list
......@@ -20,9 +20,7 @@ The parameters are
NOTE: for now, this script requires proxy manager
"""
category_list = []
if obj is None:
return []
return {'Auditor': ['SHADOW-%s' % obj.getReference()]}
return {'Auditor': ['SHADOW-%s' % obj.getUserId()]}
......@@ -6,6 +6,7 @@
##############################################################################
from erp5.component.test.testSlapOSCloudSecurityGroup import TestSlapOSSecurityMixin
from Products.SlapOS.tests.testSlapOSMixin import changeSkin
import re
import xml_marshaller
from AccessControl.SecurityManagement import getSecurityManager, \
......@@ -13,21 +14,6 @@ from AccessControl.SecurityManagement import getSecurityManager, \
from DateTime import DateTime
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):
def joinSlapOS(self, web_site, reference):
def findMessage(email, body):
......@@ -151,7 +137,7 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin):
))
sm = getSecurityManager()
try:
self.login(computer.getReference())
self.login(computer.getUserId())
self.portal.portal_slap.loadComputerConfigurationFromXML(
xml_marshaller.xml_marshaller.dumps(computer_dict))
self.tic()
......@@ -162,9 +148,9 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin):
def simulateSlapgridSR(self, computer):
sm = getSecurityManager()
computer_reference = computer.getReference()
computer_user_id = computer.getUserId()
try:
self.login(computer_reference)
self.login(computer_user_id)
computer_xml = self.portal.portal_slap.getFullComputerInformation(
computer_id=computer.getReference())
slap_computer = xml_marshaller.xml_marshaller.loads(computer_xml)
......@@ -184,9 +170,9 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin):
def simulateSlapgridUR(self, computer):
sm = getSecurityManager()
computer_reference = computer.getReference()
computer_user_id = computer.getUserId()
try:
self.login(computer_reference)
self.login(computer_user_id)
computer_xml = self.portal.portal_slap.getFullComputerInformation(
computer_id=computer.getReference())
slap_computer = xml_marshaller.xml_marshaller.loads(computer_xml)
......@@ -214,8 +200,9 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin):
def simulateSlapgridCP(self, computer):
sm = getSecurityManager()
computer_reference = computer.getReference()
computer_user_id = computer.getUserId()
try:
self.login(computer_reference)
self.login(computer_user_id)
computer_xml = self.portal.portal_slap.getFullComputerInformation(
computer_id=computer.getReference())
slap_computer = xml_marshaller.xml_marshaller.loads(computer_xml)
......@@ -229,9 +216,13 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin):
url_1 = 'http://%s/' % ip_list[0][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()
try:
self.login(instance_reference)
self.login(instance_user_id)
self.portal.portal_slap.setComputerPartitionConnectionXml(
computer_id=computer_reference,
computer_partition_id=partition._partition_id,
......@@ -314,10 +305,11 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin):
portal_type='Internet Protocol Address')],
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):
self.login(person_reference)
self.login(person_user_id)
self.personRequestInstanceNotReady(
software_release=software_release,
software_type=software_type,
......@@ -333,10 +325,11 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin):
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):
self.login(person_reference)
self.login(person_user_id)
self.personRequestInstanceNotReady(
software_release=software_release,
software_type=software_type,
......@@ -723,19 +716,21 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin):
friend_instance_type, friend_server)
# now deallocate the slaves
self.checkSlaveInstanceUnallocation(public_reference,
public_slave_instance_title, friend_server_software,
self.checkSlaveInstanceUnallocation(public_person.getUserId(),
public_reference, public_slave_instance_title, friend_server_software,
friend_instance_type, friend_server)
self.checkSlaveInstanceUnallocation(friend_reference,
friend_slave_instance_title, public_server_software,
self.checkSlaveInstanceUnallocation(friend_person.getUserId(),
friend_reference, friend_slave_instance_title, public_server_software,
public_instance_type, public_server)
# 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)
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)
# and uninstall some software on them
......
......@@ -46,8 +46,8 @@
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple>
<string>W: 38, 4: Unused variable \'credential_request_form\' (unused-variable)</string>
<string>W:872, 4: Unused variable \'credential_request_form\' (unused-variable)</string>
<string>W: 24, 4: Unused variable \'credential_request_form\' (unused-variable)</string>
<string>W:859, 4: Unused variable \'credential_request_form\' (unused-variable)</string>
</tuple>
</value>
</item>
......
# Copyright (c) 2012 Nexedi SA and Contributors. All Rights Reserved.
from Products.SlapOS.tests.testSlapOSMixin import testSlapOSMixin
from AccessControl import getSecurityManager
import transaction
class TestSlapOSGroupRoleSecurityMixin(testSlapOSMixin):
abort_transaction = 1
def afterSetUp(self):
super(TestSlapOSGroupRoleSecurityMixin, self).afterSetUp()
self.user_id = getSecurityManager().getUser().getId()
def beforeTearDown(self):
transaction.abort()
def changeOwnership(self, document):
""" Change the ownership of the document to the right and
expected user. Normally the user which setups the site.
......@@ -71,9 +69,10 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin):
computer = self.portal.computer_module.newContent(portal_type='Computer')
computer.updateLocalRolesOnSecurityGroups()
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, self.user_id, ['Owner'])
self.assertRoles(computer, computer.getUserId(), ['Assignor'])
def test_ComputerAgent(self):
reference = 'TESTPERSON-%s' % self.generateNewId()
......@@ -83,9 +82,10 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin):
source_administration=person.getRelativeUrl())
computer.updateLocalRolesOnSecurityGroups()
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, self.user_id, ['Owner'])
self.assertRoles(computer, computer.getUserId(), ['Assignor'])
def test_AllocationScope(self):
computer = self.portal.computer_module.newContent(portal_type='Computer')
......@@ -94,9 +94,10 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin):
computer.edit(allocation_scope='open/public')
computer.updateLocalRolesOnSecurityGroups()
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, self.user_id, ['Owner'])
self.assertRoles(computer, computer.getUserId(), ['Assignor'])
# open/personal
reference = 'TESTPERSON-%s' % self.generateNewId()
......@@ -106,11 +107,14 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin):
source_administration=person.getRelativeUrl()
)
computer.updateLocalRolesOnSecurityGroups()
shadow_reference = 'SHADOW-%s' % reference
shadow_user_id = 'SHADOW-%s' % person.getUserId()
self.assertSecurityGroup(computer,
[self.user_id, 'G-COMPANY', shadow_reference, person.getUserId()], False)
self.assertRoles(computer, shadow_reference, ['Auditor'])
[self.user_id, 'G-COMPANY', shadow_user_id,
person.getUserId(), computer.getUserId()], False)
self.assertRoles(computer, shadow_user_id, ['Auditor'])
self.assertRoles(computer, self.user_id, ['Owner'])
self.assertRoles(computer, computer.getUserId(), ['Assignor'])
# open/friend
friend_reference = 'TESTPERSON-%s' % self.generateNewId()
......@@ -120,11 +124,14 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin):
destination_section=friend_person.getRelativeUrl()
)
computer.updateLocalRolesOnSecurityGroups()
shadow_friend_reference = 'SHADOW-%s' % friend_reference
shadow_friend_user_id = 'SHADOW-%s' % friend_person.getUserId()
self.assertSecurityGroup(computer,
[self.user_id, 'G-COMPANY', shadow_friend_reference, person.getUserId()], False)
self.assertRoles(computer, shadow_friend_reference, ['Auditor'])
[self.user_id, 'G-COMPANY', shadow_friend_user_id,
person.getUserId(), computer.getUserId()], False)
self.assertRoles(computer, shadow_friend_user_id, ['Auditor'])
self.assertRoles(computer, self.user_id, ['Owner'])
self.assertRoles(computer, computer.getUserId(), ['Assignor'])
def test_selfComputer(self):
reference = 'TESTCOMP-%s' % self.generateNewId()
......@@ -132,8 +139,8 @@ class TestComputer(TestSlapOSGroupRoleSecurityMixin):
reference=reference)
computer.updateLocalRolesOnSecurityGroups()
self.assertSecurityGroup(computer,
[self.user_id, 'G-COMPANY', reference], False)
self.assertRoles(computer, reference, ['Assignor'])
[self.user_id, 'G-COMPANY', computer.getUserId()], False)
self.assertRoles(computer, computer.getUserId(), ['Assignor'])
self.assertRoles(computer, self.user_id, ['Owner'])
class TestComputerModel(TestSlapOSGroupRoleSecurityMixin):
......@@ -602,11 +609,11 @@ class TestSlaveInstance(TestSlapOSGroupRoleSecurityMixin):
portal_type='Slave Instance', aggregate=partition.getRelativeUrl())
instance.updateLocalRolesOnSecurityGroups()
self.assertSecurityGroup(instance, ['G-COMPANY', provider_reference,
computer_reference, self.user_id], False)
self.assertSecurityGroup(instance, ['G-COMPANY', provider.getUserId(),
computer.getUserId(), self.user_id], False)
self.assertRoles(instance, 'G-COMPANY', ['Assignor'])
self.assertRoles(instance, provider_reference, ['Assignor'])
self.assertRoles(instance, computer_reference, ['Assignor'])
self.assertRoles(instance, provider.getUserId(), ['Assignor'])
self.assertRoles(instance, computer.getUserId(), ['Assignor'])
self.assertRoles(instance, self.user_id, ['Owner', 'Assignee'])
test_Computer = test_SoftwareInstanceWhichProvidesThisSlaveInstance
......@@ -636,9 +643,9 @@ class TestSoftwareInstallation(TestSlapOSGroupRoleSecurityMixin):
installation.updateLocalRolesOnSecurityGroups()
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, computer_reference, ['Assignor'])
self.assertRoles(installation, computer.getUserId(), ['Assignor'])
self.assertRoles(installation, self.user_id, ['Owner', 'Assignee'])
def test_ProviderOfTheInstallation(self):
......@@ -717,10 +724,10 @@ class TestSoftwareInstance(TestSlapOSGroupRoleSecurityMixin):
portal_type='Software Instance', aggregate=partition.getRelativeUrl())
instance.updateLocalRolesOnSecurityGroups()
self.assertSecurityGroup(instance, ['G-COMPANY', computer_reference,
self.assertSecurityGroup(instance, ['G-COMPANY', computer.getUserId(),
self.user_id], False)
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'])
class TestSoftwareInstanceModule(TestSlapOSGroupRoleSecurityMixin):
......@@ -970,11 +977,11 @@ class TestPaymentTransaction(TestSlapOSGroupRoleSecurityMixin):
destination_section_value=person,
)
product.updateLocalRolesOnSecurityGroups()
shadow_reference = 'SHADOW-%s' % reference
shadow_user_id = 'SHADOW-%s' % person.getUserId()
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, shadow_reference, ['Auditor'])
self.assertRoles(product, shadow_user_id, ['Auditor'])
self.assertRoles(product, person.getUserId(), ['Auditor'])
self.assertRoles(product, self.user_id, ['Owner'])
......@@ -988,11 +995,11 @@ class TestPaymentTransaction(TestSlapOSGroupRoleSecurityMixin):
destination_section_value=person,
)
product.updateLocalRolesOnSecurityGroups()
shadow_reference = 'SHADOW-%s' % reference
shadow_user_id = 'SHADOW-%s' % person.getUserId()
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, shadow_reference, ['Auditor'])
self.assertRoles(product, shadow_user_id, ['Auditor'])
self.assertRoles(product, person.getUserId(), ['Auditor'])
self.assertRoles(product, self.user_id, ['Owner'])
......@@ -1973,11 +1980,11 @@ class TestPayzenEvent(TestSlapOSGroupRoleSecurityMixin):
destination_section_value=person,
)
product.updateLocalRolesOnSecurityGroups()
shadow_reference = 'SHADOW-%s' % reference
shadow_user_id = 'SHADOW-%s' % person.getUserId()
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, shadow_reference, ['Assignee'])
self.assertRoles(product, shadow_user_id, ['Assignee'])
self.assertRoles(product, self.user_id, ['Owner'])
class TestSecurePaymentTool(TestSlapOSGroupRoleSecurityMixin):
......
# Copyright (c) 2002-2012 Nexedi SA and Contributors. All Rights Reserved.
from erp5.component.test.testSlapOSERP5GroupRoleSecurity import TestSlapOSGroupRoleSecurityMixin
import transaction
class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
TestSlapOSGroupRoleSecurityMixin):
......@@ -22,7 +21,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(model, ['G-COMPANY', self.user_id], False)
model.edit(source_administration=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(model,
['G-COMPANY', self.user_id, self.person_user_id], False)
......@@ -35,55 +34,56 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
'R-SHADOW-PERSON'], False)
network.edit(source_administration=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(network,
['G-COMPANY', self.user_id, self.person_user_id, 'R-SHADOW-PERSON'],
False)
def test_Computer_setReference(self):
def test_Computer_setUserId(self):
computer = self.portal.computer_module.newContent(portal_type='Computer')
self.assertSecurityGroup(computer, ['G-COMPANY', self.user_id], False)
self.assertSecurityGroup(computer, ['G-COMPANY', self.user_id, computer.getUserId()], False)
computer.edit(reference='TESTCOMP-%s' % self.generateNewId())
transaction.commit()
computer.edit(user_id=None)
self.commit()
self.assertSecurityGroup(computer, ['G-COMPANY', self.user_id,
computer.getReference()], False)
self.assertSecurityGroup(computer, ['G-COMPANY', self.user_id], False)
def test_Computer_setSourceAdministration(self):
self._makePerson()
computer = self.portal.computer_module.newContent(
portal_type='Computer')
self.assertSecurityGroup(computer, ['G-COMPANY', self.user_id], False)
self.assertSecurityGroup(computer, ['G-COMPANY', self.user_id, computer.getUserId()], False)
computer.edit(source_administration=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(computer, ['G-COMPANY', self.user_id,
self.person_user_id], False)
self.person_user_id, computer.getUserId()], False)
def test_Computer_setAllocationScope(self):
computer = self.portal.computer_module.newContent(portal_type='Computer')
self.assertSecurityGroup(computer, ['G-COMPANY', self.user_id], False)
self.assertSecurityGroup(computer, ['G-COMPANY', self.user_id,
computer.getUserId()], False)
computer.edit(allocation_scope='open/public')
transaction.commit()
self.commit()
self.assertSecurityGroup(computer, ['G-COMPANY', self.user_id,
'R-SHADOW-PERSON'], False)
'R-SHADOW-PERSON', computer.getUserId()], False)
def test_Computer_setDestinationSection(self):
self._makePerson()
computer = self.portal.computer_module.newContent(
portal_type='Computer')
self.assertSecurityGroup(computer, ['G-COMPANY', self.user_id], False)
self.assertSecurityGroup(computer, ['G-COMPANY', self.user_id,
computer.getUserId()], False)
computer.edit(source_administration=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(computer, ['G-COMPANY', self.user_id,
self.person_user_id], False)
self.person_user_id, computer.getUserId()], False)
def test_Computer_reindexObject(self):
computer = self.portal.computer_module.template_computer\
......@@ -118,7 +118,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
False)
hosting_subscription.edit(reference='TESTHS-%s' % self.generateNewId())
transaction.commit()
self.commit()
self.assertSecurityGroup(hosting_subscription, [self.user_id,
hosting_subscription.getReference(), 'G-COMPANY'], False)
......@@ -133,7 +133,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
hosting_subscription.edit(
destination_section=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(hosting_subscription, [self.user_id,
hosting_subscription.getId(), self.person_user.getUserId(),
......@@ -148,7 +148,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(person, [self.user_id, 'G-COMPANY'], False)
person.edit(reference='TESTPER-%s' % self.generateNewId())
transaction.commit()
self.commit()
self.assertSecurityGroup(person, [self.user_id, 'G-COMPANY'], False)
......@@ -157,10 +157,10 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(person, [self.user_id, 'G-COMPANY'], False)
person.newContent(portal_type="ERP5 Login")
transaction.commit()
self.commit()
self.assertSecurityGroup(person, [self.user_id, 'G-COMPANY',
person.getUserId(), 'SHADOW-%s' % person.getReference()], False)
person.getUserId(), 'SHADOW-%s' % person.getUserId()], False)
def test_SoftwareInstallation_setAggregate(self):
installation = self.portal.software_installation_module.newContent(
......@@ -171,10 +171,10 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
reference='TESTC-%s' % self.generateNewId())
installation.edit(aggregate=computer.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(installation, [self.user_id, 'G-COMPANY',
computer.getReference()], False)
computer.getUserId()], False)
def test_SoftwareInstallation_setDestinationSection(self):
......@@ -185,7 +185,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self._makePerson()
installation.edit(destination_section=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(installation, [self.user_id, 'G-COMPANY',
self.person_user.getUserId()], False)
......@@ -200,7 +200,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
portal_type='Hosting Subscription', reference='TESTHS-%s' %
self.generateNewId())
software_instance.edit(specialise=hosting_subscription.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(software_instance, [self.user_id, 'G-COMPANY',
hosting_subscription.getReference()], False)
......@@ -227,7 +227,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.tic()
self.assertSecurityGroup(software_instance, [self.user_id, 'G-COMPANY',
computer.getReference(), hosting_subscription.getReference()], False)
computer.getUserId(), hosting_subscription.getReference()], False)
self.assertSecurityGroup(partition, [self.user_id,
hosting_subscription.getReference()], True)
......@@ -241,7 +241,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
portal_type='Hosting Subscription', reference='TESTHS-%s' %
self.generateNewId())
slave_instance.edit(specialise=hosting_subscription.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(slave_instance, [self.user_id, 'G-COMPANY',
hosting_subscription.getReference()], False)
......@@ -273,7 +273,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
slave_instance.edit(aggregate=partition.getRelativeUrl())
self.assertSecurityGroup(slave_instance, [self.user_id, 'G-COMPANY',
software_instance.getReference(), computer.getReference(),
software_instance.getUserId(), computer.getUserId(),
hosting_subscription.getReference()], False)
def test_PaymentTransaction_setDestinationSection(self):
......@@ -286,10 +286,10 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
payment_transaction.edit(
destination_section=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(payment_transaction, [self.user_id,
'G-COMPANY', 'SHADOW-%s' % self.person_user.getReference(),
'G-COMPANY', 'SHADOW-%s' % self.person_user.getUserId(),
self.person_user.getUserId()],
False)
......@@ -303,10 +303,10 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
payment_transaction.edit(
destination_section=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(payment_transaction, [self.user_id,
'G-COMPANY', 'SHADOW-%s' % self.person_user.getReference()],
'G-COMPANY', 'SHADOW-%s' % self.person_user.getUserId()],
False)
def test_IntegrationSite_reindexObject(self):
......@@ -344,7 +344,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
sale_invoice_transaction.edit(
destination_section=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(sale_invoice_transaction, [self.user_id,
'G-COMPANY', self.person_user.getUserId()],
......@@ -357,7 +357,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(support_request, ['G-COMPANY', self.user_id], False)
support_request.edit(destination_decision=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(support_request, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -369,7 +369,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(regularisation_request, ['G-COMPANY', self.user_id], False)
regularisation_request.edit(destination_decision=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(regularisation_request, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -381,7 +381,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(destination=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -393,7 +393,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(source=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -405,7 +405,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(destination=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -417,7 +417,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(source=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -429,7 +429,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(destination=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -441,7 +441,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(source=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -453,7 +453,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(destination=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -465,7 +465,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(source=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -477,7 +477,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(destination=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -489,7 +489,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(source=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -501,7 +501,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(destination=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -513,7 +513,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(source=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -525,7 +525,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(destination=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -537,7 +537,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(source=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -549,7 +549,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(destination=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -561,7 +561,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(source=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -573,7 +573,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(destination=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -585,7 +585,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(source=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -597,7 +597,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(destination=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -609,7 +609,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id], False)
event.edit(source=self.person_user.getRelativeUrl())
transaction.commit()
self.commit()
self.assertSecurityGroup(event, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -623,7 +623,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
sale_packing_list.edit(
specialise="sale_trade_condition_module/slapos_subscription_trade_condition")
transaction.commit()
self.commit()
self.assertSecurityGroup(sale_packing_list, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -637,7 +637,7 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
sale_packing_list.edit(
destination_decision_value=self.person_user)
transaction.commit()
self.commit()
self.assertSecurityGroup(sale_packing_list, ['G-COMPANY', self.user_id,
self.person_user_id], False)
......@@ -56,7 +56,7 @@
<key> <string>method_id</string> </key>
<value>
<list>
<string>_setReference</string>
<string>_setUserId.*</string>
<string>_setSourceAdministration.*</string>
<string>_setAllocationScope.*</string>
<string>_setDestinationSection.*</string>
......@@ -75,6 +75,12 @@
</list>
</value>
</item>
<item>
<key> <string>portal_type_group_filter</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>script_name</string> </key>
<value>
......
......@@ -2,11 +2,9 @@
# Copyright (c) 2002-2013 Nexedi SA and Contributors. All Rights Reserved.
import transaction
from Products.SlapOS.tests.testSlapOSMixin import \
testSlapOSMixin
testSlapOSMixin, changeSkin, simulate
from zExceptions import Unauthorized
from Products.ERP5Type.tests.utils import createZODBPythonScript
from unittest import skip
from functools import wraps
from ZPublisher.HTTPRequest import HTTPRequest
from ZPublisher.HTTPResponse import HTTPResponse
......@@ -14,40 +12,6 @@ from ZPublisher.HTTPResponse import HTTPResponse
import json
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={}):
__version__ = "0.1"
env={}
......@@ -177,18 +141,7 @@ class TestSlapOSHypermediaMixin(testSlapOSMixin):
transaction.abort()
def _makePerson(self):
new_id = self.generateNewId()
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()
person_user = self.makePerson()
self.tic()
self.changeSkin('Hal')
return person_user
......@@ -368,7 +321,7 @@ class TestSlapOSBase_getHateoasMaster(TestSlapOSHypermediaMixin):
@changeSkin('Hal')
def test_getHateoasMaster_instance_result(self):
self._makeTree()
self.login(self.software_instance.getReference())
self.login(self.software_instance.getUserId())
self.changeSkin('Hal')
fake_request = do_fake_request("GET")
result = self.portal.Base_getHateoasMaster(REQUEST=fake_request)
......@@ -716,6 +669,7 @@ class TestSlapOSInstance_getHateoasNews(TestSlapOSHypermediaMixin):
sla_xml=self.generateSafeXml(),
connection_xml=self.generateSafeXml(),
)
self._addERP5Login(instance)
self.tic()
return instance
......@@ -803,6 +757,7 @@ class TestSlapOSInstance_getHateoasRelatedHostingSubscription(TestSlapOSHypermed
sla_xml=self.generateSafeXml(),
connection_xml=self.generateSafeXml(),
)
self._addERP5Login(instance)
self.tic()
return instance
......@@ -893,6 +848,7 @@ class TestSlapOSInstance_getHateoasInformation(TestSlapOSHypermediaMixin):
sla_xml=self.generateSafeXml(),
connection_xml=self.generateSafeXml(),
)
self._addERP5Login(instance)
self.tic()
return instance
......
......@@ -27,28 +27,9 @@
##############################################################################
import transaction
from functools import wraps
from Products.SlapOS.tests.testSlapOSMixin import testSlapOSMixin
from Products.ERP5Type.tests.utils import createZODBPythonScript
from Products.SlapOS.tests.testSlapOSMixin import testSlapOSMixin, simulate
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):
def afterSetUp(self):
......@@ -77,20 +58,7 @@ class TestSlapOSPDMSkins(testSlapOSMixin):
def _makePerson(self):
# Clone person document
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()
person_user = self.makePerson(new_id=self.new_id)
return person_user
def _makeComputer(self):
......
......@@ -3,7 +3,7 @@ from AccessControl.SecurityManagement import getSecurityManager, \
setSecurityManager, newSecurityManager
@UnrestrictedMethod
def getComputerReference(item):
def getComputerReferenceAndUserId(item):
portal_type = item.getPortalType()
computer = None
......@@ -17,20 +17,28 @@ def getComputerReference(item):
computer = partition.getParentValue()
if computer is not None and computer.getValidationState() == 'validated':
return computer.getReference()
return None
return computer.getReference(), computer.getUserId()
return None, None
def Item_activateFillComputerInformationCache(state_change):
item = state_change['object']
portal = item.getPortalObject()
computer_reference = getComputerReference(item)
computer_reference, user_id = getComputerReferenceAndUserId(item)
if computer_reference is 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()
try:
newSecurityManager(None,
portal.acl_users.getUserById(computer_reference))
newSecurityManager(None, user)
portal.portal_slap._activateFillComputerInformationCache(
computer_reference, computer_reference)
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>
......@@ -54,9 +54,12 @@ class TestSlapOSSlapToolMixin(testSlapOSMixin):
self.computer.validate()
self._addERP5Login(self.computer)
self.tic()
self.computer_id = self.computer.getReference()
self.computer_user_id = self.computer.getUserId()
self.pinDateTime(DateTime())
def beforeTearDown(self):
......@@ -74,7 +77,7 @@ class TestSlapOSSlapToolComputerAccess(TestSlapOSSlapToolMixin):
partition_3_root_instance_title = self.computer.partition3.getAggregateRelatedValue(
portal_type='Software Instance').getSpecialiseValue().getTitle()
self.login(self.computer_id)
self.login(self.computer_user_id)
response = self.portal_slap.getFullComputerInformation(self.computer_id)
self.assertEqual(200, response.status)
self.assertEqual('public, max-age=1, stale-if-error=604800',
......@@ -85,7 +88,6 @@ class TestSlapOSSlapToolComputerAccess(TestSlapOSSlapToolMixin):
self.assertEqual('text/xml; charset=utf-8',
response.headers.get('content-type'))
# check returned XML
xml_fp = StringIO.StringIO()
......@@ -433,7 +435,7 @@ class TestSlapOSSlapToolComputerAccess(TestSlapOSSlapToolMixin):
self.portal_slap.getComputerInformation.im_func.func_name)
def test_not_accessed_getComputerStatus(self):
self.login(self.computer_id)
self.login(self.computer_user_id)
created_at = rfc1123_date(DateTime())
response = self.portal_slap.getComputerStatus(self.computer_id)
self.assertEqual(200, response.status)
......@@ -472,7 +474,7 @@ class TestSlapOSSlapToolComputerAccess(TestSlapOSSlapToolMixin):
'\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
def test_accessed_getComputerStatus(self):
self.login(self.computer_id)
self.login(self.computer_user_id)
self.portal_slap.getFullComputerInformation(self.computer_id)
created_at = rfc1123_date(DateTime())
......@@ -525,7 +527,7 @@ class TestSlapOSSlapToolComputerAccess(TestSlapOSSlapToolMixin):
self._makeComplexComputer()
self.computer_bang_simulator = tempfile.mkstemp()[1]
try:
self.login(self.computer_id)
self.login(self.computer_user_id)
self.computer.reportComputerBang = Simulator(
self.computer_bang_simulator, 'reportComputerBang')
error_log = 'Please bang me'
......@@ -574,7 +576,7 @@ class TestSlapOSSlapToolComputerAccess(TestSlapOSSlapToolMixin):
def test_loadComputerConfigurationFromXML(self):
self.computer_load_configuration_simulator = tempfile.mkstemp()[1]
try:
self.login(self.computer_id)
self.login(self.computer_user_id)
self.computer.Computer_updateFromDict = Simulator(
self.computer_load_configuration_simulator, 'Computer_updateFromDict')
......@@ -600,7 +602,7 @@ class TestSlapOSSlapToolComputerAccess(TestSlapOSSlapToolMixin):
def test_not_accessed_getSoftwareInstallationStatus(self):
self._makeComplexComputer()
self.computer_bang_simulator = tempfile.mkstemp()[1]
self.login(self.computer_id)
self.login(self.computer_user_id)
created_at = rfc1123_date(DateTime())
software_installation = self.start_requested_software_installation
url_string = software_installation.getUrlString()
......@@ -643,14 +645,14 @@ class TestSlapOSSlapToolComputerAccess(TestSlapOSSlapToolMixin):
def test_destroyedSoftwareRelease_noSoftwareInstallation(self):
self.login(self.computer_id)
self.login(self.computer_user_id)
self.assertRaises(NotFound,
self.portal_slap.destroyedSoftwareRelease,
"http://example.org/foo", self.computer_id)
def test_destroyedSoftwareRelease_noDestroyRequested(self):
self._makeComplexComputer()
self.login(self.computer_id)
self.login(self.computer_user_id)
self.assertRaises(NotFound,
self.portal_slap.destroyedSoftwareRelease,
self.start_requested_software_installation.getUrlString(),
......@@ -658,7 +660,7 @@ class TestSlapOSSlapToolComputerAccess(TestSlapOSSlapToolMixin):
def test_destroyedSoftwareRelease_destroyRequested(self):
self._makeComplexComputer()
self.login(self.computer_id)
self.login(self.computer_user_id)
destroy_requested = self.destroy_requested_software_installation
self.assertEquals(destroy_requested.getValidationState(), "validated")
self.portal_slap.destroyedSoftwareRelease(
......@@ -668,7 +670,7 @@ class TestSlapOSSlapToolComputerAccess(TestSlapOSSlapToolMixin):
def test_availableSoftwareRelease(self):
self._makeComplexComputer()
self.computer_bang_simulator = tempfile.mkstemp()[1]
self.login(self.computer_id)
self.login(self.computer_user_id)
software_installation = self.start_requested_software_installation
url_string = software_installation.getUrlString()
response = self.portal_slap.availableSoftwareRelease(
......@@ -707,7 +709,7 @@ class TestSlapOSSlapToolComputerAccess(TestSlapOSSlapToolMixin):
def test_buildingSoftwareRelease(self):
self._makeComplexComputer()
self.computer_bang_simulator = tempfile.mkstemp()[1]
self.login(self.computer_id)
self.login(self.computer_user_id)
software_installation = self.start_requested_software_installation
url_string = software_installation.getUrlString()
response = self.portal_slap.buildingSoftwareRelease(
......@@ -746,7 +748,7 @@ class TestSlapOSSlapToolComputerAccess(TestSlapOSSlapToolMixin):
def test_softwareReleaseError(self):
self._makeComplexComputer()
self.computer_bang_simulator = tempfile.mkstemp()[1]
self.login(self.computer_id)
self.login(self.computer_user_id)
software_installation = self.start_requested_software_installation
url_string = software_installation.getUrlString()
response = self.portal_slap.softwareReleaseError(
......@@ -783,7 +785,7 @@ class TestSlapOSSlapToolComputerAccess(TestSlapOSSlapToolMixin):
'\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
def test_useComputer_wrong_xml(self):
self.login(self.computer_id)
self.login(self.computer_user_id)
response = self.portal_slap.useComputer(
self.computer_id, "foobar")
self.assertEqual(400, response.status)
......@@ -799,7 +801,7 @@ class TestSlapOSSlapToolComputerAccess(TestSlapOSSlapToolMixin):
def test_useComputer_expected_xml(self):
self.computer_use_computer_simulator = tempfile.mkstemp()[1]
try:
self.login(self.computer_id)
self.login(self.computer_user_id)
self.computer.Computer_reportComputerConsumption = Simulator(
self.computer_use_computer_simulator,
'Computer_reportComputerConsumption')
......@@ -843,7 +845,7 @@ class TestSlapOSSlapToolComputerAccess(TestSlapOSSlapToolMixin):
def test_useComputer_empty_reference(self):
self.computer_use_computer_simulator = tempfile.mkstemp()[1]
try:
self.login(self.computer_id)
self.login(self.computer_user_id)
self.computer.Computer_reportComputerConsumption = Simulator(
self.computer_use_computer_simulator,
'Computer_reportComputerConsumption')
......@@ -890,7 +892,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
self._makeComplexComputer()
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
response = self.portal_slap.getComputerPartitionCertificate(self.computer_id,
partition_id)
self.assertEqual(200, response.status)
......@@ -927,7 +929,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
def test_getFullComputerInformation(self):
self._makeComplexComputer(with_slave=True)
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
response = self.portal_slap.getFullComputerInformation(self.computer_id)
self.assertEqual(200, response.status)
self.assertEqual('public, max-age=1, stale-if-error=604800',
......@@ -1070,7 +1072,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
created_at = rfc1123_date(DateTime())
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
response = self.portal_slap.getComputerPartitionStatus(self.computer_id,
partition_id)
self.assertEqual(200, response.status)
......@@ -1112,7 +1114,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
created_at = rfc1123_date(DateTime())
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
self.portal_slap.registerComputerPartition(self.computer_id, partition_id)
response = self.portal_slap.getComputerPartitionStatus(self.computer_id,
partition_id)
......@@ -1156,7 +1158,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
self._makeComplexComputer(with_slave=True)
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
response = self.portal_slap.registerComputerPartition(self.computer_id, partition_id)
self.assertEqual(200, response.status)
self.assertEqual( 'public, max-age=1, stale-if-error=604800',
......@@ -1288,7 +1290,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
self._makeComplexComputer()
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
response = self.portal_slap.registerComputerPartition(self.computer_id, partition_id)
self.assertEqual(200, response.status)
self.assertEqual( 'public, max-age=1, stale-if-error=604800',
......@@ -1424,7 +1426,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<parameter id="p2é">v2é</parameter>
</instance>
"""
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
self.instance_update_connection_simulator = tempfile.mkstemp()[1]
try:
......@@ -1457,7 +1459,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
<parameter id="p2é">v2é</parameter>
</instance>
"""
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
self.instance_update_connection_simulator = tempfile.mkstemp()[1]
try:
......@@ -1476,7 +1478,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
self._makeComplexComputer()
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
error_log = 'The error'
response = self.portal_slap.softwareInstanceError(self.computer_id,
partition_id, error_log)
......@@ -1524,7 +1526,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
try:
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
self.start_requested_software_instance.bang = Simulator(
self.instance_bang_simulator, 'bang')
error_log = 'Please bang me'
......@@ -1577,7 +1579,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
try:
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
self.start_requested_software_instance.rename = Simulator(
self.instance_rename_simulator, 'rename')
new_name = 'new me'
......@@ -1595,7 +1597,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
self._makeComplexComputer()
partition_id = self.destroy_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
self.login(self.destroy_requested_software_instance.getReference())
self.login(self.destroy_requested_software_instance.getUserId())
response = self.portal_slap.destroyedComputerPartition(self.computer_id,
partition_id)
self.assertEqual('None', response)
......@@ -1617,7 +1619,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
try:
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
self.start_requested_software_instance.requestInstance = Simulator(
self.instance_request_simulator, 'requestInstance')
response = self.portal_slap.requestComputerPartition(
......@@ -1652,7 +1654,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
try:
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
self.start_requested_software_instance.requestInstance = Simulator(
self.instance_request_simulator, 'requestInstance')
response = self.portal_slap.requestComputerPartition(
......@@ -1686,7 +1688,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
# Atach two software instances
instance_kw = dict(
......@@ -1738,7 +1740,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
# Atach one software instance
instance_kw = dict(
......@@ -1771,7 +1773,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
self.assertEqual([],
self.start_requested_software_instance.getPredecessorTitleList())
......@@ -1802,7 +1804,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
self._makeComplexComputer()
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
response = self.portal_slap.availableComputerPartition(self.computer_id,
partition_id)
self.assertEqual('None', response)
......@@ -1839,7 +1841,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
self._makeComplexComputer()
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
response = self.portal_slap.buildingComputerPartition(self.computer_id,
partition_id)
self.assertEqual('None', response)
......@@ -1876,7 +1878,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
self._makeComplexComputer()
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
response = self.portal_slap.stoppedComputerPartition(self.computer_id,
partition_id)
self.assertEqual('None', response)
......@@ -1913,7 +1915,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
self._makeComplexComputer()
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
response = self.portal_slap.startedComputerPartition(self.computer_id,
partition_id)
self.assertEqual('None', response)
......@@ -2136,6 +2138,7 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
title=reference,
reference=reference, password=password)
person.newContent(portal_type='Assignment', role='member').open()
person.newContent(portal_type='ERP5 Login', reference=reference).validate()
transaction.commit()
person.recursiveImmediateReindexObject()
......@@ -2184,7 +2187,7 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
'\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
def test_accessed_getComputerStatus(self):
self.login(self.computer_id)
self.login(self.computer_user_id)
self.portal_slap.getFullComputerInformation(self.computer_id)
self.login(self.person_user_id)
created_at = rfc1123_date(DateTime())
......@@ -2281,7 +2284,7 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
created_at = rfc1123_date(DateTime())
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
response = self.portal_slap.getComputerPartitionStatus(self.computer_id,
partition_id)
self.assertEqual(200, response.status)
......@@ -2324,7 +2327,7 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
partition_id = self.start_requested_software_instance.getAggregateValue(
portal_type='Computer Partition').getReference()
created_at = rfc1123_date(DateTime())
self.login(self.start_requested_software_instance.getReference())
self.login(self.start_requested_software_instance.getUserId())
self.portal_slap.registerComputerPartition(self.computer_id, partition_id)
self.login(self.person_user_id)
response = self.portal_slap.getComputerPartitionStatus(self.computer_id,
......
......@@ -48,22 +48,22 @@
<tuple>
<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:517, 13: Use of eval (eval-used)</string>
<string>W:568, 13: Use of eval (eval-used)</string>
<string>W:793, 13: Use of eval (eval-used)</string>
<string>W:1401, 13: Use of eval (eval-used)</string>
<string>W:1514, 13: Use of eval (eval-used)</string>
<string>W:1568, 13: Use of eval (eval-used)</string>
<string>W:1608, 13: Use of eval (eval-used)</string>
<string>W:2132, 2: Arguments number differs from overridden \'afterSetUp\' method (arguments-differ)</string>
<string>W:2229, 13: Use of eval (eval-used)</string>
<string>W:2614, 13: Use of eval (eval-used)</string>
<string>W:2668, 13: Use of eval (eval-used)</string>
<string>W:2695, 13: Use of eval (eval-used)</string>
<string>W:2850, 13: Use of eval (eval-used)</string>
<string>W:2878, 13: Use of eval (eval-used)</string>
<string>W:2927, 13: Use of eval (eval-used)</string>
<string>W:2974, 13: Use of eval (eval-used)</string>
<string>W:519, 13: Use of eval (eval-used)</string>
<string>W:570, 13: Use of eval (eval-used)</string>
<string>W:795, 13: Use of eval (eval-used)</string>
<string>W:1403, 13: Use of eval (eval-used)</string>
<string>W:1516, 13: Use of eval (eval-used)</string>
<string>W:1570, 13: Use of eval (eval-used)</string>
<string>W:1610, 13: Use of eval (eval-used)</string>
<string>W:2134, 2: Arguments number differs from overridden \'afterSetUp\' method (arguments-differ)</string>
<string>W:2231, 13: Use of eval (eval-used)</string>
<string>W:2616, 13: Use of eval (eval-used)</string>
<string>W:2670, 13: Use of eval (eval-used)</string>
<string>W:2697, 13: Use of eval (eval-used)</string>
<string>W:2852, 13: Use of eval (eval-used)</string>
<string>W:2880, 13: Use of eval (eval-used)</string>
<string>W:2929, 13: Use of eval (eval-used)</string>
<string>W:2976, 13: Use of eval (eval-used)</string>
</tuple>
</value>
</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)
......@@ -26,28 +26,13 @@
#
##############################################################################
from zLOG import LOG, PROBLEM, WARNING
from Products.ERP5Type.Globals import InitializeClass
from AccessControl import ClassSecurityInfo
import sys
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Products.PluggableAuthService.PluggableAuthService import \
_SWALLOWABLE_PLUGIN_EXCEPTIONS
from Products.PluggableAuthService.interfaces import plugins
from Products.PluggableAuthService.utils import classImplements
from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin
from Products.ERP5Type.Cache import transactional_cached
from Products import ERP5Security
from ZODB.POSException import ConflictError
from Products.PluggableAuthService.PluggableAuthService import DumbHTTPExtractor
from Products.ERP5Security.ERP5GroupManager import ConsistencyError, NO_CACHE_MODE
from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod
from Products.ERP5Type.ERP5Type \
import ERP5TYPE_SECURITY_GROUP_ID_GENERATION_SCRIPT
from Products.ERP5Type.Cache import CachingMethod
from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery
from Products.ERP5Security.ERP5UserManager import getValidAssignmentList
#Form for new plugin in ZMI
manage_addSlapOSMachineAuthenticationPluginForm = PageTemplateFile(
......@@ -67,39 +52,6 @@ def addSlapOSMachineAuthenticationPlugin(dispatcher, id, title=None, REQUEST=Non
'SlapOSMachineAuthenticationPlugin+added.'
% dispatcher.absolute_url())
@transactional_cached(lambda portal, *args: args)
def getUserByLogin(portal, login):
if isinstance(login, basestring):
login = login,
machine_query = Query(portal_type=["Computer", "Software Instance"],
validation_state="validated",
reference=dict(query=login, key='ExactMatch'))
person_query = Query(portal_type=["Person"],
reference=dict(query=login, key='ExactMatch'))
result = portal.portal_catalog.unrestrictedSearchResults(
query=ComplexQuery(machine_query, person_query,logical_operator="OR"),
select_expression='reference')
result = [x for x in result if \
(x.getPortalType() == 'Person' and x.getValidationState() != 'deleted') or \
(x.getPortalType() in ("Computer", "Software Instance") and \
x.getValidationState() == 'validated')]
# XXX: Here, we filter catalog result list ALTHOUGH we did pass
# parameters to unrestrictedSearchResults to restrict result set.
# This is done because the following values can match person with
# reference "foo":
# "foo " because of MySQL (feature, PADSPACE collation):
# mysql> SELECT reference as r FROM catalog
# -> WHERE reference="foo ";
# +-----+
# | r |
# +-----+
# | foo |
# +-----+
# 1 row in set (0.01 sec)
# "bar OR foo" because of ZSQLCatalog tokenizing searched strings
# by default (feature).
return [x.getObject() for x in result if x['reference'] in login]
class SlapOSMachineAuthenticationPlugin(BasePlugin):
"""
Plugin to authenicate as machines.
......@@ -110,12 +62,9 @@ class SlapOSMachineAuthenticationPlugin(BasePlugin):
def __init__(self, id, title=None):
#Register value
self._setId(id)
self._id = self.id = id
self.title = title
####################################
#ILoginPasswordHostExtractionPlugin#
####################################
security.declarePrivate('extractCredentials')
def extractCredentials(self, request):
""" Extract credentials from the request header. """
......@@ -126,8 +75,9 @@ class SlapOSMachineAuthenticationPlugin(BasePlugin):
getHeader = request.get_header
user_id = getHeader('REMOTE_USER')
if user_id is not None:
creds['machine_login'] = user_id
creds['external_login'] = user_id
creds['remote_host'] = request.get('REMOTE_HOST', '')
creds['login_portal_type'] = "ERP5 Login"
try:
creds['remote_address'] = request.getClientAddr()
except AttributeError:
......@@ -137,218 +87,7 @@ class SlapOSMachineAuthenticationPlugin(BasePlugin):
# fallback to default way
return DumbHTTPExtractor().extractCredentials(request)
################################
# IAuthenticationPlugin #
################################
security.declarePrivate('authenticateCredentials')
def authenticateCredentials(self, credentials):
"""Authentificate with credentials"""
login = credentials.get('machine_login', None)
# Forbidden the usage of the super user.
if login == ERP5Security.SUPER_USER:
return None
#Search the user by his login
user_list = self.getUserByLogin(login)
if len(user_list) != 1:
return None
user = user_list[0]
if user.getPortalType() == 'Person':
if len(getValidAssignmentList(user)) == 0:
return None
return (login, login)
def getUserByLogin(self, login):
# Search the Catalog for login and return a list of person objects
# login can be a string or a list of strings
# (no docstring to prevent publishing)
if not login:
return []
if isinstance(login, list):
login = tuple(login)
elif not isinstance(login, (tuple, str)):
login = login.getUserName()
try:
return getUserByLogin(self.getPortalObject(), login)
except ConflictError:
raise
except:
LOG('SlapOSMachineAuthenticationPlugin', PROBLEM, 'getUserByLogin failed',
error=sys.exc_info())
# Here we must raise an exception to prevent callers from caching
# a result of a degraded situation.
# The kind of exception does not matter as long as it's catched by
# PAS and causes a lookup using another plugin or user folder.
# As PAS does not define explicitely such exception, we must use
# the _SWALLOWABLE_PLUGIN_EXCEPTIONS list.
raise _SWALLOWABLE_PLUGIN_EXCEPTIONS[0]
#################################
# IGroupsPlugin #
#################################
# This is patched version of
# Products.ERP5Security.ERP5GroupManager.ERP5GroupManager.getGroupsForPrincipal
# which allows to treat Computer and Software Instance as loggable user
loggable_portal_type_list = ['Computer', 'Person', 'Software Instance']
@UnrestrictedMethod
def getGroupsForPrincipal(self, principal, request=None):
""" See IGroupsPlugin.
"""
# If this is the super user, skip the check.
if principal.getId() == ERP5Security.SUPER_USER:
return ()
def _getGroupsForPrincipal(user_name, path):
security_category_dict = {} # key is the base_category_list,
# value is the list of fetched categories
security_group_list = []
security_definition_list = ()
try:
# To get the complete list of groups, we try to call the
# ERP5Type_getSecurityCategoryMapping which should return a list
# of lists of two elements (script, base_category_list) like :
# (
# ('script_1', ['base_category_1', 'base_category_2', ...]),
# ('script_2', ['base_category_1', 'base_category_3', ...])
# )
#
# else, if the script does not exist, falls back to a list containng
# only one list :
# (('ERP5Type_getSecurityCategoryFromAssignment',
# self.getPortalAssignmentBaseCategoryList() ),)
mapping_method = getattr(self,
'ERP5Type_getSecurityCategoryMapping', None)
if mapping_method is None:
security_definition_list = ((
'ERP5Type_getSecurityCategoryFromAssignment',
self.getPortalAssignmentBaseCategoryList()
),)
else:
security_definition_list = mapping_method()
# get the loggable document from its reference - no security check needed
catalog_result = self.portal_catalog.unrestrictedSearchResults(
portal_type=self.loggable_portal_type_list,
reference=user_name)
if len(catalog_result) != 1: # we won't proceed with groups
if len(catalog_result) > 1: # configuration is screwed
raise ConsistencyError, 'There is more than one of %s whose \
login is %s : %s' % (','.join(self.loggable_portal_type_list),
user_name,
repr([r.getObject() for r in catalog_result]))
else:
return ()
loggable_object = catalog_result[0].getObject()
# Fetch category values from defined scripts
for (method_name, base_category_list) in security_definition_list:
base_category_list = tuple(base_category_list)
method = getattr(self, method_name)
security_category_list = security_category_dict.setdefault(
base_category_list, [])
try:
# The called script may want to distinguish if it is called
# from here or from _updateLocalRolesOnSecurityGroups.
# Currently, passing portal_type='' (instead of 'Person')
# is the only way to make the difference.
security_category_list.extend(
method(base_category_list, user_name, loggable_object, '')
)
except ConflictError:
raise
except:
LOG('ERP5GroupManager', WARNING,
'could not get security categories from %s' % (method_name,),
error = sys.exc_info())
# Get group names from category values
# XXX try ERP5Type_asSecurityGroupIdList first for compatibility
generator_name = 'ERP5Type_asSecurityGroupIdList'
group_id_list_generator = getattr(self, generator_name, None)
if group_id_list_generator is None:
generator_name = ERP5TYPE_SECURITY_GROUP_ID_GENERATION_SCRIPT
group_id_list_generator = getattr(self, generator_name)
for base_category_list, category_value_list in \
security_category_dict.iteritems():
for category_dict in category_value_list:
try:
group_id_list = group_id_list_generator(
category_order=base_category_list,
**category_dict)
if isinstance(group_id_list, str):
group_id_list = [group_id_list]
security_group_list.extend(group_id_list)
except ConflictError:
raise
except:
LOG('ERP5GroupManager', WARNING,
'could not get security groups from %s' %
generator_name,
error = sys.exc_info())
finally:
pass
return tuple(security_group_list)
if not NO_CACHE_MODE:
_getGroupsForPrincipal = CachingMethod(_getGroupsForPrincipal,
id='ERP5GroupManager_getGroupsForPrincipal',
cache_factory='erp5_content_short')
return _getGroupsForPrincipal(
user_name=principal.getId(),
path=self.getPhysicalPath())
#
# IUserEnumerationPlugin implementation
#
security.declarePrivate( 'enumerateUsers' )
def enumerateUsers(self, id=None, login=None, exact_match=False,
sort_by=None, max_results=None, **kw):
""" See IUserEnumerationPlugin.
"""
if id is None:
id = login
if isinstance(id, str):
id = (id,)
if isinstance(id, list):
id = tuple(id)
user_info = []
plugin_id = self.getId()
id_list = []
for user_id in id:
if ERP5Security.SUPER_USER == user_id:
info = { 'id' : ERP5Security.SUPER_USER
, 'login' : ERP5Security.SUPER_USER
, 'pluginid' : plugin_id
}
user_info.append(info)
else:
id_list.append(user_id)
if id_list:
for user in self.getUserByLogin(tuple(id_list)):
info = { 'id' : user.getReference()
, 'login' : user.getReference()
, 'pluginid' : plugin_id
}
user_info.append(info)
return tuple(user_info)
#List implementation of class
classImplements(SlapOSMachineAuthenticationPlugin,
plugins.IAuthenticationPlugin)
classImplements( SlapOSMachineAuthenticationPlugin,
plugins.ILoginPasswordHostExtractionPlugin)
classImplements( SlapOSMachineAuthenticationPlugin,
plugins.IGroupsPlugin)
classImplements( SlapOSMachineAuthenticationPlugin,
plugins.IUserEnumerationPlugin)
InitializeClass(SlapOSMachineAuthenticationPlugin)
......@@ -25,29 +25,23 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
##############################################################################
from zLOG import LOG, PROBLEM
from functools import partial
from Products.ERP5Type.Globals import InitializeClass
from AccessControl import ClassSecurityInfo
import sys
from Products import ERP5Security
from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Products.PluggableAuthService.PluggableAuthService import \
_SWALLOWABLE_PLUGIN_EXCEPTIONS
from Products.PluggableAuthService.interfaces import plugins
from Products.PluggableAuthService.utils import classImplements
from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin
from Products.ERP5Type.Cache import transactional_cached
from Products import ERP5Security
from ZODB.POSException import ConflictError
from Products.ERP5Security.ERP5GroupManager import ConsistencyError, NO_CACHE_MODE
from Products.ERP5Security.ERP5GroupManager import NO_CACHE_MODE
from Products.ERP5Type.Cache import CachingMethod
from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery
from Products.ERP5Security.ERP5UserManager import getValidAssignmentList
from Products.ERP5Security.ERP5LoginUserManager import SYSTEM_USER_USER_NAME,\
SPECIAL_USER_NAME_SET
# some usefull globals
LOGGABLE_PORTAL_TYPE_LIST = ["Person", "Computer", "Software Instance"]
LOGIN_PREFIX = 'SHADOW-'
LOGIN_PREFIX_LENGTH = len(LOGIN_PREFIX)
......@@ -69,49 +63,6 @@ def addSlapOSShadowAuthenticationPlugin(dispatcher, id, title=None, REQUEST=None
'SlapOSShadowAuthenticationPlugin+added.'
% dispatcher.absolute_url())
@transactional_cached(lambda portal, *args: args)
def getUserByLogin(portal, login):
if isinstance(login, basestring):
login = login,
if len(login) != 1:
return []
login = login[0]
if login.startswith(LOGIN_PREFIX):
login = login[LOGIN_PREFIX_LENGTH:]
else:
return []
machine_query = Query(portal_type=["Computer", "Software Instance"],
validation_state="validated",
reference=dict(query=login, key='ExactMatch'))
person_query = Query(portal_type=["Person"],
reference=dict(query=login, key='ExactMatch'))
result = portal.portal_catalog.unrestrictedSearchResults(
query=ComplexQuery(machine_query, person_query,logical_operator="OR"),
select_expression='reference')
result = [x for x in result if \
(x.getPortalType() == 'Person' and x.getValidationState() != 'deleted') or \
(x.getPortalType() in ("Computer", "Software Instance") and \
x.getValidationState() == 'validated')]
# XXX: Here, we filter catalog result list ALTHOUGH we did pass
# parameters to unrestrictedSearchResults to restrict result set.
# This is done because the following values can match person with
# reference "foo":
# "foo " because of MySQL (feature, PADSPACE collation):
# mysql> SELECT reference as r FROM catalog
# -> WHERE reference="foo ";
# +-----+
# | r |
# +-----+
# | foo |
# +-----+
# 1 row in set (0.01 sec)
# "bar OR foo" because of ZSQLCatalog tokenizing searched strings
# by default (feature).
return [x.getObject() for x in result if x['reference'] in login]
class SlapOSShadowAuthenticationPlugin(BasePlugin):
"""
Plugin to authenicate as shadows.
......@@ -125,59 +76,12 @@ class SlapOSShadowAuthenticationPlugin(BasePlugin):
self._setId(id)
self.title = title
################################
# IAuthenticationPlugin #
################################
security.declarePrivate('authenticateCredentials')
def authenticateCredentials(self, credentials):
"""Authentificate with credentials"""
login = credentials.get('machine_login', None)
# Forbidden the usage of the super user.
if login == ERP5Security.SUPER_USER:
return None
#Search the user by his login
user_list = self.getUserByLogin(login)
if len(user_list) != 1:
return None
user = user_list[0]
if user.getPortalType() == 'Person':
if len(getValidAssignmentList(user)) == 0:
return None
return (login, login)
def getUserByLogin(self, login):
# Search the Catalog for login and return a list of person objects
# login can be a string or a list of strings
# (no docstring to prevent publishing)
if not login:
return []
if isinstance(login, list):
login = tuple(login)
elif not isinstance(login, tuple):
login = str(login)
try:
return getUserByLogin(self.getPortalObject(), login)
except ConflictError:
raise
except:
LOG('SlapOSShadowAuthenticationPlugin', PROBLEM, 'getUserByLogin failed',
error=sys.exc_info())
# Here we must raise an exception to prevent callers from caching
# a result of a degraded situation.
# The kind of exception does not matter as long as it's catched by
# PAS and causes a lookup using another plugin or user folder.
# As PAS does not define explicitely such exception, we must use
# the _SWALLOWABLE_PLUGIN_EXCEPTIONS list.
raise _SWALLOWABLE_PLUGIN_EXCEPTIONS[0]
#################################
# IGroupsPlugin #
#################################
# This is patched version of
# Products.ERP5Security.ERP5GroupManager.ERP5GroupManager.getGroupsForPrincipal
# which allows to treat Computer and Software Instance as loggable user
loggable_portal_type_list = LOGGABLE_PORTAL_TYPE_LIST
def getGroupsForPrincipal(self, principal, request=None):
""" See IGroupsPlugin.
"""
......@@ -186,30 +90,28 @@ class SlapOSShadowAuthenticationPlugin(BasePlugin):
return ()
@UnrestrictedMethod
def _getGroupsForPrincipal(user_name, path):
if user_name.startswith(LOGIN_PREFIX):
user_name = user_name[LOGIN_PREFIX_LENGTH:]
def _getGroupsForPrincipal(user_id, path):
if user_id.startswith(LOGIN_PREFIX):
user_id = user_id[LOGIN_PREFIX_LENGTH:]
else:
return ( )
# get the loggable document from its reference - no security check needed
catalog_result = self.portal_catalog.unrestrictedSearchResults(
portal_type=self.loggable_portal_type_list,
reference=dict(query=user_name, key='ExactMatch'))
if len(catalog_result) != 1: # we won't proceed with groups
if len(catalog_result) > 1: # configuration is screwed
raise ConsistencyError, 'There is more than one of %s whose \
login is %s : %s' % (','.join(self.loggable_portal_type_list),
user_name,
repr([r.getObject() for r in catalog_result]))
else:
# get the person from its login - no security check needed
user_path_set = {
x['path']
for x in self.searchUsers(id=user_id, exact_match=True)
if 'path' in x
}
if not user_path_set:
return ()
else:
portal_type = catalog_result[0].getPortalType()
user_path, = user_path_set
person_object = self.getPortalObject().unrestrictedTraverse(user_path)
portal_type = person_object.getPortalType()
return (
'R-SHADOW-%s' % portal_type.replace(' ', '').upper(), # generic group
'SHADOW-%s' % user_name # user specific shadow
'SHADOW-%s' % user_id # user specific shadow
)
if not NO_CACHE_MODE:
......@@ -218,52 +120,141 @@ class SlapOSShadowAuthenticationPlugin(BasePlugin):
cache_factory='erp5_content_short')
return _getGroupsForPrincipal(
user_name=principal.getId(),
user_id=principal.getId(),
path=self.getPhysicalPath())
#
# IUserEnumerationPlugin implementation
#
security.declarePrivate( 'enumerateUsers' )
security.declarePrivate('enumerateUsers')
def enumerateUsers(self, id=None, login=None, exact_match=False,
sort_by=None, max_results=None, **kw):
sort_by=None, max_results=None, login_portal_type=None, **kw):
""" See IUserEnumerationPlugin.
"""
if id is None:
id = login
portal = self.getPortalObject()
if login_portal_type is None:
login_portal_type = portal.getPortalLoginTypeList()
unrestrictedSearchResults = portal.portal_catalog.unrestrictedSearchResults
searchUser = lambda **kw: unrestrictedSearchResults(
select_list=('user_id', ),
**kw
).dictionaries()
searchLogin = lambda **kw: unrestrictedSearchResults(
select_list=('parent_uid', 'reference'),
validation_state='validated',
**kw
).dictionaries()
if login_portal_type is not None:
searchLogin = partial(searchLogin, portal_type=login_portal_type)
special_user_name_set = set()
if login is None:
# Only search by id if login is not given. Same logic as in
# PluggableAuthService.searchUsers.
# CUSTOM: Modify the id to remove the prefix before search the User
if id.startswith(LOGIN_PREFIX):
id = id[LOGIN_PREFIX_LENGTH:]
else:
return ( )
# END OF CUSTOM CODE
if isinstance(id, str):
id = (id,)
if isinstance(id, list):
id = tuple(id)
id = (id, )
user_info = []
plugin_id = self.getId()
# Short-cut "System Processes" as not being searchable by user_id.
# This improves performance in proxy-role'd execution by avoiding an
# sql query expected to find no user.
id = [x for x in id if x != SYSTEM_USER_USER_NAME]
if id:
if exact_match:
requested = set(id).__contains__
else:
requested = lambda x: True
user_list = [
x for x in searchUser(
user_id={
'query': id,
'key': 'ExactMatch' if exact_match else 'Keyword',
},
limit=max_results,
)
if requested(x['user_id'])
]
else:
user_list = []
login_dict = {}
if user_list:
for login in searchLogin(parent_uid=[x['uid'] for x in user_list]):
login_dict.setdefault(login['parent_uid'], []).append(login)
else:
id_list = []
for user_id in id:
if ERP5Security.SUPER_USER == user_id:
info = { 'id' : ERP5Security.SUPER_USER
, 'login' : ERP5Security.SUPER_USER
, 'pluginid' : plugin_id
}
user_info.append(info)
# CUSTOM: Modify the login to remove the prefix before search the User
if login.startswith(LOGIN_PREFIX):
login = login[LOGIN_PREFIX_LENGTH:]
else:
return ( )
# END OF CUSTOM CODE
if isinstance(login, str):
login = (login, )
login_list = []
for user_login in login:
if user_login in SPECIAL_USER_NAME_SET:
special_user_name_set.add(user_login)
else:
login_list.append(user_login)
login_dict = {}
if exact_match:
requested = set(login_list).__contains__
else:
requested = lambda x: True
if login_list:
for login in searchLogin(
reference={
'query': login_list,
'key': 'ExactMatch' if exact_match else 'Keyword',
},
limit=max_results,
):
if requested(login['reference']):
login_dict.setdefault(login['parent_uid'], []).append(login)
if login_dict:
user_list = searchUser(uid=list(login_dict))
else:
id_list.append(user_id)
user_list = []
plugin_id = self.getId()
if id_list:
for user in self.getUserByLogin(tuple(id_list)):
info = { 'id' : LOGIN_PREFIX + user.getReference()
, 'login' : LOGIN_PREFIX + user.getReference()
, 'pluginid' : plugin_id
}
# CUSTOM: In the block below the LOGIN_PREFIX is added before id and login
# to keep compatibility.
result = [
{
'id': LOGIN_PREFIX + user['user_id'],
# Note: PAS forbids us from returning more than one entry per given id,
# so take any available login.
'login': LOGIN_PREFIX + login_dict.get(user['uid'], [{'reference': None}])[0]['reference'],
'pluginid': plugin_id,
user_info.append(info)
# Extra properties, specific to ERP5
'path': user['path'],
'uid': user['uid'],
'login_list': [
{
'reference': LOGIN_PREFIX + login['reference'],
'path': login['path'],
'uid': login['uid'],
}
for login in login_dict.get(user['uid'], [])
],
}
for user in user_list if user['user_id']
]
# END OF CUSTOM CODE
return tuple(user_info)
return tuple(result)
#List implementation of class
classImplements(SlapOSShadowAuthenticationPlugin,
plugins.IAuthenticationPlugin)
classImplements( SlapOSShadowAuthenticationPlugin,
plugins.IGroupsPlugin
)
......
......@@ -40,6 +40,39 @@ from Products.ERP5Type.tests.utils import createZODBPythonScript
from AccessControl.SecurityManagement import getSecurityManager, \
setSecurityManager
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 withAbort(func):
@functools.wraps(func)
......@@ -52,6 +85,8 @@ def withAbort(func):
class testSlapOSMixin(ERP5TypeTestCase):
abort_transaction = 0
def clearCache(self):
self.portal.portal_caches.clearAllCache()
self.portal.portal_workflow.refreshWorklistCache()
......@@ -125,7 +160,8 @@ class testSlapOSMixin(ERP5TypeTestCase):
def beforeTearDown(self):
if self.isLiveTest():
self.deSetUpPersistentDummyMailHost()
return
if self.abort_transaction:
transaction.abort()
def getUserFolder(self):
"""
......@@ -143,6 +179,10 @@ class testSlapOSMixin(ERP5TypeTestCase):
def afterSetUp(self):
self.login()
self.createAlarmStep()
# Helpfull for the tests
self.new_id = self.generateNewId()
if self.isLiveTest():
self.setUpPersistentDummyMailHost()
return
......@@ -162,7 +202,6 @@ class testSlapOSMixin(ERP5TypeTestCase):
self.commit()
def deSetUpPersistentDummyMailHost(self):
if 'MailHost' in self.portal.objectIds():
self.portal.manage_delObjects(['MailHost'])
......@@ -237,10 +276,7 @@ class testSlapOSMixin(ERP5TypeTestCase):
if user:
login = person_user.newContent(
portal_type="ERP5 Login",
reference=person_user.getReference())
login.validate()
login = self._addERP5Login(person_user)
if index:
transaction.commit()
......@@ -250,6 +286,13 @@ class testSlapOSMixin(ERP5TypeTestCase):
return person_user
def _addERP5Login(self, document):
login = document.newContent(
portal_type="ERP5 Login",
reference=document.getReference())
login.validate()
return login
def _makeTree(self, requested_template_id='template_software_instance'):
new_id = self.generateNewId()
......@@ -313,7 +356,7 @@ class testSlapOSMixin(ERP5TypeTestCase):
self.requested_software_instance.validate()
self.tic()
def _makeComputer(self):
def _makeComputer(self, owner=None):
self.computer = self.portal.computer_module.template_computer\
.Base_createCloneDocument(batch_mode=1)
reference = 'TESTCOMP-%s' % self.generateNewId()
......@@ -332,6 +375,11 @@ class testSlapOSMixin(ERP5TypeTestCase):
self.partition.markFree()
self.partition.validate()
self.tic()
if owner is not None:
self.computer.edit(
source_administration_value=owner,
)
return self.computer, self.partition
def _makeComputerNetwork(self):
......
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