diff --git a/cetmix_tower_server/security/cx_tower_plan_line_action_security.xml b/cetmix_tower_server/security/cx_tower_plan_line_action_security.xml index 74068caf..9437bc40 100644 --- a/cetmix_tower_server/security/cx_tower_plan_line_action_security.xml +++ b/cetmix_tower_server/security/cx_tower_plan_line_action_security.xml @@ -12,12 +12,25 @@ - Tower plan line action: manager access rule + Tower plan line action: manager Read/Write access rule [('access_level', '<=', '2')] + + + + + + + Tower plan line action: manager delete own records + + [('create_uid', '=', user.id)] + + diff --git a/cetmix_tower_server/security/cx_tower_plan_line_security.xml b/cetmix_tower_server/security/cx_tower_plan_line_security.xml index 0179fdf4..f216dfc2 100644 --- a/cetmix_tower_server/security/cx_tower_plan_line_security.xml +++ b/cetmix_tower_server/security/cx_tower_plan_line_security.xml @@ -12,12 +12,23 @@ - Tower plan line: manager access rule + Tower plan line: manager Read/Write access rule [('access_level', '<=', '2')] + + + + + + + Tower plan line: manager delete own records + + [('create_uid', '=', user.id)] + + diff --git a/cetmix_tower_server/security/cx_tower_variable_value_security.xml b/cetmix_tower_server/security/cx_tower_variable_value_security.xml index 697addb6..f41e5551 100644 --- a/cetmix_tower_server/security/cx_tower_variable_value_security.xml +++ b/cetmix_tower_server/security/cx_tower_variable_value_security.xml @@ -1,8 +1,12 @@ - - Tower variable value: manager access rule + + + Tower variable value: user and manager access rule ['|', ('is_global', '=', True), ('server_id.message_partner_ids', 'in', [user.partner_id.id])] @@ -13,6 +17,59 @@ + + Tower variable value: user access to variable values in plan line action + rule + + + [ + ('plan_line_action_id.access_level', '=', '1') + ] + + + + + + Tower variable value: manager access to variable values in plan line + action rule + + + [ + ('plan_line_action_id.access_level', '<=', '2') + ] + + + + + + + + + + Tower variable value: manager delete own variable values in plan line + action + + + [ + ('plan_line_action_id.create_uid', '=', user.id) + ] + + + + + Tower variable value: root access rule diff --git a/cetmix_tower_server/security/ir.model.access.csv b/cetmix_tower_server/security/ir.model.access.csv index d647ad7a..a4851f32 100644 --- a/cetmix_tower_server/security/ir.model.access.csv +++ b/cetmix_tower_server/security/ir.model.access.csv @@ -14,7 +14,7 @@ access_server_user,Server->User,model_cx_tower_server,group_user,1,0,0,0 access_server_manager,Server->Manager,model_cx_tower_server,group_manager,1,1,1,0 access_server_root,Server->Root,model_cx_tower_server,group_root,1,1,1,1 access_interpreter_user,Interpreter->User,model_cx_tower_interpreter,group_user,1,0,0,0 -access_interpreter_manager,Interpreter->Manager,model_cx_tower_interpreter,group_manager,1,1,1,0 +access_interpreter_manager,Interpreter->Manager,model_cx_tower_interpreter,group_manager,1,1, 1,0 access_interpreter_root,Interpreter->Root,model_cx_tower_interpreter,group_root,1,1,1,1 access_command_user,Command->User,model_cx_tower_command,group_user,1,0,0,0 access_command_manager,Command->Manager,model_cx_tower_command,group_manager,1,1,1,0 @@ -30,10 +30,10 @@ access_plan_user,Plan->User,model_cx_tower_plan,group_user,1,0,0,0 access_plan_manager,Plan->Manager,model_cx_tower_plan,group_manager,1,1,1,0 access_plan_root,Plan->Root,model_cx_tower_plan,group_root,1,1,1,1 access_plan_line_user,Plan Line->User,model_cx_tower_plan_line,group_user,1,0,0,0 -access_plan_line_manager,Plan Line->Manager,model_cx_tower_plan_line,group_manager,1,1,1,0 +access_plan_line_manager,Plan Line->Manager,model_cx_tower_plan_line,group_manager,1,1,1,1 access_plan_line_root,Plan Line->Root,model_cx_tower_plan_line,group_root,1,1,1,1 access_plan_line_action_user,Plan Line Action->User,model_cx_tower_plan_line_action,group_user,1,0,0,0 -access_plan_line_action_manager,Plan Line Action->Manager,model_cx_tower_plan_line_action,group_manager,1,1,1,0 +access_plan_line_action_manager,Plan Line Action->Manager,model_cx_tower_plan_line_action,group_manager,1,1,1,1 access_plan_line_action_root,Plan Line Action->Root,model_cx_tower_plan_line_action,group_root,1,1,1,1 access_plan_log_user,Plan Log->User,model_cx_tower_plan_log,group_user,1,0,0,0 access_plan_log_root,Plan Log->User,model_cx_tower_plan_log,group_root,1,1,1,1 diff --git a/cetmix_tower_server/tests/test_plan.py b/cetmix_tower_server/tests/test_plan.py index d8a0b495..61b2416c 100644 --- a/cetmix_tower_server/tests/test_plan.py +++ b/cetmix_tower_server/tests/test_plan.py @@ -735,3 +735,195 @@ def test_flight_plan_copy(self): original_action.variable_value_ids.value_char, "Variable value should be the same in the copied action", ) + + def test_plan_lines_access_rights(self): + # Create a test plan with plan lines + self.plan_2 = self.Plan.create( + { + "name": "Test plan 2", + "note": "Test note", + "tag_ids": [ + (6, 0, [self.env.ref("cetmix_tower_server.tag_staging").id]) + ], + "line_ids": [ + (0, 0, {"command_id": self.command_create_dir.id, "sequence": 1}), + (0, 0, {"command_id": self.command_list_dir.id, "sequence": 2}), + ], + } + ) + # Ensure default access level is correct + self.assertEqual(self.plan_2.access_level, "2") + + # Remove user_bob from all cxtower_server groups + self.remove_from_group( + self.user_bob, + [ + "cetmix_tower_server.group_user", + "cetmix_tower_server.group_manager", + "cetmix_tower_server.group_root", + ], + ) + + # Ensure that user without any group cannot access plan lines + test_plan_2_as_bob = self.plan_2.with_user(self.user_bob) + with self.assertRaises(AccessError): + plan_line_name = test_plan_2_as_bob.line_ids[0].command_id.name + + # Add user_bob to `group_user` and test plan.line access + self.add_to_group(self.user_bob, "cetmix_tower_server.group_user") + # Set access level to 1, so group_user can access the plan lines + self.plan_2.write({"access_level": "1"}) + plan_line_name = test_plan_2_as_bob.line_ids[0].name + self.assertEqual( + plan_line_name, + "Test create directory", + msg="User should access plan lines with access_level 1", + ) + + # Add user_bob to `group_manager` and test edit rights for plan.line + self.add_to_group(self.user_bob, "cetmix_tower_server.group_manager") + test_plan_2_as_bob.write({"access_level": "2"}) + self.assertEqual(test_plan_2_as_bob.access_level, "2") + test_plan_2_as_bob.line_ids.write({"sequence": 3}) + self.assertEqual( + test_plan_2_as_bob.line_ids[0].sequence, + 3, + msg="Manager should be able to update sequence", + ) + + # Ensure that manager cannot delete plan lines they did not create + with self.assertRaises(AccessError): + test_plan_2_as_bob.line_ids[0].unlink() + + # Create a new plan line as user_bob (manager) + plan_line_as_bob = self.plan_line.with_user(self.user_bob).create( + { + "plan_id": test_plan_2_as_bob.id, + "command_id": self.command_create_dir.id, + "sequence": 10, + } + ) + + # Ensure the plan line was created and check that create_uid is user_bob + self.assertEqual( + plan_line_as_bob.create_uid.id, + self.user_bob.id, + msg="Create_uid should be user_bob", + ) + + # Check that user_bob can delete the plan line he has just created + plan_line_as_bob.unlink() + + # Ensure the plan line has been deleted + self.assertFalse( + plan_line_as_bob.exists(), + msg="Manager should be able to delete own plan line", + ) + + def test_plan_line_action_access_rights(self): + # Create a test plan with plan lines + self.plan_2 = self.Plan.create( + { + "name": "Test plan 2", + "note": "Test note", + "tag_ids": [ + (6, 0, [self.env.ref("cetmix_tower_server.tag_staging").id]) + ], + "line_ids": [ + (0, 0, {"command_id": self.command_create_dir.id, "sequence": 1}), + ], + } + ) + # Create a plan line action for the first line + self.plan_line_action = self.env["cx.tower.plan.line.action"].create( + { + "line_id": self.plan_2.line_ids[0].id, + "condition": "==", + "value_char": "0", + "action": "n", + } + ) + + # Ensure default access level is correct + self.assertEqual(self.plan_2.access_level, "2") + + # Remove user_bob from all cxtower_server groups + self.remove_from_group( + self.user_bob, + [ + "cetmix_tower_server.group_user", + "cetmix_tower_server.group_manager", + "cetmix_tower_server.group_root", + ], + ) + + # Ensure that user_bob without any group cannot access plan line actions + test_plan_line_action_as_bob = self.plan_line_action.with_user(self.user_bob) + with self.assertRaises(AccessError): + plan_line_action_read_result = test_plan_line_action_as_bob.read([]) + + # Add user_bob to `group_user` and test plan.line.action access + self.add_to_group(self.user_bob, "cetmix_tower_server.group_user") + # Set access level to 1, so group_user can access the plan line actions + self.plan_2.write({"access_level": "1"}) + self.assertEqual(test_plan_line_action_as_bob.access_level, "1") + self.plan_2.invalidate_cache() + plan_line_action_read_result = test_plan_line_action_as_bob.condition + self.assertEqual( + plan_line_action_read_result, + test_plan_line_action_as_bob.condition, + msg="User should access plan line actions with access_level 1", + ) + + # Add user_bob to `group_manager` and test plan.line.action access + self.add_to_group(self.user_bob, "cetmix_tower_server.group_manager") + # Set access level to 2, so group_manager can access the plan line action + self.plan_2.write({"access_level": "2"}) + self.assertEqual(test_plan_line_action_as_bob.access_level, "2") + # Ensure that user_bob as member of group_manager + # can read to plan line actions + plan_line_action_read_result = test_plan_line_action_as_bob.read([]) + self.assertEqual( + plan_line_action_read_result[0]["name"], + test_plan_line_action_as_bob.name, + msg="Name should be the same", + ) + + # Ensure that manager can update plan line actions they did not create + test_plan_line_action_as_bob.write({"sequence": 3}) + self.assertEqual( + test_plan_line_action_as_bob.sequence, + 3, + msg="Manager should be able to update sequence", + ) + + # Ensure that manager cannot delete plan line actions they did not create + with self.assertRaises(AccessError): + test_plan_line_action_as_bob.unlink() + + # Create a new plan line action as user_bob manager + + self.new_plan_line_action = self.env["cx.tower.plan.line.action"].create( + { + "line_id": self.plan_2.line_ids[0].id, + "condition": ">", + "value_char": "100", + "action": "e", + } + ) + + self.new_plan_line_action.write({"create_uid": self.user_bob}) + self.assertEqual( + self.new_plan_line_action.create_uid.id, + self.user_bob.id, + msg="Create_uid should be user_bob", + ) + + # # Check that user_bob can delete the plan line action he has created + self.new_plan_line_action.with_user(self.user_bob).unlink() + + # Ensure the plan line action has been deleted + self.assertFalse( + self.new_plan_line_action.exists(), + msg="Manager should be able to delete own plan line action", + )