Skip to content
Snippets Groups Projects
Commit cf63d4d2 authored by Martin Trigaux's avatar Martin Trigaux Committed by Antony Lesuisse
Browse files

[FIX] share,base: avoid loading order issues

Move share column to base instead of module share.

The column is used to filter some groups and make them hidden from the res.users
form. However, if a module was loaded before the module share (e.g. depends only
from base), when upgraded, the eventual update of a res.group regenerated the
res.user view (to compute in_group_XX fields). This recomputation was done
before the module share was loaded in the registry (due to the dependency graph)
and the override of get_application_groups was not done, including shared groups
in the user form.

As we can not guarantee that a module is loaded, better to move to base module.
As share depends only of mail and is autoinstall, it was installed on most
instances anyway.

Fixes #6324
Fixes #5820
parent 10f81cce
No related branches found
No related tags found
No related merge requests found
......@@ -16,18 +16,6 @@
</field>
</record>
<!-- Force update of groups' user view.
When updating (not new install), as `share` module is not loaded yet, shared groups
are taken into account when getting the group list, resulting to a different
organisation of the `Sharing` category (booleans instead of a selection) and thus,
different virtual field names.
When applying then inheritance of the following view, the check of field names
failed due to these virtual field name missmatch.
This is only for databases updated between a6eac0f08ee9100d1a44a4068d4f580b1c7c4b2c
and the commit introducing this line.
-->
<function model="res.groups" name="update_user_groups_view" />
<!-- Update user form !-->
<record id="view_users_form_mail" model="ir.ui.view">
<field name="name">res.users.form.mail</field>
......
......@@ -2,5 +2,4 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import ir_model
import res_users
import wizard
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from openerp.osv import fields, osv
from openerp import SUPERUSER_ID
class res_users(osv.osv):
_name = 'res.users'
_inherit = 'res.users'
def _is_share(self, cr, uid, ids, name, args, context=None):
res = {}
for user in self.browse(cr, uid, ids, context=context):
res[user.id] = not self.has_group(cr, user.id, 'base.group_user')
return res
def _get_users_from_group(self, cr, uid, ids, context=None):
result = set()
groups = self.pool['res.groups'].browse(cr, uid, ids, context=context)
# Clear cache to avoid perf degradation on databases with thousands of users
groups.invalidate_cache()
for group in groups:
result.update(user.id for user in group.users)
return list(result)
_columns = {
'share': fields.function(_is_share, string='Share User', type='boolean',
store={
'res.users': (lambda self, cr, uid, ids, c={}: ids, None, 50),
'res.groups': (_get_users_from_group, None, 50),
}, help="External user with limited access, created only for the purpose of sharing data."),
}
class res_groups(osv.osv):
_name = "res.groups"
_inherit = 'res.groups'
_columns = {
'share': fields.boolean('Share Group', readonly=True,
help="Group created to set access rights for sharing data with some users.")
}
def init(self, cr):
# force re-generation of the user groups view without the shared groups
self.update_user_groups_view(cr, SUPERUSER_ID)
parent_class = super(res_groups, self)
if hasattr(parent_class, 'init'):
parent_class.init(cr)
def get_application_groups(self, cr, uid, domain=None, context=None):
if domain is None:
domain = []
domain.append(('share', '=', False))
return super(res_groups, self).get_application_groups(cr, uid, domain=domain, context=context)
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record model="ir.ui.view" id="res_users_search_sharing">
<field name="name">res.users.search.share</field>
<field name="model">res.users</field>
<field name="inherit_id" ref="base.view_users_search"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='company_ids']" position="after">
<filter name="no_share" string="Regular users only (no share user)" icon="terp-partner"
domain="[('share','=',False)]"/>
</xpath>
<xpath expr="//field[@name='company_ids']" position="after">
<field name="share"/>
</xpath>
</field>
</record>
<!-- Hide share users/groups by default -->
<record model="ir.actions.act_window" id="base.action_res_users">
<field name="name">Users</field>
<field name="context">{'search_default_no_share': 1}</field>
</record>
<record model="ir.ui.view" id="res_groups_search_sharing">
<field name="name">res.groups.search.share</field>
<field name="model">res.groups</field>
<field name="inherit_id" ref="base.view_groups_search"/>
<field name="arch" type="xml">
<field name="name" position="after">
<filter name="share" string="Share Groups" domain="[('share','=',True)]"/>
<filter name="no_share" string="Non-Share Groups" domain="[('share','=',False)]"/>
<separator orientation="vertical"/>
</field>
</field>
</record>
<!-- Hide share users/groups by default -->
<record model="ir.actions.act_window" id="base.action_res_groups">
<field name="name">Groups</field>
<field name="context">{'search_default_no_share': 1}</field>
</record>
<record id="view_groups_form_share" model="ir.ui.view">
<field name="name">res.groups.form</field>
<field name="model">res.groups</field>
<field name="inherit_id" ref="base.view_groups_form"/>
<field name="arch" type="xml">
<field name="users" position="attributes">
<attribute name="context">{'search_default_no_share':1}</attribute>
</field>
<field name="name" position="after">
<field name="share"/>
</field>
</field>
</record>
</data>
</openerp>
......@@ -85,6 +85,8 @@ class res_groups(osv.osv):
'comment' : fields.text('Comment', size=250, translate=True),
'category_id': fields.many2one('ir.module.category', 'Application', select=True),
'full_name': fields.function(_get_full_name, type='char', string='Group Name', fnct_search=_search_group),
'share': fields.boolean('Share Group',
help="Group created to set access rights for sharing data with some users.")
}
_sql_constraints = [
......@@ -146,6 +148,21 @@ class res_users(osv.osv):
def _get_password(self, cr, uid, ids, arg, karg, context=None):
return dict.fromkeys(ids, '')
def _is_share(self, cr, uid, ids, name, args, context=None):
res = {}
for user in self.browse(cr, uid, ids, context=context):
res[user.id] = not self.has_group(cr, user.id, 'base.group_user')
return res
def _get_users_from_group(self, cr, uid, ids, context=None):
result = set()
groups = self.pool['res.groups'].browse(cr, uid, ids, context=context)
# Clear cache to avoid perf degradation on databases with thousands of users
groups.invalidate_cache()
for group in groups:
result.update(user.id for user in group.users)
return list(result)
_columns = {
'id': fields.integer('ID'),
'login_date': fields.datetime('Latest connection', select=1, copy=False),
......@@ -171,6 +188,11 @@ class res_users(osv.osv):
'company_id': fields.many2one('res.company', 'Company', required=True,
help='The company this user is currently working for.', context={'user_preference': True}),
'company_ids':fields.many2many('res.company','res_company_users_rel','user_id','cid','Companies'),
'share': fields.function(_is_share, string='Share User', type='boolean',
store={
'res.users': (lambda self, cr, uid, ids, c={}: ids, None, 50),
'res.groups': (_get_users_from_group, None, 50),
}, help="External user with limited access, created only for the purpose of sharing data."),
}
# overridden inherited fields to bypass access rights, in case you have
......@@ -759,7 +781,10 @@ class groups_view(osv.osv):
return True
def get_application_groups(self, cr, uid, domain=None, context=None):
return self.search(cr, uid, domain or [])
if domain is None:
domain = []
domain.append(('share', '=', False))
return self.search(cr, uid, domain, context=context)
def get_groups_by_application(self, cr, uid, context=None):
""" return all groups classified by application (module category), as a list of pairs:
......
......@@ -43,6 +43,8 @@
<field name="arch" type="xml">
<search string="Groups">
<field name="name" filter_domain="['|', ('name','ilike',self), ('category_id','ilike',self)]" string="Group"/>
<field name="share"/>
<filter name="no_share" string="Internal Groups" domain="[('share','=',False)]"/>
</search>
</field>
</record>
......@@ -55,10 +57,11 @@
<group col="4">
<field name="category_id"/>
<field name="name"/>
<field name="share"/>
</group>
<notebook>
<page string="Users">
<field name="users"/>
<field name="users" context="{'search_default_no_share':1}"/>
</page>
<page string="Inherited">
<label string="Users added to this group are automatically added in the following groups."/>
......@@ -115,6 +118,7 @@
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.groups</field>
<field name="view_type">form</field>
<field name="context">{'search_default_no_share': 1}</field>
<field name="help">A group is a set of functional areas that will be assigned to the user in order to give them access and rights to specific applications and tasks in the system. You can create custom groups or edit the ones existing by default in order to customize the view of the menu that users will be able to see. Whether they can have a read, write, create and delete access right can be managed from here.</field>
</record>
<menuitem action="action_res_groups" id="menu_action_res_groups" parent="base.menu_users" groups="base.group_no_one" sequence="3"/>
......@@ -231,6 +235,8 @@
<search string="Users">
<field name="name" filter_domain="['|', '|', ('name','ilike',self), ('login','ilike',self), ('email','ilike',self)]" string="User"/>
<field name="company_ids" string="Company" groups="base.group_multi_company"/>
<field name="share"/>
<filter name="no_share" string="Internal Users" domain="[('share','=',False)]"/>
</search>
</field>
</record>
......@@ -250,6 +256,7 @@
<field name="view_type">form</field>
<field name="view_id" ref="view_users_tree"/>
<field name="search_view_id" ref="view_users_search"/>
<field name="context">{'search_default_no_share': 1}</field>
<field name="help">Create and manage users that will connect to the system. Users can be deactivated should there be a period of time during which they will/should not connect to the system. You can assign them groups in order to give them specific access to the applications they need to use in the system.</field>
</record>
<record id="action_res_users_view1" model="ir.actions.act_window.view">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment