Commit fc328498 authored by Rafael Monnerat's avatar Rafael Monnerat

slapos_erp5: Fix user security for Software/Slave Instance/Installation on shared context

Once the Computer/Hosting Subscription is transferred using Internal Packing List, the associated installation and instance should acquire security from the respective context.
parent 1c509f97
Pipeline #7322 failed with stage
in 0 seconds
...@@ -23,6 +23,18 @@ ...@@ -23,6 +23,18 @@
<multi_property id='categories'>local_role_group/subscription</multi_property> <multi_property id='categories'>local_role_group/subscription</multi_property>
<multi_property id='base_category'>specialise</multi_property> <multi_property id='base_category'>specialise</multi_property>
</role> </role>
<role id='Assignee'>
<property id='title'>Organisation Member</property>
<property id='base_category_script'>Instance_getSecurityCategoryFromMovementSpecialiseDestination</property>
<multi_property id='categories'>local_role_group/organisation</multi_property>
<multi_property id='base_category'>destination</multi_property>
</role>
<role id='Assignee'>
<property id='title'>Project Member</property>
<property id='base_category_script'>Instance_getSecurityCategoryFromMovementSpecialiseDestinationProject</property>
<multi_property id='categories'>local_role_group/project</multi_property>
<multi_property id='base_category'>destination_project</multi_property>
</role>
<role id='Assignor'> <role id='Assignor'>
<property id='title'>Software Instance which provides this Slave Instance</property> <property id='title'>Software Instance which provides this Slave Instance</property>
<property id='base_category_script'>SlaveInstanceType_getSecurityCategoryFromSoftwareInstance</property> <property id='base_category_script'>SlaveInstanceType_getSecurityCategoryFromSoftwareInstance</property>
......
...@@ -23,4 +23,16 @@ ...@@ -23,4 +23,16 @@
<multi_property id='categories'>local_role_group/subscription</multi_property> <multi_property id='categories'>local_role_group/subscription</multi_property>
<multi_property id='base_category'>specialise</multi_property> <multi_property id='base_category'>specialise</multi_property>
</role> </role>
<role id='Assignee'>
<property id='title'>Organisation Member</property>
<property id='base_category_script'>Instance_getSecurityCategoryFromMovementSpecialiseDestination</property>
<multi_property id='categories'>local_role_group/organisation</multi_property>
<multi_property id='base_category'>destination</multi_property>
</role>
<role id='Assignee'>
<property id='title'>Project Member</property>
<property id='base_category_script'>Instance_getSecurityCategoryFromMovementSpecialiseDestinationProject</property>
<multi_property id='categories'>local_role_group/project</multi_property>
<multi_property id='base_category'>destination_project</multi_property>
</role>
</type_roles> </type_roles>
\ No newline at end of file
"""
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 []
specialise_value = obj.getSpecialiseValue()
if specialise_value is None:
return []
# Object on this case can be Hosting Subscription, Computer, or Computer Network
organisation = specialise_value.Item_getCurrentOwnerValue()
if organisation is not None and \
organisation.getPortalType() == "Organisation":
category_list.append({'destination': [organisation.getRelativeUrl()]})
return category_list
<?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>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>Instance_getSecurityCategoryFromMovementSpecialiseDestination</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 []
specialise_value = obj.getSpecialiseValue()
if specialise_value is None:
return []
# Object on this case can be Hosting Subscription, Computer, or Computer Network
project = specialise_value.Item_getCurrentProjectValue()
if project is not None:
category_list.append({'destination_project': [project.getRelativeUrl()]})
return category_list
<?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>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>Instance_getSecurityCategoryFromMovementSpecialiseDestinationProject</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
# Copyright (c) 2002-2012 Nexedi SA and Contributors. All Rights Reserved. # -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2012 Nexedi SA and Contributors. All Rights Reserved.
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from erp5.component.test.testSlapOSERP5GroupRoleSecurity import TestSlapOSGroupRoleSecurityMixin from erp5.component.test.testSlapOSERP5GroupRoleSecurity import TestSlapOSGroupRoleSecurityMixin
from DateTime import DateTime
class TestSlapOSLocalPermissionSlapOSInteractionWorkflow( class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
TestSlapOSGroupRoleSecurityMixin): TestSlapOSGroupRoleSecurityMixin):
...@@ -295,17 +315,33 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow( ...@@ -295,17 +315,33 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
def test_PayzenEvent_setDestinationSection(self): def test_PayzenEvent_setDestinationSection(self):
self._makePerson() self._makePerson()
payment_transaction = self.portal.system_event_module.newContent( event = self.portal.system_event_module.newContent(
portal_type='Payzen Event') portal_type='Payzen Event')
self.assertSecurityGroup(payment_transaction, [self.user_id, self.assertSecurityGroup(event, [self.user_id,
'G-COMPANY'], 'G-COMPANY'],
False) False)
payment_transaction.edit( event.edit(
destination_section=self.person_user.getRelativeUrl()) destination_section=self.person_user.getRelativeUrl())
self.commit() self.commit()
self.assertSecurityGroup(payment_transaction, [self.user_id, self.assertSecurityGroup(event, [self.user_id,
'G-COMPANY', 'SHADOW-%s' % self.person_user.getUserId()],
False)
def test_WechatEvent_setDestinationSection(self):
self._makePerson()
event = self.portal.system_event_module.newContent(
portal_type='Payzen Event')
self.assertSecurityGroup(event, [self.user_id,
'G-COMPANY'],
False)
event.edit(
destination_section=self.person_user.getRelativeUrl())
self.commit()
self.assertSecurityGroup(event, [self.user_id,
'G-COMPANY', 'SHADOW-%s' % self.person_user.getUserId()], 'G-COMPANY', 'SHADOW-%s' % self.person_user.getUserId()],
False) False)
...@@ -641,3 +677,165 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow( ...@@ -641,3 +677,165 @@ class TestSlapOSLocalPermissionSlapOSInteractionWorkflow(
self.assertSecurityGroup(sale_packing_list, ['G-COMPANY', self.user_id, self.assertSecurityGroup(sale_packing_list, ['G-COMPANY', self.user_id,
self.person_user_id], False) self.person_user_id], False)
def test_RestrictedAccessToken_setAgent(self):
self._makePerson()
token = self.portal.access_token_module.newContent(
portal_type='Restricted Access Token')
self.assertSecurityGroup(token, [self.user_id,
'G-COMPANY'],
False)
token.edit(
agent=self.person_user.getRelativeUrl())
self.commit()
self.assertSecurityGroup(token, [self.user_id,
'G-COMPANY', self.person_user.getUserId()],
False)
def test_InternalPackingListLine_setAggregate_hosting_subscription(self):
self._makePerson()
project = self.portal.project_module.newContent(
portal_type="Project",
)
hosting_subscription = self.portal.hosting_subscription_module.newContent(
portal_type='Hosting Subscription',
reference='TESTHS-%s' % self.generateNewId())
internal_packing_list = self.portal.internal_packing_list_module.newContent(
portal_type='Internal Packing List')
internal_packing_list_line = internal_packing_list.newContent(
portal_type='Internal Packing List Line')
internal_packing_list.edit(source_value=self.person_user,
source_section_value=self.person_user,
source_project_value=project,
destination=self.person_user.getRelativeUrl(),
destination_section=self.person_user.getRelativeUrl(),
source_decision=self.person_user.getRelativeUrl(),
destination_decision=self.person_user.getRelativeUrl(),
destination_project_value=project,
start_date=DateTime()-1,
stop_date=DateTime()-1)
internal_packing_list.confirm()
internal_packing_list.stop()
internal_packing_list.deliver()
software_instance = self.portal.software_instance_module.newContent(
portal_type='Software Instance')
software_instance.edit(specialise=hosting_subscription.getRelativeUrl())
slave_instance = self.portal.software_instance_module.newContent(
portal_type='Slave Instance')
slave_instance.edit(specialise=hosting_subscription.getRelativeUrl())
self.tic()
self.assertSecurityGroup(internal_packing_list, [self.user_id,],
False)
self.assertSecurityGroup(hosting_subscription, [self.user_id, 'G-COMPANY',
hosting_subscription.getReference()],
False)
self.assertSecurityGroup(software_instance, [self.user_id, 'G-COMPANY',
hosting_subscription.getReference()], False)
self.assertSecurityGroup(slave_instance, [self.user_id, 'G-COMPANY',
hosting_subscription.getReference()], False)
internal_packing_list_line.edit(
#quantity_unit="unit",
resource_value=self.portal.product_module.computer,
price=0.0,
quantity=1.0,
aggregate_value=hosting_subscription)
self.tic()
self.assertSecurityGroup(internal_packing_list, [self.user_id,],
False)
self.assertSecurityGroup(hosting_subscription, [self.user_id, 'G-COMPANY',
project.getReference(),
hosting_subscription.getReference()],
False)
self.assertSecurityGroup(software_instance, [self.user_id, 'G-COMPANY',
project.getReference(),
hosting_subscription.getReference()], False)
self.assertSecurityGroup(slave_instance, [self.user_id, 'G-COMPANY',
project.getReference(),
hosting_subscription.getReference()], False)
def test_InternalPackingListLine_setAggregate_computer(self):
self._makePerson()
project = self.portal.project_module.newContent(
portal_type="Project",
)
computer = self.portal.computer_module.newContent(
portal_type='Computer',
reference='TESTCOMP-%s' % self.generateNewId())
internal_packing_list = self.portal.internal_packing_list_module.newContent(
portal_type='Internal Packing List')
internal_packing_list_line = internal_packing_list.newContent(
portal_type='Internal Packing List Line')
internal_packing_list.edit(source_value=self.person_user,
source_section_value=self.person_user,
source_project_value=project,
destination=self.person_user.getRelativeUrl(),
destination_section=self.person_user.getRelativeUrl(),
source_decision=self.person_user.getRelativeUrl(),
destination_decision=self.person_user.getRelativeUrl(),
destination_project_value=project,
start_date=DateTime()-1,
stop_date=DateTime()-1)
internal_packing_list.confirm()
internal_packing_list.stop()
internal_packing_list.deliver()
installation = self.portal.software_installation_module.newContent(
portal_type='Software Installation')
installation.edit(aggregate=computer.getRelativeUrl())
self.tic()
self.assertSecurityGroup(internal_packing_list, [self.user_id,],
False)
self.assertSecurityGroup(computer, [self.user_id, 'G-COMPANY',
computer.getUserId()],
False)
self.assertSecurityGroup(installation, [self.user_id, 'G-COMPANY',
computer.getUserId()], False)
internal_packing_list_line.edit(
#quantity_unit="unit",
resource_value=self.portal.product_module.computer,
price=0.0,
quantity=1.0,
aggregate_value=computer)
self.tic()
self.assertSecurityGroup(internal_packing_list, [self.user_id,],
False)
self.assertSecurityGroup(computer, [self.user_id, 'G-COMPANY',
project.getReference(), computer.getUserId()],
False)
self.assertSecurityGroup(installation, [self.user_id, 'G-COMPANY',
project.getReference(), computer.getUserId()], False)
...@@ -117,6 +117,7 @@ ...@@ -117,6 +117,7 @@
</item> </item>
</dictionary> </dictionary>
</list> </list>
<none/>
</tuple> </tuple>
</pickle> </pickle>
</record> </record>
......
portal_type_list = ['Computer', 'Computer Network', 'Hosting Subscription'] portal_type_list = ['Computer', 'Computer Network', 'Hosting Subscription']
internal_packing_list_line = state_change['object'] internal_packing_list_line = state_change['object']
after_tag = (internal_packing_list_line.getPath(), ('immediateReindexObject', 'recursiveImmediateReindexObject')) after_tag = (internal_packing_list_line.getPath(), ('immediateReindexObject', 'recursiveImmediateReindexObject'))
internal_packing_list_line.getParentValue().reindexObject()
for object_ in internal_packing_list_line.getAggregateValueList(portal_type=portal_type_list): for object_ in internal_packing_list_line.getAggregateValueList(portal_type=portal_type_list):
object_.activate(after_path_and_method_id=after_tag).updateLocalRolesOnSecurityGroups() object_.activate(after_path_and_method_id=after_tag).updateLocalRolesOnSecurityGroups()
if object_.getPortalType() == "Computer":
for software_installation in object_.getAggregateRelatedValueList(portal_type="Software Installation"):
software_installation.activate(after_path_and_method_id=after_tag).updateLocalRolesOnSecurityGroups()
elif object_.getPortalType() == "Hosting Subscription":
for instance in object_.getSpecialiseRelatedValueList(portal_type=["Software instance", "Slave Instance"]):
instance.activate(after_path_and_method_id=after_tag).updateLocalRolesOnSecurityGroups()
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