From 5d5be956f3ec1de5b45f71fe13c229c83ddf69e4 Mon Sep 17 00:00:00 2001 From: "Xavier BOL (xbo)" Date: Thu, 26 Aug 2021 12:09:22 +0200 Subject: [PATCH] [IMP] project,hr_timesheet: enable project sharing feature when needed Before this commit, the project sharing feature is enabled by default when the Project app is installed but the user could never use the feature and thus we add more access rights to portal user for nothing. To avoid this, this commit removes by default all additional access rights given by project sharing feature and adds this access rights only when a collaborator is added. If the user removes all collaborators for all projects then we need to disable the feature. That is, we will remove the access rights and ir.rule records added. So, the feature will not really disable but we remove the additionnal access rights and ir.rule records added with this feature. task-2379518 closes #73341 --- addons/hr_timesheet/__init__.py | 4 +++ addons/hr_timesheet/__manifest__.py | 1 + addons/hr_timesheet/models/__init__.py | 1 + .../models/project_collaborator.py | 21 +++++++++++++ .../security/hr_timesheet_security.xml | 1 + .../hr_timesheet/security/ir.model.access.csv | 1 - .../hr_timesheet/security/ir.model.access.xml | 19 ++++++++++++ addons/project/__init__.py | 18 +++++++++++ addons/project/__manifest__.py | 2 ++ addons/project/models/project_collaborator.py | 30 +++++++++++++++++++ addons/project/security/ir.model.access.csv | 2 +- addons/project/security/ir.model.access.xml | 19 ++++++++++++ addons/project/security/project_security.xml | 1 + 13 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 addons/hr_timesheet/models/project_collaborator.py create mode 100644 addons/hr_timesheet/security/ir.model.access.xml create mode 100644 addons/project/security/ir.model.access.xml diff --git a/addons/hr_timesheet/__init__.py b/addons/hr_timesheet/__init__.py index ea15e1da791..5556aba9fe4 100644 --- a/addons/hr_timesheet/__init__.py +++ b/addons/hr_timesheet/__init__.py @@ -8,6 +8,8 @@ from . import wizard from odoo import api, fields, SUPERUSER_ID, _ +from odoo.addons.project import _check_exists_collaborators_for_project_sharing + def create_internal_project(cr, registry): env = api.Environment(cr, SUPERUSER_ID, {}) @@ -28,3 +30,5 @@ def create_internal_project(cr, registry): 'project_id': task.project_id.id, 'task_id': task.id, } for task in project_ids.task_ids.filtered(lambda t: t.company_id in admin.employee_ids.company_id)]) + + _check_exists_collaborators_for_project_sharing(env) diff --git a/addons/hr_timesheet/__manifest__.py b/addons/hr_timesheet/__manifest__.py index ff049b01573..4cb43356441 100644 --- a/addons/hr_timesheet/__manifest__.py +++ b/addons/hr_timesheet/__manifest__.py @@ -24,6 +24,7 @@ up a management by affair. 'data': [ 'security/hr_timesheet_security.xml', 'security/ir.model.access.csv', + 'security/ir.model.access.xml', 'data/digest_data.xml', 'views/hr_timesheet_views.xml', 'views/res_config_settings_views.xml', diff --git a/addons/hr_timesheet/models/__init__.py b/addons/hr_timesheet/models/__init__.py index 969632575ce..87061d8bb36 100644 --- a/addons/hr_timesheet/models/__init__.py +++ b/addons/hr_timesheet/models/__init__.py @@ -7,5 +7,6 @@ from . import ir_http from . import res_company from . import res_config_settings from . import project +from . import project_collaborator from . import project_update from . import uom diff --git a/addons/hr_timesheet/models/project_collaborator.py b/addons/hr_timesheet/models/project_collaborator.py new file mode 100644 index 00000000000..d2083a3258e --- /dev/null +++ b/addons/hr_timesheet/models/project_collaborator.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, models + + +class ProjectCollaborator(models.Model): + _inherit = 'project.collaborator' + + @api.model + def _toggle_project_sharing_portal_rules(self, active): + super()._toggle_project_sharing_portal_rules(active) + # ir.model.access + access_timesheet_portal = self.env.ref('hr_timesheet.access_account_analytic_line_portal_user').sudo() + if access_timesheet_portal.active != active: + access_timesheet_portal.write({'active': active}) + + # ir.rule + timesheet_portal_ir_rule = self.env.ref('hr_timesheet.timesheet_line_rule_portal_user').sudo() + if timesheet_portal_ir_rule.active != active: + access_timesheet_portal.write({'active': active}) diff --git a/addons/hr_timesheet/security/hr_timesheet_security.xml b/addons/hr_timesheet/security/hr_timesheet_security.xml index 63d1b679d9d..2c35c99bfb2 100644 --- a/addons/hr_timesheet/security/hr_timesheet_security.xml +++ b/addons/hr_timesheet/security/hr_timesheet_security.xml @@ -33,6 +33,7 @@ account.analytic.line.timesheet.portal.user + 0 [ ('project_id', '!=', False), '|', diff --git a/addons/hr_timesheet/security/ir.model.access.csv b/addons/hr_timesheet/security/ir.model.access.csv index ccddcb13a5d..db5329a5262 100644 --- a/addons/hr_timesheet/security/ir.model.access.csv +++ b/addons/hr_timesheet/security/ir.model.access.csv @@ -1,5 +1,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_account_analytic_line_portal_user,analytic.account.analytic.line.timesheet.portal.user,analytic.model_account_analytic_line,base.group_portal,1,0,0,0 access_account_analytic_line_user,analytic.account.analytic.line.timesheet.user,analytic.model_account_analytic_line,hr_timesheet.group_hr_timesheet_user,1,1,1,1 access_account_analytic_user,analytic.account.analytic.timesheet.user,analytic.model_account_analytic_account,hr_timesheet.group_hr_timesheet_user,1,1,0,0 access_uom_uom_hr_timesheet,uom.uom.timesheet.user,uom.model_uom_uom,hr_timesheet.group_hr_timesheet_user,1,0,0,0 diff --git a/addons/hr_timesheet/security/ir.model.access.xml b/addons/hr_timesheet/security/ir.model.access.xml new file mode 100644 index 00000000000..5732923928f --- /dev/null +++ b/addons/hr_timesheet/security/ir.model.access.xml @@ -0,0 +1,19 @@ + + + + + + + analytic.account.analytic.line.timesheet.portal.user + + + 0 + 1 + 0 + 0 + 0 + + + + + diff --git a/addons/project/__init__.py b/addons/project/__init__.py index e35155177e6..0f9917d22dd 100644 --- a/addons/project/__init__.py +++ b/addons/project/__init__.py @@ -6,3 +6,21 @@ from . import models from . import report from . import wizard from . import populate + +from odoo import api, SUPERUSER_ID + + +def _check_exists_collaborators_for_project_sharing(env): + """ Check if it exists at least a collaborator in a shared project + + If it is the case we need to active the portal rules added only for this feature. + """ + collaborator = env['project.collaborator'].search([], limit=1) + if collaborator: + # Then we need to enable the access rights linked to project sharing for the portal user + env['project.collaborator']._toggle_project_sharing_portal_rules(True) + + +def _project_post_init(cr, registry): + env = api.Environment(cr, SUPERUSER_ID, {}) + _check_exists_collaborators_for_project_sharing(env) diff --git a/addons/project/__manifest__.py b/addons/project/__manifest__.py index 0c28fc67a61..d635e16c866 100644 --- a/addons/project/__manifest__.py +++ b/addons/project/__manifest__.py @@ -23,6 +23,7 @@ 'data': [ 'security/project_security.xml', 'security/ir.model.access.csv', + 'security/ir.model.access.xml', 'data/digest_data.xml', 'report/project_report_views.xml', 'report/project_task_burndown_chart_report_views.xml', @@ -55,6 +56,7 @@ 'installable': True, 'auto_install': False, 'application': True, + 'post_init_hook': '_project_post_init', 'assets': { 'web.assets_backend': [ 'project/static/src/css/project.css', diff --git a/addons/project/models/project_collaborator.py b/addons/project/models/project_collaborator.py index 4268a62f705..4315e5a2a9b 100644 --- a/addons/project/models/project_collaborator.py +++ b/addons/project/models/project_collaborator.py @@ -17,7 +17,37 @@ class ProjectCollaborator(models.Model): @api.model_create_multi def create(self, vals_list): + collaborator = self.env['project.collaborator'].search([], limit=1) project_collaborators = super().create(vals_list) non_authenticated_collaborator = project_collaborators.partner_id.filtered(lambda partner: not partner.user_ids) non_authenticated_collaborator._create_portal_users() + if not collaborator: + self._toggle_project_sharing_portal_rules(True) return project_collaborators + + def unlink(self): + res = super().unlink() + # Check if it remains at least a collaborator in all shared projects. + collaborator = self.env['project.collaborator'].search([], limit=1) + if not collaborator: # then disable the project sharing feature + self._toggle_project_sharing_portal_rules(False) + return res + + @api.model + def _toggle_project_sharing_portal_rules(self, active): + """ Enable/disable project sharing feature + + When the first collaborator is added in the model then we need to enable the feature. + In the inverse case, if no collaborator is stored in the model then we disable the feature. + To enable/disable the feature, we just need to enable/disable the ir.model.access and ir.rule + added to portal user that we do not want to give when we know the project sharing is unused. + + :param active: contains boolean value, True to enable the project sharing feature, otherwise we disable the feature. + """ + access_project_sharing_portal = self.env.ref('project.access_project_sharing_task_portal').sudo() + if access_project_sharing_portal.active != active: + access_project_sharing_portal.write({'active': active}) + + task_portal_ir_rule = self.env.ref('project.project_task_rule_portal_project_sharing').sudo() + if task_portal_ir_rule.active != active: + task_portal_ir_rule.write({'active': active}) diff --git a/addons/project/security/ir.model.access.csv b/addons/project/security/ir.model.access.csv index f9637300734..35c80887da6 100644 --- a/addons/project/security/ir.model.access.csv +++ b/addons/project/security/ir.model.access.csv @@ -11,7 +11,7 @@ access_project_task,project.task,model_project_task,project.group_project_user,1 access_report_project_task_user,report.project.task.user,model_report_project_task_user,project.group_project_manager,1,1,1,1 access_partner_task_user,base.res.partner user,base.model_res_partner,project.group_project_user,1,0,0,0 access_task_on_partner,project.task on partners,model_project_task,base.group_user,1,0,0,0 -access_task_portal,task_portal,project.model_project_task,base.group_portal,1,1,1,0 +access_task_portal,task_portal,project.model_project_task,base.group_portal,1,0,0,0 access_project_user,project.project on partners,model_project_project,base.group_user,1,0,0,0 access_project_portal,project_portal,project.model_project_project,base.group_portal,1,0,0,0 access_resource_calendar,project.resource_calendar user,resource.model_resource_calendar,project.group_project_user,1,0,0,0 diff --git a/addons/project/security/ir.model.access.xml b/addons/project/security/ir.model.access.xml new file mode 100644 index 00000000000..5657be31cdd --- /dev/null +++ b/addons/project/security/ir.model.access.xml @@ -0,0 +1,19 @@ + + + + + + + project_sharing_task_portal + + + 0 + 0 + 1 + 1 + 0 + + + + + diff --git a/addons/project/security/project_security.xml b/addons/project/security/project_security.xml index 9d233304c84..84a5865ae16 100644 --- a/addons/project/security/project_security.xml +++ b/addons/project/security/project_security.xml @@ -149,6 +149,7 @@ Project/Task: portal users: portal user can edit with project sharing feature + 0 [ ('project_id.privacy_visibility', '=', 'portal'), ('active', '=', True),