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>
......
......@@ -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
......
......@@ -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):
......
......@@ -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>
......@@ -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)
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