Commit 6350e391 authored by Rafael Monnerat's avatar Rafael Monnerat

slapos_erp5: Cleanup Shadow User roles implementation

  Deduplicate script to get shadow user from context, now it relies on base_category_list configured in the role, and output all needed roles (Assignee and Auditor), so the Role configuration can filter it properly.

  This change makes no change on output result for the configured roles.
parent e2797512
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<role id='Assignee'> <role id='Assignee'>
<property id='title'>Shadow User</property> <property id='title'>Shadow User</property>
<property id='condition'>python: (here.getDestination('', portal_type='Person') != "") and (here.getLedger("") == "automated")</property> <property id='condition'>python: (here.getDestination('', portal_type='Person') != "") and (here.getLedger("") == "automated")</property>
<property id='base_category_script'>PaymentTransaction_getSecurityCategoryFromUser</property> <property id='base_category_script'>Base_getSecurityCategoryAsShadowUser</property>
<multi_property id='categories'>local_role_group/shadow</multi_property> <multi_property id='categories'>local_role_group/shadow</multi_property>
<multi_property id='base_category'>destination</multi_property> <multi_property id='base_category'>destination</multi_property>
</role> </role>
......
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
<role id='Assignee'> <role id='Assignee'>
<property id='title'>Shadow User</property> <property id='title'>Shadow User</property>
<property id='condition'>python: here.getDestinationSection('', portal_type='Person') != ''</property> <property id='condition'>python: here.getDestinationSection('', portal_type='Person') != ''</property>
<property id='base_category_script'>PayzenEvent_getSecurityCategoryFromUser</property> <property id='base_category_script'>Base_getSecurityCategoryAsShadowUser</property>
<multi_property id='categories'>local_role_group/shadow</multi_property> <multi_property id='categories'>local_role_group/shadow</multi_property>
<multi_property id='base_category'>aggregate</multi_property> <multi_property id='base_category'>destination_section</multi_property>
</role> </role>
</type_roles> </type_roles>
\ No newline at end of file
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
<role id='Assignee'> <role id='Assignee'>
<property id='title'>Shadow User</property> <property id='title'>Shadow User</property>
<property id='condition'>python: here.getDestinationSection('', portal_type='Person') != ''</property> <property id='condition'>python: here.getDestinationSection('', portal_type='Person') != ''</property>
<property id='base_category_script'>PayzenEvent_getSecurityCategoryFromUser</property> <property id='base_category_script'>Base_getSecurityCategoryAsShadowUser</property>
<multi_property id='categories'>local_role_group/shadow</multi_property> <multi_property id='categories'>local_role_group/shadow</multi_property>
<multi_property id='base_category'>aggregate</multi_property> <multi_property id='base_category'>destination_section</multi_property>
</role> </role>
</type_roles> </type_roles>
\ No newline at end of file
...@@ -25,16 +25,23 @@ The parameters are ...@@ -25,16 +25,23 @@ The parameters are
NOTE: for now, this script requires proxy manager NOTE: for now, this script requires proxy manager
""" """
category_list = []
if obj is None: if obj is None:
return [] return []
# XXX rename script to: setShadowUserAsAssignee if not base_category_list:
# use base category instead of Hardcoding getDestinationSectionValue return []
person = obj.getDestinationValue(portal_type="Person")
if person is not None: # We only need the first
if base_category_list: base_category = base_category_list[0]
return {"Assignee": ["SHADOW-%s" % person.getUserId()]}
person_list = [i for i in obj.getValueList(base_category) if i.getPortalType() == "Person"]
if not person_list:
return []
# The assignee is hardcoded here.
person_shadow_id = "SHADOW-%s" % person_list[0].getUserId()
return category_list # Return all usecased so the role filter on upper level
return {"Assignee": [person_shadow_id],
"Auditor": [person_shadow_id]}
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>PayzenEvent_getSecurityCategoryFromUser</string> </value> <value> <string>Base_getSecurityCategoryAsShadowUser</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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>base_category_list, user_name, obj, portal_type</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>PaymentTransaction_getSecurityCategoryFromUser</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
"""
This script returns a list of dictionaries which represent
the security groups which a person is member of. It extracts
the categories from the current content. It is useful in the
following cases:
- calculate a security group based on a given
category of the current object (ex. group). This
is used for example in ERP5 DMS to calculate
document security.
- assign local roles to a document based on
the person which the object related to through
a given base category (ex. destination). This
is used for example in ERP5 Project to calculate
Task / Task Report security.
The parameters are
base_category_list -- list of category values we need to retrieve
user_name -- string obtained from getSecurityManager().getUser().getId()
object -- object which we want to assign roles to
portal_type -- portal type of object
NOTE: for now, this script requires proxy manager
"""
category_list = []
if obj is None:
return []
person = obj.getDestinationSectionValue(portal_type="Person")
if person is not None:
if base_category_list:
return {"Assignee": ["SHADOW-%s" % person.getUserId()]}
return category_list
...@@ -211,7 +211,6 @@ def makeTestSlapOSCodingStyleTestCase(tested_business_template): ...@@ -211,7 +211,6 @@ def makeTestSlapOSCodingStyleTestCase(tested_business_template):
'slapos_administration/z_get_uid_group_from_roles_and_users', 'slapos_administration/z_get_uid_group_from_roles_and_users',
'slapos_administration/SoftwareInstance_renewCertificate', 'slapos_administration/SoftwareInstance_renewCertificate',
'slapos_core/ERP5Type_getSecurityCategoryMapping', 'slapos_core/ERP5Type_getSecurityCategoryMapping',
'slapos_core/SlaveInstance_getSecurityCategoryFromSoftwareInstance',
'slapos_base/Login_getFastExpirationReferenceList', 'slapos_base/Login_getFastExpirationReferenceList',
'slapos_base/Login_isLoginBlocked', 'slapos_base/Login_isLoginBlocked',
'slapos_base/Login_isPasswordExpired', 'slapos_base/Login_isPasswordExpired',
......
...@@ -164,41 +164,74 @@ class TestSoftwareInstance_getSecurityCategoryFromUser(TestSlapOSCoreMixin): ...@@ -164,41 +164,74 @@ class TestSoftwareInstance_getSecurityCategoryFromUser(TestSlapOSCoreMixin):
self.assertEqual([{'couscous': [person.getRelativeUrl()]}, {'destination_section': [person.getRelativeUrl()]}], self.assertEqual([{'couscous': [person.getRelativeUrl()]}, {'destination_section': [person.getRelativeUrl()]}],
self.portal.SoftwareInstance_getSecurityCategoryFromUser(["couscous", "destination_section"], None, instance, None)) self.portal.SoftwareInstance_getSecurityCategoryFromUser(["couscous", "destination_section"], None, instance, None))
class TestSlaveInstance_getSecurityCategoryFromSoftwareInstance(TestSlapOSCoreMixin):
class TestPaymentTransaction_getSecurityCategoryFromUser(TestSlapOSCoreMixin):
def test(self): def test(self):
person = self.createPerson() person = self.createPerson()
payment = self.portal.accounting_module.newContent( computer_node = self.portal.compute_node_module.newContent(
portal_type='Payment Transaction', destination_value=person) portal_type='Compute Node',
source_administration=person.getRelativeUrl())
partition = computer_node.newContent(portal_type="Compute Partition")
instance = self.portal.software_instance_module.newContent(
portal_type='Software Instance',
aggregate=partition.getRelativeUrl())
instance.validate()
slave_instance = self.portal.software_instance_module.newContent(
portal_type='Slave Instance',
aggregate=partition.getRelativeUrl())
self.tic() # Script calls catalog so it requires indexation
self.assertEqual([], self.assertEqual([],
self.portal.PaymentTransaction_getSecurityCategoryFromUser([], None, None, None)) self.portal.SlaveInstance_getSecurityCategoryFromSoftwareInstance([], None, None, None))
self.assertEqual([], self.assertEqual([],
self.portal.PaymentTransaction_getSecurityCategoryFromUser([], None, payment, None)) self.portal.SlaveInstance_getSecurityCategoryFromSoftwareInstance([], None, slave_instance, None))
shadow_user_id = 'SHADOW-%s' % person.getUserId() self.assertEqual([{'aggregate': [instance.getRelativeUrl()]}],
self.assertEqual({'Assignee': [shadow_user_id]}, self.portal.SlaveInstance_getSecurityCategoryFromSoftwareInstance(["aggregate"], None, slave_instance, None))
self.portal.PaymentTransaction_getSecurityCategoryFromUser(["destination"], None, payment, None))
self.assertEqual({'Assignee': [shadow_user_id]}, self.assertEqual([{'couscous': [instance.getRelativeUrl()]}, {'aggregate': [instance.getRelativeUrl()]}],
self.portal.PaymentTransaction_getSecurityCategoryFromUser(["couscous", "destination"], None, payment, None)) self.portal.SlaveInstance_getSecurityCategoryFromSoftwareInstance(["couscous", "aggregate"], None, slave_instance, None))
class TestPayzenEvent_getSecurityCategoryFromUserr(TestSlapOSCoreMixin):
def test(self): class TestBase_getSecurityCategoryAsShadowUser(TestSlapOSCoreMixin):
def test_destination_section(self):
person = self.createPerson() person = self.createPerson()
event = self.portal.system_event_module.newContent( event = self.portal.system_event_module.newContent(
portal_type='Payzen Event', destination_section_value=person) portal_type='Payzen Event', destination_section_value=person)
self.assertEqual([], self.assertEqual([],
self.portal.PayzenEvent_getSecurityCategoryFromUser([], None, None, None)) self.portal.Base_getSecurityCategoryAsShadowUser([], None, None, None))
self.assertEqual([], self.assertEqual([],
self.portal.PayzenEvent_getSecurityCategoryFromUser([], None, event, None)) self.portal.Base_getSecurityCategoryAsShadowUser([], None, event, None))
shadow_user_id = 'SHADOW-%s' % person.getUserId() shadow_user_id = 'SHADOW-%s' % person.getUserId()
self.assertEqual({'Assignee': [shadow_user_id]}, self.assertEqual({'Assignee': [shadow_user_id], 'Auditor': [shadow_user_id]},
self.portal.PayzenEvent_getSecurityCategoryFromUser(["destination_section"], None, event, None)) self.portal.Base_getSecurityCategoryAsShadowUser(["destination_section"], None, event, None))
self.assertEqual([],
self.portal.Base_getSecurityCategoryAsShadowUser(["couscous", "destination_section"], None, event, None))
def test_destination(self):
person = self.createPerson()
payment = self.portal.accounting_module.newContent(
portal_type='Payment Transaction', destination_value=person)
self.assertEqual([],
self.portal.Base_getSecurityCategoryAsShadowUser([], None, None, None))
self.assertEqual([],
self.portal.Base_getSecurityCategoryAsShadowUser(["destination_section"], None, payment, None))
shadow_user_id = 'SHADOW-%s' % person.getUserId()
self.assertEqual({'Assignee': [shadow_user_id], 'Auditor': [shadow_user_id]},
self.portal.Base_getSecurityCategoryAsShadowUser(["destination"], None, payment, None))
# It only consider the first one.
self.assertEqual([],
self.portal.Base_getSecurityCategoryAsShadowUser(["couscous", "destination"], None, payment, None))
self.assertEqual({'Assignee': [shadow_user_id]},
self.portal.PayzenEvent_getSecurityCategoryFromUser(["couscous", "destination_section"], None, event, None))
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