[IMP] portal,share: moved option for group share to portal module + existing users option. Fixed obj1/2/3 classes to skip obj0 during processing of relationships.
bzr revid: odo@openerp.com-20110617092305-2c55z5hs2uickv5o
This commit is contained in:
@@ -41,6 +41,7 @@ module 'share'.
|
||||
'security/ir.model.access.csv',
|
||||
'portal_view.xml',
|
||||
'wizard_view.xml',
|
||||
'wizard/share_wizard_view.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'certificate' : '',
|
||||
|
||||
@@ -4,7 +4,14 @@
|
||||
<record id="group_portal_manager" model="res.groups">
|
||||
<field name="name">Portal / Manager</field>
|
||||
<field name="comment">
|
||||
Members of this groups have access to the portal definitions, and can easily manage the users, access right and menus of portal users.</field>
|
||||
Members of this groups have access to the portal definitions, and can easily manage the users, access right and menus of portal users.
|
||||
Members of this group who are also members of the Sharing/User group get additional options in the sharing wizard:
|
||||
- they may select a list of existing users to share with, without having to give a list of emails
|
||||
- they may choose to share with a Portal group instead of sharing with users, effectively extending the Portal content
|
||||
These features are useful for setting up Portals, but this could result in an alteration of the system's security policy.
|
||||
Therefore this should be granted only to trustworthy users who know the security policy very well.
|
||||
This group must not be deleted.</field>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -19,7 +19,7 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv
|
||||
from osv import osv, fields
|
||||
|
||||
UID_ROOT = 1
|
||||
SHARED_DOCS_MENU = "Documents"
|
||||
@@ -30,6 +30,36 @@ class share_wizard_portal(osv.osv_memory):
|
||||
menus in the selected portal upon sharing with a portal group."""
|
||||
_inherit = "share.wizard"
|
||||
|
||||
_columns = {
|
||||
'user_ids': fields.many2many('res.users', 'share_wizard_res_user_rel', 'share_id', 'user_id', 'Existing users', domain=[('share', '=', True)]),
|
||||
'group_ids': fields.many2many('res.groups', 'share_wizard_res_group_rel', 'share_id', 'group_id', 'Existing groups', domain=[('share', '=', False)]),
|
||||
}
|
||||
|
||||
def is_portal_manager(self, cr, uid, context=None):
|
||||
return self.has_group(cr, uid, module='portal', group_xml_id='group_portal_manager', context=context)
|
||||
|
||||
def has_share(self, cr, uid, context=None):
|
||||
return self.has_extended_share(cr, uid, context=context) or \
|
||||
super(share_wizard_portal, self).has_share(cr, uid, context=context)
|
||||
|
||||
def _user_type_selection(self, cr, uid, context=None):
|
||||
selection = super(share_wizard_portal, self)._user_type_selection(cr, uid, context=context)
|
||||
if self.is_portal_manager(cr, uid, context=context):
|
||||
selection.extend([('existing','Users you already shared with'),
|
||||
('groups','Portal Groups')])
|
||||
return selection
|
||||
|
||||
def _check_preconditions(self, cr, uid, wizard_data, context=None):
|
||||
if wizard_data.user_type == 'existing':
|
||||
self._assert(wizard_data.user_ids,
|
||||
_('Please select at least one user to share with'),
|
||||
context=context)
|
||||
elif wizard_data.user_type == 'groups':
|
||||
self._assert(wizard_data.group_ids,
|
||||
_('Please select at least one group to share with'),
|
||||
context=context)
|
||||
return super(share_wizard_portal, self)._check_preconditions(cr, uid, wizard_data, context=context)
|
||||
|
||||
def _create_or_get_submenu_named(self, cr, uid, parent_menu_id, menu_name, context=None):
|
||||
if not parent_menu_id:
|
||||
return
|
||||
@@ -83,10 +113,26 @@ class share_wizard_portal(osv.osv_memory):
|
||||
return menu_id
|
||||
|
||||
def _create_share_users_groups(self, cr, uid, wizard_data, context=None):
|
||||
"""Create sharing menus in portal menu after sharing"""
|
||||
group_ids = super(share_wizard_portal,self)._create_share_users_groups(cr, uid, wizard_data, context=context)
|
||||
if wizard_data.user_type == "groups":
|
||||
"""Creates the appropriate shared users and groups, and populates
|
||||
result_line_ids of wizard_data with one line for each user.
|
||||
|
||||
:return: group_ids (to which the shared access should be granted),
|
||||
new_user_ids, and existing_user_ids.
|
||||
"""
|
||||
group_ids, new_ids, existing_ids = [], [], []
|
||||
|
||||
if wizard_data.user_type == 'groups':
|
||||
group_id = None
|
||||
group_ids.extend([g.id for g in wizard_data.group_ids])
|
||||
# populate result lines with the users of each group
|
||||
for group in wizard_data.group_ids:
|
||||
for user in group.users:
|
||||
new_line = {'login': user.login,
|
||||
'newly_created': False}
|
||||
wizard_data.write({'result_line_ids': [(0,0,new_line)]})
|
||||
|
||||
# get the list of portals and the related groups
|
||||
# and install their menus.
|
||||
Portals = self.pool.get('res.portal')
|
||||
all_portals = Portals.browse(cr, UID_ROOT, Portals.search(cr, UID_ROOT, [])) #no context!
|
||||
all_portal_group_ids = [p.group_id.id for p in all_portals]
|
||||
@@ -94,6 +140,24 @@ class share_wizard_portal(osv.osv_memory):
|
||||
if group.id in all_portal_group_ids:
|
||||
portal = all_portals[all_portal_group_ids.index(group.id)]
|
||||
self._create_shared_data_menu(cr, uid, wizard_data, portal, context=context)
|
||||
return group_ids
|
||||
|
||||
else:
|
||||
# for other case with user_type in ('emails', 'existing'), we rely on super()
|
||||
group_ids, new_ids, existing_ids = super(share_wizard_portal,self)._create_share_users_groups(cr, uid, wizard_data, context=context)
|
||||
|
||||
# must take care of existing users, by adding them to the new group, which is group_ids[0],
|
||||
# and adding the shortcut
|
||||
existing_user_ids = [x.id for x in wizard_data.user_ids] # manually selected users
|
||||
if existing_user_ids:
|
||||
self.pool.get('res.users').write(cr, UID_ROOT, existing_user_ids, {'groups_id': [(4,group_id)]})
|
||||
self._setup_action_and_shortcut(cr, uid, wizard_data, existing_ids, make_home=False, context=context)
|
||||
existing_ids.extend(existing_user_ids)
|
||||
# populate the result lines for existing users too
|
||||
for user in wizard_data.user_ids:
|
||||
new_line = { 'login': user.login,
|
||||
'newly_created': False}
|
||||
wizard_data.write({'result_line_ids': [(0,0,new_line)]})
|
||||
|
||||
return group_ids, new_ids, existing_ids
|
||||
|
||||
share_wizard_portal()
|
||||
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="share_step1_form_portal" model="ir.ui.view">
|
||||
<field name="name">share.step1.form.portal</field>
|
||||
<field name="model">share.wizard</field>
|
||||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="share.share_step1_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/form/group[@name='emails_group']" position="before">
|
||||
<group colspan="4" col="4" groups="portal.group_portal_manager">
|
||||
<separator colspan="4" string="Who do you want to share with?"/>
|
||||
<field name="user_type" />
|
||||
</group>
|
||||
<group colspan="4" attrs="{'invisible':[('user_type','!=','existing')]}">
|
||||
<field colspan="4" nolabel="1" name="user_ids" mode="tree">
|
||||
<tree string="Existing users">
|
||||
<field name="login"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
<group colspan="4" attrs="{'invisible':[('user_type','!=','groups')]}">
|
||||
<separator colspan="4" string="Existing Groups"/>
|
||||
<field colspan="4" nolabel="1" name="group_ids" mode="tree">
|
||||
<tree string="Existing groups">
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="share_step2_form_portal" model="ir.ui.view">
|
||||
<field name="name">share.step2.form.portal</field>
|
||||
<field name="model">share.wizard</field>
|
||||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="share.share_step2_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/form/field[@name='result_line_ids']/tree/field[@name='login']" position="after">
|
||||
<field name="share_url" groups="portal.group_portal_manager"/>
|
||||
</xpath>
|
||||
<xpath expr="/form/field[@name='result_line_ids']/form/field[@name='login']" position="after">
|
||||
<field name="share_url" colspan="4" groups="portal.group_portal_manager"/>
|
||||
</xpath>
|
||||
<xpath expr="/form/field[@name='result_line_ids']" position="after">
|
||||
<field colspan="4" name="share_root_url" groups="portal.group_portal_manager"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -6,14 +6,5 @@
|
||||
<field name="comment">
|
||||
Members of this groups have access to the sharing wizard, which allows them to invite external users to view or edit some of their documents.</field>
|
||||
</record>
|
||||
|
||||
<record id="group_share_user_extended" model="res.groups">
|
||||
<field name="name">Sharing / Share With Groups</field>
|
||||
<field name="comment">
|
||||
Members of this group are allowed to share documents with Groups in addition to Users, and have a few more options in the share wizard. This is useful for setting up Portals
|
||||
with the portal module, but this could result in an alteration of the system's security policy.
|
||||
Therefore this should be granted only to trustworthy users who know the security policy very well.
|
||||
This group should not be deleted.</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -24,7 +24,7 @@ import time
|
||||
|
||||
import tools
|
||||
from osv import osv, fields
|
||||
from osv.expression import expression
|
||||
from osv import expression
|
||||
from tools.translate import _
|
||||
from tools.safe_eval import safe_eval
|
||||
|
||||
@@ -74,8 +74,7 @@ def get_column_infos(osv_model):
|
||||
return result
|
||||
|
||||
|
||||
|
||||
class share_create(osv.osv_memory):
|
||||
class share_wizard(osv.osv_memory):
|
||||
__logger = logging.getLogger('share.wizard')
|
||||
_name = 'share.wizard'
|
||||
_description = 'Share Wizard'
|
||||
@@ -99,9 +98,6 @@ class share_create(osv.osv_memory):
|
||||
def has_share(self, cr, uid, context=None):
|
||||
return self.has_group(cr, uid, module='share', group_xml_id='group_share_user', context=context)
|
||||
|
||||
def has_extended_share(self, cr, uid, context=None):
|
||||
return self.has_group(cr, uid, module='share', group_xml_id='group_share_user_extended', context=context)
|
||||
|
||||
def has_email(self, cr, uid, context=None):
|
||||
return bool(self.pool.get('res.users').browse(cr, uid, uid, context=context).user_email)
|
||||
|
||||
@@ -109,21 +105,18 @@ class share_create(osv.osv_memory):
|
||||
if not self.has_email(cr, uid, context=context):
|
||||
raise osv.except_osv(_('No e-mail address configured'),
|
||||
_('You must configure your e-mail address in the user preferences before using the Share button.'))
|
||||
return super(share_create, self).view_init(cr, uid, fields_list, context=context)
|
||||
return super(share_wizard, self).view_init(cr, uid, fields_list, context=context)
|
||||
|
||||
def _user_type_selection(self, cr, uid, context=None):
|
||||
result = [('new','New users (emails required)')]
|
||||
if self.has_extended_share(cr, uid, context=context):
|
||||
result.extend([('groups','Existing groups (Portals setup only)'),
|
||||
('existing','Users you already shared with')])
|
||||
return result
|
||||
"""Selection values may be easily overridden/extended via inheritance"""
|
||||
return [('emails','List of emails')]
|
||||
|
||||
"""Override of create() to auto-compute the action name"""
|
||||
def create(self, cr, uid, values, context=None):
|
||||
if 'action_id' in values and not 'name' in values:
|
||||
action = self.pool.get('ir.actions.actions').browse(cr, uid, values['action_id'], context=context)
|
||||
values['name'] = action.name
|
||||
return super(share_create,self).create(cr, uid, values, context=context)
|
||||
return super(share_wizard,self).create(cr, uid, values, context=context)
|
||||
|
||||
_columns = {
|
||||
'action_id': fields.many2one('ir.actions.act_window', 'Action to share', required=True,
|
||||
@@ -131,18 +124,16 @@ class share_create(osv.osv_memory):
|
||||
'domain': fields.char('Domain', size=256, help="Optional domain for further data filtering"),
|
||||
'user_type': fields.selection(_user_type_selection,'Users to share with',
|
||||
help="Select the type of user(s) you would like to share data with."),
|
||||
'user_ids': fields.many2many('res.users', 'share_wizard_res_user_rel', 'share_id', 'user_id', 'Existing users', domain=[('share', '=', True)]),
|
||||
'group_ids': fields.many2many('res.groups', 'share_wizard_res_group_rel', 'share_id', 'group_id', 'Existing groups', domain=[('share', '=', False)]),
|
||||
'new_users': fields.text("New users"),
|
||||
'new_users': fields.text("Emails"),
|
||||
'access_mode': fields.selection([('readonly','Can view'),('readwrite','Can edit')],'Access Mode', required=True,
|
||||
help="Access rights to be granted on the shared documents."),
|
||||
'result_line_ids': fields.one2many('share.wizard.result.line', 'share_wizard_id', 'Summary', readonly=True),
|
||||
'share_root_url': fields.char('Generic Share Access URL', size=512, readonly=True, tooltip='Main access page for users that are granted shared access'),
|
||||
'share_root_url': fields.char('Share Access URL', size=512, readonly=True, tooltip='Main access page for users that are granted shared access'),
|
||||
'name': fields.char('Share Title', size=64, required=True, help="Title for the share (displayed to users as menu and shortcut name)"),
|
||||
'message': fields.text("Personal Message", help="An optional personal message, to be included in the e-mail notification."),
|
||||
}
|
||||
_defaults = {
|
||||
'user_type' : lambda self, cr, uid, *a: 'new',
|
||||
'user_type' : 'new',
|
||||
'domain': lambda self, cr, uid, context, *a: context.get('domain', '[]'),
|
||||
'share_root_url': lambda self, cr, uid, context, *a: context.get('share_root_url') or _('Please specify "share_root_url" in context'),
|
||||
'action_id': lambda self, cr, uid, context, *a: context.get('action_id'),
|
||||
@@ -334,7 +325,7 @@ class share_create(osv.osv_memory):
|
||||
parent_colinfos = get_column_infos(parent_model)
|
||||
parent_model_browse = model_obj.browse(cr, UID_ROOT,
|
||||
model_obj.search(cr, UID_ROOT, [('model','=',parent)]))[0]
|
||||
if coldef._fields_id in parent_colinfos:
|
||||
if relation_field and coldef._fields_id in parent_colinfos:
|
||||
# inverse relationship is available in the parent
|
||||
local_rel_fields.append((relation_field, parent_model_browse))
|
||||
else:
|
||||
@@ -373,11 +364,11 @@ class share_create(osv.osv_memory):
|
||||
ir_model_obj.search(cr, UID_ROOT, [('model','=',parent)]))[0]
|
||||
obj0 += [(None, parent_model_browse)]
|
||||
|
||||
obj1 = self._get_recursive_relations(cr, uid, model, ['one2many'], context=context)
|
||||
obj2 = self._get_recursive_relations(cr, uid, model, ['one2many', 'many2many'], context=context)
|
||||
obj3 = self._get_recursive_relations(cr, uid, model, ['many2one'], context=context)
|
||||
obj1 = self._get_recursive_relations(cr, uid, model, ['one2many'], relation_fields=obj0, context=context)
|
||||
obj2 = self._get_recursive_relations(cr, uid, model, ['one2many', 'many2many'], relation_fields=obj0, context=context)
|
||||
obj3 = self._get_recursive_relations(cr, uid, model, ['many2one'], relation_fields=obj0, context=context)
|
||||
for dummy, model in obj1:
|
||||
obj3 += self._get_recursive_relations(cr, uid, model, ['many2one'], context=context)
|
||||
obj3 += self._get_recursive_relations(cr, uid, model, ['many2one'], relation_fields=obj0, context=context)
|
||||
return obj0, obj1, obj2, obj3
|
||||
|
||||
def _get_access_map_for_groups_and_models(self, cr, uid, group_ids, model_ids, context=None):
|
||||
@@ -460,28 +451,70 @@ class share_create(osv.osv_memory):
|
||||
})
|
||||
self.__logger.debug("Linking rule %s (%s) on model %s with domain: %s", rule.name, rule.id, model.model, rule.domain_force)
|
||||
|
||||
def _create_or_combine_sharing_rule(self, cr, current_user, wizard_data, group_id, model_id, domain, rule_name=None, context=None):
|
||||
def _check_personal_rule_or_duplicate(self, cr, group_id, rule, context=None):
|
||||
"""Verifies that the given rule only belongs to the given group_id, otherwise
|
||||
duplicate it for the current group, and unlink the previous one.
|
||||
The duplicated rule has the original domain copied verbatim, without
|
||||
any evaluation.
|
||||
Returns the final rule to use (browse_record), either the original one if it
|
||||
only belongs to this group, or the copy."""
|
||||
if len(rule.groups) == 1:
|
||||
return rule
|
||||
# duplicate it first:
|
||||
rule_obj = self.pool.get('ir.rule')
|
||||
new_id = rule_obj.copy(cr, UID_ROOT, rule.id,
|
||||
default={
|
||||
'name': '%s %s' %(rule.name, _('(Duplicated for modified sharing permissions)')),
|
||||
'groups': [(6,0,[group_id])],
|
||||
'domain_force': rule.domain_force, # non evaluated!
|
||||
})
|
||||
self.__logger.debug("Duplicating rule %s (%s) (domain: %s) for modified access ", rule.name, rule.id, rule.domain_force)
|
||||
# then disconnect from group_id:
|
||||
rule.write({'groups':[(3,group_id)]}) # disconnects, does not delete!
|
||||
return rule_obj.browse(cr, UID_ROOT, new_id, context=context)
|
||||
|
||||
def _create_or_combine_sharing_rule(self, cr, current_user, wizard_data, group_id, model_id, domain, restrict=False, rule_name=None, context=None):
|
||||
"""Add a new ir.rule entry for model_id and domain on the target group_id.
|
||||
If ``restrict`` is True, instead of adding a rule, the domain is
|
||||
combined with AND operator with all existing rules in the group, to implement
|
||||
an additional restriction (as of 6.1, multiple rules in the same group are
|
||||
OR'ed by default, so a restriction must alter all existing rules)"""
|
||||
if rule_name is None:
|
||||
rule_name = _('Sharing filter created by user %s (%s) for group %s') % \
|
||||
(current_user.name, current_user.login, group_id)
|
||||
rule_obj = self.pool.get('ir.rule')
|
||||
rule_ids = rule_obj.search(cr, UID_ROOT, [('groups', 'in', group_id), ('model_id', '=', model_id)])
|
||||
if rule_ids:
|
||||
for rule in rule_obj.browse(cr, UID_ROOT, rule_ids, context=context):
|
||||
if rule.domain_force == domain:
|
||||
# don't create it twice!
|
||||
self.__logger.debug("Ignoring sharing rule on model %s with domain: %s because the same rule exists already", model_id, domain)
|
||||
return
|
||||
if rule_name is None:
|
||||
rule_name = _('Sharing filter created by user %s (%s) for group %s') % \
|
||||
(current_user.name, current_user.login, group_id)
|
||||
# Adding the new rule in the group is fine in all cases, because rules
|
||||
# in the same group and for the same model will be combined with OR
|
||||
# (as of v6.1), so the desired effect is achieved.
|
||||
rule_obj.create(cr, UID_ROOT, {
|
||||
'name': rule_name,
|
||||
'model_id': model_id,
|
||||
'domain_force': domain,
|
||||
'groups': [(4,group_id)]
|
||||
})
|
||||
self.__logger.debug("Created sharing rule on model %s with domain: %s", model_id, domain)
|
||||
if restrict:
|
||||
continue
|
||||
else:
|
||||
self.__logger.debug("Ignoring sharing rule on model %s with domain: %s the same rule exists already", model_id, domain)
|
||||
return
|
||||
if restrict:
|
||||
# restricting existing rules is done by adding the clause
|
||||
# with an AND, but we can't alter the rule if it belongs to
|
||||
# other groups, so we duplicate if needed
|
||||
rule = self._check_personal_rule_or_duplicate(cr, group_id, rule, context=context)
|
||||
eval_ctx = rule_obj._eval_context_for_combinations()
|
||||
org_domain = expression.normalize(eval(rule.domain_force, eval_ctx))
|
||||
new_clause = expression.normalize(eval(domain, eval_ctx))
|
||||
combined_domain = expression.AND([new_clause, org_domain])
|
||||
rule.write({'domain_force': combined_domain, 'name': rule.name + _('(Modified)')})
|
||||
self.__logger.debug("Combining sharing rule %s on model %s with domain: %s", rule.id, model_id, domain)
|
||||
if not restrict:
|
||||
# Adding the new rule in the group is ok for normal cases, because rules
|
||||
# in the same group and for the same model will be combined with OR
|
||||
# (as of v6.1), so the desired effect is achieved.
|
||||
rule_obj.create(cr, UID_ROOT, {
|
||||
'name': rule_name,
|
||||
'model_id': model_id,
|
||||
'domain_force': domain,
|
||||
'groups': [(4,group_id)]
|
||||
})
|
||||
self.__logger.debug("Created sharing rule on model %s with domain: %s", model_id, domain)
|
||||
|
||||
def _create_indirect_sharing_rules(self, cr, current_user, wizard_data, group_id, fields_relations, context=None):
|
||||
rule_name = _('Indirect sharing filter created by user %s (%s) for group %s') % \
|
||||
@@ -489,7 +522,7 @@ class share_create(osv.osv_memory):
|
||||
try:
|
||||
domain = safe_eval(wizard_data.domain)
|
||||
if domain:
|
||||
domain_expr = expression(domain)
|
||||
domain_expr = expression.expression(domain)
|
||||
for rel_field, model in fields_relations:
|
||||
related_domain = []
|
||||
if not rel_field: continue
|
||||
@@ -501,7 +534,7 @@ class share_create(osv.osv_memory):
|
||||
related_domain.append(element)
|
||||
self._create_or_combine_sharing_rule(cr, current_user, wizard_data,
|
||||
group_id, model_id=model.id, domain=str(related_domain),
|
||||
rule_name=rule_name, context=context)
|
||||
rule_name=rule_name, restrict=True, context=context)
|
||||
except Exception:
|
||||
self.__logger.exception('Failed to create share access')
|
||||
raise osv.except_osv(_('Sharing access could not be created'),
|
||||
@@ -525,18 +558,10 @@ class share_create(osv.osv_memory):
|
||||
self._assert(self.has_share(cr, uid, context=context),
|
||||
_('You must be a member of the Share/User group to use the share wizard'),
|
||||
context=context)
|
||||
if wizard_data.user_type == 'new':
|
||||
if wizard_data.user_type == 'emails':
|
||||
self._assert(wizard_data.new_users,
|
||||
_('Please indicate the emails of the persons to share with, one per line'),
|
||||
context=context)
|
||||
elif wizard_data.user_type == 'existing':
|
||||
self._assert(wizard_data.user_ids,
|
||||
_('Please select at least one user to share with'),
|
||||
context=context)
|
||||
elif wizard_data.user_type == 'groups':
|
||||
self._assert(wizard_data.group_ids,
|
||||
_('Please select at least one group to share with'),
|
||||
context=context)
|
||||
|
||||
def _create_share_users_groups(self, cr, uid, wizard_data, context=None):
|
||||
"""Creates the appropriate shared users and groups, and populates
|
||||
@@ -545,37 +570,21 @@ class share_create(osv.osv_memory):
|
||||
:return: group_ids (to which the shared access should be granted),
|
||||
new_user_ids, and existing_user_ids.
|
||||
"""
|
||||
group_ids, new_ids, existing_ids = [], [], []
|
||||
|
||||
if wizard_data.user_type == 'groups':
|
||||
group_id = None
|
||||
group_ids.extend([g.id for g in wizard_data.group_ids])
|
||||
# populate result lines with the users of each group
|
||||
for group in wizard_data.group_ids:
|
||||
for user in group.users:
|
||||
new_line = {'login': user.login,
|
||||
'newly_created': False}
|
||||
wizard_data.write({'result_line_ids': [(0,0,new_line)]})
|
||||
|
||||
else:
|
||||
group_id = self._create_share_group(cr, uid, wizard_data, context=context)
|
||||
group_ids.append(group_id)
|
||||
# First create any missing user, based on the email addresses provided
|
||||
new_ids, exist_ids = self._create_new_share_users(cr, uid, wizard_data, group_id, context=context)
|
||||
existing_ids.extend(exist_ids)
|
||||
# Then, add any existing users to the share group
|
||||
existing_ids.extend([x.id for x in wizard_data.user_ids]) # manually selected users
|
||||
group_id = self._create_share_group(cr, uid, wizard_data, context=context)
|
||||
group_ids = [group_id] # other implementations may return multiple groups
|
||||
# First create any missing user, based on the email addresses provided
|
||||
new_ids, existing_ids = self._create_new_share_users(cr, uid, wizard_data, group_id, context=context)
|
||||
# Finally, setup the new action and shortcut for the users.
|
||||
if existing_ids:
|
||||
# existing users still need to join the new group
|
||||
self.pool.get('res.users').write(cr, UID_ROOT, existing_ids, {
|
||||
'groups_id': [(4,group_id)],
|
||||
})
|
||||
# Finally, setup the new action and shortcut for the users.
|
||||
if existing_ids:
|
||||
# Existing users will only need a shortcut
|
||||
self._setup_action_and_shortcut(cr, uid, wizard_data, existing_ids, False, context=context)
|
||||
if new_ids:
|
||||
# New users need the shortcut AND a home action
|
||||
self._setup_action_and_shortcut(cr, uid, wizard_data, new_ids, True, context=context)
|
||||
|
||||
# existing user don't need their home action replaced, only a new shortcut
|
||||
self._setup_action_and_shortcut(cr, uid, wizard_data, existing_ids, make_home=False, context=context)
|
||||
if new_ids:
|
||||
# new users need a new shortcut AND a home action
|
||||
self._setup_action_and_shortcut(cr, uid, wizard_data, new_ids, make_home=True, context=context)
|
||||
return group_ids, new_ids, existing_ids
|
||||
|
||||
def go_step_2(self, cr, uid, ids, context=None):
|
||||
@@ -613,8 +622,12 @@ class share_create(osv.osv_memory):
|
||||
self._add_access_rights_for_share_group(cr, uid, group_id, 'readonly', obj2, context=context)
|
||||
|
||||
# IR.RULES
|
||||
# A. On [obj0]: 1 rule with domain of shared action
|
||||
# B. For each model in [obj1]: 1 rule in the form:
|
||||
# A. On [obj0], [obj1], [obj2]: add all rules from all groups of
|
||||
# the user that is sharing
|
||||
# Warning: rules must be copied instead of linked if they contain a reference
|
||||
# to uid or if the rule is shared with other groups (and it must be replaced correctly)
|
||||
# B. On [obj0]: 1 rule with domain of shared action
|
||||
# C. For each model in [obj1]: 1 rule in the form:
|
||||
# many2one_rel.domain_of_obj0
|
||||
# where many2one_rel is the many2one used in the definition of the
|
||||
# one2many, and domain_of_obj0 is the sharing domain
|
||||
@@ -623,21 +636,17 @@ class share_create(osv.osv_memory):
|
||||
# then we will have project.task in [obj1] and we need to create this
|
||||
# ir.rule on project.task:
|
||||
# ['project_id.id', 'in', [1,2]]
|
||||
# C. And on [obj0], [obj1], [obj2]: add all rules from all groups of
|
||||
# the user that is sharing
|
||||
# (Warning: rules must be copied instead of linked if they contain a reference
|
||||
# to uid, and it must be replaced correctly)
|
||||
|
||||
# A.
|
||||
all_relations = obj0 + obj1 + obj2
|
||||
self._link_or_copy_current_user_rules(cr, current_user, group_id, all_relations, context=context)
|
||||
# B.
|
||||
main_domain = wizard_data.domain if wizard_data.domain != '[]' else DOMAIN_ALL
|
||||
self._create_or_combine_sharing_rule(cr, current_user, wizard_data,
|
||||
group_id, model_id=model.id, domain=main_domain,
|
||||
context=context)
|
||||
# B.
|
||||
self._create_indirect_sharing_rules(cr, current_user, wizard_data, group_id, obj1, context=context)
|
||||
restrict=True, context=context)
|
||||
# C.
|
||||
all_relations = obj0 + obj1 + obj2
|
||||
self._link_or_copy_current_user_rules(cr, current_user, group_id, all_relations, context=context)
|
||||
self._create_indirect_sharing_rules(cr, current_user, wizard_data, group_id, obj1, context=context)
|
||||
|
||||
# so far, so good -> check summary results and return them
|
||||
self._finish_result_lines(cr, uid, wizard_data, context=context)
|
||||
@@ -706,9 +715,9 @@ class share_create(osv.osv_memory):
|
||||
if tools.email_send(user.user_email, [email_to], subject, body):
|
||||
emails_sent += 1
|
||||
else:
|
||||
self.__logger.warning('Failed to send sharing email from %s to %s, ignored', user.user_email, email_to)
|
||||
self.__logger.warning('Failed to send share notification from %s to %s, ignored', user.user_email, email_to)
|
||||
self.__logger.info('%s share notification(s) successfully sent.', emails_sent)
|
||||
share_create()
|
||||
share_wizard()
|
||||
|
||||
class share_result_line(osv.osv_memory):
|
||||
_name = 'share.wizard.result.line'
|
||||
|
||||
@@ -29,29 +29,10 @@
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Grant instant access to your documents">
|
||||
<group colspan="4" col="4" groups="share.group_share_user_extended">
|
||||
<separator colspan="4" string="Who do you want to share with?"/>
|
||||
<field name="user_type" />
|
||||
</group>
|
||||
<group colspan="4" attrs="{'invisible':[('user_type','!=','existing')]}">
|
||||
<field colspan="4" nolabel="1" name="user_ids" mode="tree">
|
||||
<tree string="Existing users">
|
||||
<field name="login"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
<group colspan="4" attrs="{'invisible':[('user_type','!=','new')]}">
|
||||
<group colspan="4" attrs="{'invisible':[('user_type','!=','emails')]}">
|
||||
<separator colspan="4" string="Share with these people (one e-mail per line)"/>
|
||||
<field colspan="4" nolabel="1" name="new_users"/>
|
||||
</group>
|
||||
<group colspan="4" attrs="{'invisible':[('user_type','!=','groups')]}">
|
||||
<separator colspan="4" string="Existing Groups"/>
|
||||
<field colspan="4" nolabel="1" name="group_ids" mode="tree">
|
||||
<tree string="Existing groups">
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
<separator colspan="4" string="Optional: include a personal message"/>
|
||||
<group colspan="4" col="4">
|
||||
<field name="message" colspan="4" nolabel="1"/>
|
||||
@@ -80,14 +61,11 @@
|
||||
<field name="result_line_ids" nolabel="1" colspan="4" mode="tree">
|
||||
<tree string="Summary">
|
||||
<field name="login"/>
|
||||
<field name="share_url" groups="share.group_share_user_extended"/>
|
||||
</tree>
|
||||
<form string="Access info">
|
||||
<field name="login"/>
|
||||
<field name="share_url" colspan="4" groups="share.group_share_user_extended"/>
|
||||
</form>
|
||||
</field>
|
||||
<field colspan="4" name="share_root_url" groups="share.group_share_user_extended"/>
|
||||
<separator colspan="4"/>
|
||||
<group colspan="4">
|
||||
<button special="cancel" string="Close" icon='gtk-ok'/>
|
||||
@@ -128,9 +106,5 @@
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<!-- temporarily under Low-Level-Actions -->
|
||||
<menuitem action="action_share_wizard" id="menu_action_share_wizard" parent="base.next_id_4"
|
||||
groups="group_share_user,group_share_user_extended" icon="terp-rating-rated"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
Reference in New Issue
Block a user