[MERGE][IMP] *: settings improvements
* verify settings access for "Settings" user (`base.group_system`) * Improve loading performance through the use of conditional groups inheritance * Do not imply application administration groups for "Settings" users * Fix wrong view inheritance (views hooked on content defined in siblings, not in parent(s)) Enterprise PR: https://github.com/odoo/enterprise/pull/27595 Task - 2858427 -- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr closes odoo/odoo#91909 Related: odoo/enterprise#27595 Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
This commit is contained in:
@@ -75,11 +75,7 @@
|
||||
</record>
|
||||
|
||||
<record id="base.user_admin" model="res.users">
|
||||
<field name="groups_id" eval="[(4, ref('account.group_account_invoice'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="base.group_system" model="res.groups">
|
||||
<field name="implied_ids" eval="[(4, ref('account.group_account_manager'))]"/>
|
||||
<field name="groups_id" eval="[(4, ref('account.group_account_manager'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="group_warning_account" model="res.groups">
|
||||
|
||||
@@ -46,7 +46,11 @@ class AccountTestInvoicingCommon(TransactionCase):
|
||||
'name': 'Because I am accountman!',
|
||||
'login': 'accountman',
|
||||
'password': 'accountman',
|
||||
'groups_id': [(6, 0, cls.env.user.groups_id.ids), (4, cls.env.ref('account.group_account_user').id)],
|
||||
'groups_id': [
|
||||
(6, 0, cls.env.user.groups_id.ids),
|
||||
(4, cls.env.ref('account.group_account_manager').id),
|
||||
(4, cls.env.ref('account.group_account_user').id),
|
||||
],
|
||||
})
|
||||
user.partner_id.email = 'accountman@test.com'
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ class TestTourRenderInvoiceReport(AccountTestInvoicingHttpCommon):
|
||||
|
||||
cls.env.user.write({
|
||||
'groups_id': [
|
||||
(6, 0, (cls.env.ref('account.group_account_invoice') + cls.env.ref('base.group_system')).ids),
|
||||
(6, 0, (cls.env.ref('account.group_account_manager') + cls.env.ref('base.group_system')).ids),
|
||||
],
|
||||
})
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="40"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="groups_id" eval="[(4, ref('account.group_account_manager'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<field name="country_code" invisible="1"/>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<field name="name">res.config.settings.view.form.inherit.auth_totp_mail_enforce</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="40"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="inherit_id" ref="base_setup.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@id='allow_import']" position="before">
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="auth_totp_policy">
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="5"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="groups_id" eval="[(4, ref('sales_team.group_sale_manager'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<div class="app_settings_block" data-string="CRM" string="CRM" data-key="crm" groups="sales_team.group_sale_manager">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_delivery_carrier,delivery.carrier,model_delivery_carrier,sales_team.group_sale_salesman,1,0,0,0
|
||||
access_delivery_carrier_system,delivery.carrier,model_delivery_carrier,base.group_system,1,0,0,0
|
||||
access_delivery_price_rule,delivery.price.rule,model_delivery_price_rule,sales_team.group_sale_salesman,1,0,0,0
|
||||
access_delivery_carrier_manager,delivery.carrier,model_delivery_carrier,sales_team.group_sale_manager,1,1,1,1
|
||||
access_delivery_price_rule_manager,delivery.price.rule,model_delivery_price_rule,sales_team.group_sale_manager,1,1,1,1
|
||||
|
||||
|
@@ -6,6 +6,7 @@
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="65"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="groups_id" eval="[(4, ref('event.group_event_manager'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<div class="app_settings_block" data-string="Events" string="Events" data-key="event" groups="event.group_event_manager">
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="90"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="groups_id" eval="[(4, ref('fleet.fleet_group_manager'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<div class="app_settings_block" data-string="Fleet" id="fleet" string="Fleet" data-key="fleet" groups="fleet.fleet_group_manager">
|
||||
|
||||
@@ -20,5 +20,11 @@
|
||||
<field name="perm_unlink" eval="0"/>
|
||||
<field name="perm_read" eval="1"/>
|
||||
</record>
|
||||
<record id="google_calendar_token_system_access" model="ir.rule">
|
||||
<field name="name">Google Calendar manage all tokens</field>
|
||||
<field name="model_id" ref="model_google_calendar_credentials"/>
|
||||
<field name="domain_force">[(1,'=',1)]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_system'))]"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -2,7 +2,7 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_hr_employee_category_user,hr.employee.category.user,model_hr_employee_category,group_hr_user,1,1,1,1
|
||||
access_hr_employee_category_emp,hr.employee.category.emp,model_hr_employee_category,base.group_user,1,0,0,0
|
||||
access_hr_employee_user,hr.employee user,model_hr_employee,group_hr_user,1,1,1,1
|
||||
access_hr_employee_system_user,hr.employee system user,model_hr_employee,base.group_user,0,0,0,0
|
||||
access_hr_employee_system_user,hr.employee system user,model_hr_employee,base.group_system,1,0,0,0
|
||||
access_hr_employee_public_user,hr.employee_public,model_hr_employee_public,base.group_user,1,0,0,0
|
||||
access_hr_employee_resource_user,resource.resource.user,resource.model_resource_resource,group_hr_user,1,1,1,1
|
||||
access_hr_department_user,hr.department.user,model_hr_department,group_hr_user,1,1,1,1
|
||||
|
||||
|
@@ -5,6 +5,7 @@
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="70"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="groups_id" eval="[(4, ref('hr.group_hr_manager'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<div class="app_settings_block" data-string="Employees" string="Employees" data-key="hr" groups="hr.group_hr_manager">
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="80"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="groups_id" eval="[(4, ref('hr_attendance.group_hr_attendance_manager'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<div class="app_settings_block" data-string="Attendances" string="Attendances" data-key="hr_attendance" groups="hr_attendance.group_hr_attendance_manager">
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="85"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="groups_id" eval="[(4, ref('hr_expense.group_hr_expense_manager'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<div class="app_settings_block" data-string="Expenses" string="Expenses" data-key="hr_expense" groups="hr_expense.group_hr_expense_manager">
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="75"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="groups_id" eval="[(4, ref('hr_recruitment.group_hr_recruitment_manager'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<div class="app_settings_block" data-string="Recruitment" string="Recruitment" data-key="hr_recruitment" groups="hr_recruitment.group_hr_recruitment_manager">
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="55"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="groups_id" eval="[(4, ref('hr_timesheet.group_timesheet_manager'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//form" position="attributes">
|
||||
<attribute name="js_class">hr_timesheet_config_form</attribute>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="90"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="groups_id" eval="[(4, ref('lunch.group_lunch_manager'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<div class="app_settings_block" data-string="Lunch" string="Lunch" data-key="lunch" groups="lunch.group_lunch_manager">
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="60"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="groups_id" eval="[(4, ref('mass_mailing.group_mass_mailing_user'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<div class="app_settings_block" data-string="Email Marketing" string="Email Marketing" data-key="mass_mailing" groups="mass_mailing.group_mass_mailing_user">
|
||||
|
||||
@@ -27,7 +27,7 @@ class ResConfigSettings(models.TransientModel):
|
||||
super().set_values()
|
||||
if not self.group_mrp_workorder_dependencies:
|
||||
# Disabling this option should not interfere with currently planned productions
|
||||
self.env['mrp.bom'].search([('allow_operation_dependencies', '=', True)]).allow_operation_dependencies = False
|
||||
self.env['mrp.bom'].sudo().search([('allow_operation_dependencies', '=', True)]).allow_operation_dependencies = False
|
||||
|
||||
@api.onchange('use_manufacturing_lead')
|
||||
def _onchange_use_manufacturing_lead(self):
|
||||
|
||||
@@ -40,10 +40,6 @@
|
||||
<field name="category_id" ref="base.module_category_hidden"/>
|
||||
</record>
|
||||
|
||||
<record id="base.group_system" model="res.groups">
|
||||
<field name="implied_ids" eval="[(4, ref('mrp.group_mrp_manager'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="group_mrp_workorder_dependencies" model="res.groups">
|
||||
<field name="name">Use Operation Dependencies</field>
|
||||
<field name="category_id" ref="base.module_category_hidden"/>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="35"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form" />
|
||||
<field name="groups_id" eval="[(4, ref('mrp.group_mrp_manager'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<div class="app_settings_block" data-string="Manufacturing" string="Manufacturing" data-key="mrp" groups="mrp.group_mrp_manager">
|
||||
|
||||
@@ -35,6 +35,7 @@ access_product_pricelist_user,product.pricelist user,product.model_product_price
|
||||
access_product_tag_pos_manager,product.tag.pos.manager,product.model_product_tag,group_pos_manager,1,1,1,1
|
||||
access_pos_session_user,pos.session user,model_pos_session,group_pos_user,1,1,1,0
|
||||
access_pos_config_user,pos.config user,model_pos_config,group_pos_user,1,1,0,0
|
||||
access_pos_config_system_user,pos.config system,model_pos_config,base.group_system,1,1,0,0
|
||||
access_pos_config_manager,pos.config manager,model_pos_config,group_pos_manager,1,1,1,1
|
||||
access_product_category_pos_manager,pos.category manager,model_pos_category,group_pos_manager,1,1,1,1
|
||||
access_product_category_pos_user,pos.category user,model_pos_category,group_pos_user,1,0,0,0
|
||||
|
||||
|
@@ -5,6 +5,7 @@
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="95"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form" />
|
||||
<field name="groups_id" eval="[(4, ref('point_of_sale.group_pos_manager'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<field name="pos_selectable_categ_ids" invisible="1"/>
|
||||
@@ -14,6 +15,7 @@
|
||||
<field name="pos_iface_print_via_proxy" invisible="1"/>
|
||||
<field name="pos_company_has_template" invisible="1"/>
|
||||
<field name="is_default_pricelist_displayed" invisible="1"/>
|
||||
<field name="group_cash_rounding" invisible="1"/>
|
||||
|
||||
<div class="app_settings_block" data-string="Point of sale" string="Point of Sale" data-key="point_of_sale" groups="point_of_sale.group_pos_manager">
|
||||
<div id="pos_header" class="row o_settings_container mb-0 mt-0 ml-0 mw-100"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<field name="name">res.config.settings.view.form.inherit.portal</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="40"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="inherit_id" ref="base_setup.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//button[@name=%(base.action_apikeys_admin)d]//ancestor::div[hasclass('o_setting_box')]" position="inside">
|
||||
<div groups="base.group_no_one">
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="50"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form" />
|
||||
<field name="groups_id" eval="[(4, ref('project.group_project_manager'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<div class="app_settings_block" data-string="Project" string="Project" data-key="project" groups="project.group_project_manager">
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="25"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="groups_id" eval="[(4, ref('purchase.group_purchase_manager'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<div class="app_settings_block" data-string="Purchase" string="Purchase" data-key="purchase" groups="purchase.group_purchase_manager">
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
<field name="name">res.config.settings.view.form.inherit.sale</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form" />
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="groups_id" eval="[(4, ref('sales_team.group_sale_manager'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<div class="app_settings_block o_not_app"
|
||||
|
||||
@@ -18,10 +18,10 @@ class ResConfigSettings(models.TransientModel):
|
||||
[],
|
||||
)
|
||||
sale_line_ids = milestone_read_group[0]['sale_line_ids'] if milestone_read_group else []
|
||||
sale_lines = self.env['sale.order.line'].browse(sale_line_ids)
|
||||
sale_lines = self.env['sale.order.line'].sudo().browse(sale_line_ids)
|
||||
sale_lines.product_id.service_policy = 'delivered_milestones'
|
||||
else:
|
||||
product_domain = [('type', '=', 'service'), ('service_type', '=', 'milestones')]
|
||||
products = self.env['product.product'].search(product_domain)
|
||||
products.service_policy = 'delivered_manual'
|
||||
self.env['sale.order.line'].search([('product_id', 'in', products.ids)]).qty_delivered_method = 'manual'
|
||||
self.env['sale.order.line'].sudo().search([('product_id', 'in', products.ids)]).qty_delivered_method = 'manual'
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="30"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form" />
|
||||
<field name="groups_id" eval="[(4, ref('stock.group_stock_manager'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside" >
|
||||
<div class="app_settings_block" data-string="Inventory" string="Inventory" data-key="stock" groups="stock.group_stock_manager">
|
||||
|
||||
@@ -23,10 +23,6 @@
|
||||
<field name="groups_id" eval="[(4, ref('website.group_website_designer'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="base.group_system" model="res.groups">
|
||||
<field name="implied_ids" eval="[(4, ref('website.group_website_designer'))]"/>
|
||||
</record>
|
||||
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="website_designer_edit_qweb" model="ir.rule">
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="res_config_settings_view_form_inherit_auth_signup" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.website</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="auth_signup.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<!-- Remove customer accounts setting from general settings tab -->
|
||||
<!-- It must not be in the view at all to make sure settings can be saved
|
||||
(because auth_signup_uninvited is specified as required) -->
|
||||
<xpath expr="//div[@id='login_documents']" position="replace"></xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="res_config_settings_view_form" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.website</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="groups_id" eval="[(4, ref('website.group_website_designer'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<!-- Remove customer accounts setting from general settings tab -->
|
||||
<xpath expr="//div[@id='login_documents']" position="attributes">
|
||||
<attribute name="invisible">1</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||
<div class="app_settings_block" data-string="Website" string="Website" data-key="website" groups="website.group_website_designer">
|
||||
<div class="row o_settings_container mb-0 mt-0 ml-0 mw-100"
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
<field name="name">res.config.settings.view.form.inherit.website</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="inherit_id" ref="website.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('settings')]//div[@id='website_settings']" position="inside">
|
||||
<!-- TODO TDE there are two div with website_settings id in the website settings view -->
|
||||
<xpath expr="//div[@id='website_settings']" position="inside">
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="events_app_setting" groups="base.group_no_one">
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="events_app_name" string="Events PWA"/>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<field name="name">res.config.settings.view.form.inherit.website</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="inherit_id" ref="website.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<div id="website_info_settings" position="after">
|
||||
<h2>Shop - Payment</h2>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<field name="name">res.config.settings.view.form.inherit.payment.authorize</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="priority" eval="20"/>
|
||||
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||
<field name="inherit_id" ref="website_payment.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<div id="paypal_settings" position="before">
|
||||
<div class="col-12 col-lg-6 o_setting_box">
|
||||
|
||||
@@ -18,15 +18,23 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="res_config_settings_view_form_inherit_sale" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.sale</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="sale.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<!-- Remove customer accounts setting from sales settings tab -->
|
||||
<!-- It must not be in the view at all to make sure settings can be saved
|
||||
(because auth_signup_uninvited is specified as required) -->
|
||||
<xpath expr="//div[@id='auth_signup_documents']" position="replace"></xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="res_config_settings_view_form" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.website.sale</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="website.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<!-- Remove customer accounts setting from sales settings tab -->
|
||||
<xpath expr="//div[@id='auth_signup_documents']" position="attributes">
|
||||
<attribute name="invisible">1</attribute>
|
||||
</xpath>
|
||||
<div id="website_info_settings" position="after">
|
||||
<h2>Shop - Checkout Process</h2>
|
||||
<div class="row mt16 o_settings_container" id="website_shop_checkout">
|
||||
|
||||
@@ -20,10 +20,6 @@
|
||||
<field name="groups_id" eval="[(4,ref('group_website_slides_manager'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="base.group_system" model="res.groups">
|
||||
<field name="implied_ids" eval="[(4, ref('group_website_slides_manager'))]"/>
|
||||
</record>
|
||||
|
||||
<data noupdate="1">
|
||||
<!-- CHANNEL -->
|
||||
<record id="rule_slide_channel_global" model="ir.rule">
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<field name="name">res.config.settings.view.form.inherit.website.slides</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="website.res_config_settings_view_form"/>
|
||||
<field name="groups_id" eval="[(4, ref('website_slides.group_website_slides_manager'), 0)]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@id='website_marketing_automation']" position="after">
|
||||
<div class="col-12 col-lg-6 o_setting_box" id="slides_install_setting">
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
-->
|
||||
<record model="res.groups" id="group_erp_manager">
|
||||
<field name="name">Access Rights</field>
|
||||
<field name="implied_ids" eval="[Command.link(ref('group_user'))]"/>
|
||||
</record>
|
||||
|
||||
<record model="res.groups" id="group_system">
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from collections import defaultdict
|
||||
import logging
|
||||
|
||||
from odoo import exceptions
|
||||
from odoo.tests.common import TransactionCase, tagged
|
||||
from odoo import exceptions, Command
|
||||
from odoo.tests.common import Form, TransactionCase, tagged
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -97,3 +98,86 @@ class TestResConfigExecute(TransactionCase):
|
||||
for config_settings in all_config_settings:
|
||||
_logger.info("Testing %s" % (config_settings.name))
|
||||
self.env[config_settings.name].create({}).execute()
|
||||
|
||||
def test_settings_access(self):
|
||||
"""Check that settings user are able to open & save settings
|
||||
|
||||
Also check that user with settings rights + any one of the groups restricting
|
||||
a conditional view inheritance of res.config.settings view is also able to
|
||||
open & save the settings (considering the added conditional content)
|
||||
"""
|
||||
ResUsers = self.env['res.users']
|
||||
group_system = self.env.ref('base.group_system')
|
||||
self.settings_view = self.env.ref('base.res_config_settings_view_form')
|
||||
settings_only_user = ResUsers.create({
|
||||
'name': 'Sleepy Joe',
|
||||
'login': 'sleepy',
|
||||
'groups_id': [Command.link(group_system.id)],
|
||||
})
|
||||
|
||||
_logger.info("Testing settings access for group %s", group_system.full_name)
|
||||
forbidden_models = self._test_user_settings_fields_access(settings_only_user)
|
||||
self._test_user_settings_view_save(settings_only_user)
|
||||
|
||||
for model in forbidden_models:
|
||||
_logger.warning("Settings user doesn\'t have read access to the model %s", model)
|
||||
|
||||
settings_view_conditional_groups = self.env['ir.ui.view'].search([
|
||||
('model', '=', 'res.config.settings'),
|
||||
]).groups_id
|
||||
|
||||
for group in settings_view_conditional_groups:
|
||||
group_name = group.full_name
|
||||
_logger.info("Testing settings access for group %s", group_name)
|
||||
create_values = {
|
||||
'name': f'Test {group_name}',
|
||||
'login': group_name,
|
||||
'groups_id': [Command.link(group_system.id), Command.link(group.id)]
|
||||
}
|
||||
user = ResUsers.create(create_values)
|
||||
self._test_user_settings_view_save(user)
|
||||
forbidden_models_fields = self._test_user_settings_fields_access(user)
|
||||
|
||||
for model, fields in forbidden_models_fields.items():
|
||||
_logger.warning(
|
||||
"Settings + %s user doesn\'t have read access to the model %s"
|
||||
"linked to settings records by the field(s) %s",
|
||||
group_name, model, ", ".join(str(field) for field in fields)
|
||||
)
|
||||
|
||||
def _test_user_settings_fields_access(self, user):
|
||||
"""Verify that settings user are able to create & save settings."""
|
||||
settings = self.env['res.config.settings'].with_user(user).create({})
|
||||
|
||||
# Save the settings
|
||||
settings.set_values()
|
||||
|
||||
# Check user has access to all models of relational fields in view
|
||||
# because the webclient makes a name_get request for all specified records
|
||||
# even if they are not shown to the user.
|
||||
settings_view_arch = self.settings_view.with_user(user)._get_combined_arch()
|
||||
seen_fields = set()
|
||||
for node in settings_view_arch.iterdescendants(tag='field'):
|
||||
seen_fields.add(node.get('name'))
|
||||
|
||||
models_to_check = defaultdict(set)
|
||||
for field_name in seen_fields:
|
||||
field = settings._fields[field_name]
|
||||
if field.relational:
|
||||
models_to_check[field.comodel_name].add(field)
|
||||
|
||||
forbidden_models_fields = defaultdict(set)
|
||||
for model in models_to_check:
|
||||
has_read_access = self.env[model].with_user(user).check_access_rights(
|
||||
'read', raise_exception=False)
|
||||
if not has_read_access:
|
||||
forbidden_models_fields[model] = models_to_check[model]
|
||||
|
||||
return forbidden_models_fields
|
||||
|
||||
def _test_user_settings_view_save(self, user):
|
||||
"""Verify that settings user are able to save the settings form."""
|
||||
ResConfigSettings = self.env['res.config.settings'].with_user(user)
|
||||
|
||||
settings_form = Form(ResConfigSettings)
|
||||
settings_form.save()
|
||||
|
||||
@@ -33,7 +33,7 @@ class TestActionBindings(common.TransactionCase):
|
||||
)
|
||||
|
||||
# add a group on an action, and check that it is not returned
|
||||
group = self.env.ref('base.group_user')
|
||||
group = self.env.ref('base.group_system')
|
||||
action2.groups_id += group
|
||||
self.env.user.groups_id -= group
|
||||
|
||||
|
||||
Reference in New Issue
Block a user