summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRémy Voet (ryv) <ryv@odoo.com>2020-01-08 10:09:20 +0000
committerThibault Delavallée <tde@odoo.com>2020-01-21 16:40:06 +0000
commit15c934a1abfc72c965a6b46618b7b2ae6fad49cc (patch)
tree6494f8b926cdf8a45e47d67f4ef6389e3bd3721a
parente3ff7a49ae261c22336e6fdfcc01c33b7e9b2229 (diff)
[IMP] (website_)mail: improve routes and management of mail followers
Purpose of this commit is to improve model of followers, notably management code and its use in routes. Indeed it is quite an old model and code had to be cleaned a bit to improve code readability and maintenance. In this commit we * remove unnecessary code examples in gamification about followers: using that model as example of code for goals is probably not a good idea as it is technical; * rewrite routes called by JS are simplified to better match JS implementation; * introduce computed fields to fetch related partner or channel name, email (partner only) and active status; LINKS Task 1933771 Task 2078313 closes odoo/odoo#39808 Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com> Co-authored-by: Remy Voet <ryv@odoo.com> Co-authored-by: jgi-odoo <jgi@odoo.com> Co-authored-by: Xavier-Do <xdo@odoo.com>
-rw-r--r--addons/gamification/data/goal_base.xml9
-rw-r--r--addons/gamification/views/goal.xml2
-rw-r--r--addons/mail/controllers/main.py57
-rw-r--r--addons/mail/models/mail_followers.py18
-rw-r--r--addons/mail/models/mail_thread.py25
-rw-r--r--addons/mail/security/ir.model.access.csv5
-rw-r--r--addons/mail/security/mail_security.xml10
-rw-r--r--addons/mail/static/src/js/followers.js35
-rw-r--r--addons/mail/static/src/xml/followers.xml10
-rw-r--r--addons/mail/static/tests/chatter_tests.js69
-rw-r--r--addons/test_mail/tests/test_mail_channel.py11
-rw-r--r--addons/website_mail/controllers/main.py18
12 files changed, 148 insertions, 121 deletions
diff --git a/addons/gamification/data/goal_base.xml b/addons/gamification/data/goal_base.xml
index af96a4806cf..3289073cb13 100644
--- a/addons/gamification/data/goal_base.xml
+++ b/addons/gamification/data/goal_base.xml
@@ -280,15 +280,6 @@ Thank you,
<field name="action_id" eval="ref('action_new_simplified_res_users')" />
</record>
- <record model="gamification.goal.definition" id="definition_nbr_following">
- <field name="name">Mail Group Following</field>
- <field name="description">Follow mail.channels to receive news</field>
- <field name="computation_mode">python</field>
- <field name="compute_code">result = env['mail.followers'].search_count([('res_model', '=', 'mail.channel'), ('partner_id', '=', object.user_id.partner_id.id)])</field>
- <field name="action_id" eval="ref('mail.mail_channel_action_view')" />
- </record>
-
-
<!-- challenges -->
<record model="gamification.challenge" id="challenge_base_discover">
<field name="name">Complete your Profile</field>
diff --git a/addons/gamification/views/goal.xml b/addons/gamification/views/goal.xml
index 7301891f705..1f43e81fc6e 100644
--- a/addons/gamification/views/goal.xml
+++ b/addons/gamification/views/goal.xml
@@ -249,7 +249,7 @@
attrs="{'invisible':[('computation_mode','!=','sum')], 'required':[('computation_mode','=','sum')]}"/>
<field name="field_date_id" class="oe_inline" attrs="{'invisible':[('computation_mode','not in',('sum', 'count'))]}"/>
<field name="domain" attrs="{'invisible':[('computation_mode','not in',('sum', 'count'))], 'required':[('computation_mode','in',('sum', 'count'))]}" class="oe_inline"/>
- <field name="compute_code" attrs="{'invisible':[('computation_mode','!=','python')], 'required':[('computation_mode','=','python')]}" placeholder="e.g. result = env['mail.followers'].search_count([('res_model', '=', 'mail.channel'), ('partner_id', '=', object.user_id.partner_id.id)])"/>
+ <field name="compute_code" attrs="{'invisible':[('computation_mode','!=','python')], 'required':[('computation_mode','=','python')]}"/>
<field name="condition" widget="radio"/>
</group>
<group string="Optimisation" name="optimisation" attrs="{'invisible': [('computation_mode', '!=', 'count')]}">
diff --git a/addons/mail/controllers/main.py b/addons/mail/controllers/main.py
index 2dbc9c09288..b8a2387dbed 100644
--- a/addons/mail/controllers/main.py
+++ b/addons/mail/controllers/main.py
@@ -141,55 +141,66 @@ class MailController(http.Controller):
return True
@http.route('/mail/read_followers', type='json', auth='user')
- def read_followers(self, follower_ids, res_model):
- followers = []
- # When editing the followers, the "pencil" icon that leads to the edition of subtypes
- # should be always be displayed and not only when "debug" mode is activated.
- is_editable = True
- partner_id = request.env.user.partner_id
- follower_id = None
+ def read_followers(self, follower_ids):
+ request.env['mail.followers'].check_access_rights("read")
follower_recs = request.env['mail.followers'].sudo().browse(follower_ids)
res_ids = follower_recs.mapped('res_id')
+ res_models = set(follower_recs.mapped('res_model'))
+ if len(res_models) > 1:
+ raise AccessError(_("Can't read followers with different targeted model"))
+ res_model = res_models.pop()
+ request.env[res_model].check_access_rights("read")
request.env[res_model].browse(res_ids).check_access_rule("read")
+
+ followers = []
+ follower_id = None
for follower in follower_recs:
- is_uid = partner_id == follower.partner_id
- follower_id = follower.id if is_uid else follower_id
+ if follower.partner_id == request.env.user.partner_id:
+ follower_id = follower.id
followers.append({
'id': follower.id,
- 'name': follower.partner_id.name or follower.channel_id.name,
- 'email': follower.partner_id.email if follower.partner_id else None,
- 'res_model': 'res.partner' if follower.partner_id else 'mail.channel',
- 'res_id': follower.partner_id.id or follower.channel_id.id,
- 'is_editable': is_editable,
- 'is_uid': is_uid,
- 'active': follower.partner_id.active or bool(follower.channel_id),
+ 'partner_id': follower.partner_id.id,
+ 'channel_id': follower.channel_id.id,
+ 'name': follower.name,
+ 'email': follower.email,
+ 'is_active': follower.is_active,
+ # When editing the followers, the "pencil" icon that leads to the edition of subtypes
+ # should be always be displayed and not only when "debug" mode is activated.
+ 'is_editable': True
})
return {
'followers': followers,
- 'subtypes': self.read_subscription_data(res_model, follower_id) if follower_id else None
+ 'subtypes': self.read_subscription_data(follower_id) if follower_id else None
}
@http.route('/mail/read_subscription_data', type='json', auth='user')
- def read_subscription_data(self, res_model, follower_id):
+ def read_subscription_data(self, follower_id):
""" Computes:
- message_subtype_data: data about document subtypes: which are
available, which are followed if any """
- followers = request.env['mail.followers'].browse(follower_id)
+ request.env['mail.followers'].check_access_rights("read")
+ follower = request.env['mail.followers'].sudo().browse(follower_id)
+ follower.ensure_one()
+ request.env[follower.res_model].check_access_rights("read")
+ request.env[follower.res_model].browse(follower.res_id).check_access_rule("read")
# find current model subtypes, add them to a dictionary
- subtypes = request.env['mail.message.subtype'].search(['&', ('hidden', '=', False), '|', ('res_model', '=', res_model), ('res_model', '=', False)])
+ subtypes = request.env['mail.message.subtype'].search([
+ '&', ('hidden', '=', False),
+ '|', ('res_model', '=', follower.res_model), ('res_model', '=', False)])
+ followed_subtypes_ids = set(follower.subtype_ids.ids)
subtypes_list = [{
'name': subtype.name,
'res_model': subtype.res_model,
'sequence': subtype.sequence,
'default': subtype.default,
'internal': subtype.internal,
- 'followed': subtype.id in followers.mapped('subtype_ids').ids,
+ 'followed': subtype.id in followed_subtypes_ids,
'parent_model': subtype.parent_id.res_model,
'id': subtype.id
} for subtype in subtypes]
- subtypes_list = sorted(subtypes_list, key=lambda it: (it['parent_model'] or '', it['res_model'] or '', it['internal'], it['sequence']))
- return subtypes_list
+ return sorted(subtypes_list,
+ key=lambda it: (it['parent_model'] or '', it['res_model'] or '', it['internal'], it['sequence']))
@http.route('/mail/view', type='http', auth='public')
def mail_action_view(self, model=None, res_id=None, access_token=None, **kwargs):
diff --git a/addons/mail/models/mail_followers.py b/addons/mail/models/mail_followers.py
index b9b3f53e8b9..2cd2d48b38d 100644
--- a/addons/mail/models/mail_followers.py
+++ b/addons/mail/models/mail_followers.py
@@ -35,6 +35,12 @@ class Followers(models.Model):
subtype_ids = fields.Many2many(
'mail.message.subtype', string='Subtype',
help="Message subtypes followed, meaning subtypes that will be pushed onto the user's Wall.")
+ name = fields.Char('Name', compute='_compute_related_fields',
+ help="Name of the related partner (if exist) or the related channel")
+ email = fields.Char('Email', compute='_compute_related_fields',
+ help="Email of the related partner (if exist) or False")
+ is_active = fields.Boolean('Is Active', compute='_compute_related_fields',
+ help="If the related partner is active (if exist) or if related channel exist")
def _invalidate_documents(self, vals_list=None):
""" Invalidate the cache of the documents followed by ``self``.
@@ -75,6 +81,18 @@ class Followers(models.Model):
# Private tools methods to fetch followers data
# --------------------------------------------------
+ @api.depends('partner_id', 'channel_id')
+ def _compute_related_fields(self):
+ for follower in self:
+ if follower.partner_id:
+ follower.name = follower.partner_id.name
+ follower.email = follower.partner_id.email
+ follower.is_active = follower.partner_id.active
+ else:
+ follower.name = follower.channel_id.name
+ follower.is_active = bool(follower.channel_id)
+ follower.email = False
+
def _get_recipient_data(self, records, message_type, subtype_id, pids=None, cids=None):
""" Private method allowing to fetch recipients data based on a subtype.
Purpose of this method is to fetch all data necessary to notify recipients
diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py
index 4672cd4d569..c83d4ae8705 100644
--- a/addons/mail/models/mail_thread.py
+++ b/addons/mail/models/mail_thread.py
@@ -82,13 +82,15 @@ class MailThread(models.AbstractModel):
message_is_follower = fields.Boolean(
'Is Follower', compute='_compute_is_follower', search='_search_is_follower')
message_follower_ids = fields.One2many(
- 'mail.followers', 'res_id', string='Followers')
+ 'mail.followers', 'res_id', string='Followers', groups='base.group_user')
message_partner_ids = fields.Many2many(
comodel_name='res.partner', string='Followers (Partners)',
- compute='_get_followers', search='_search_follower_partners')
+ compute='_get_followers', search='_search_follower_partners',
+ groups='base.group_user')
message_channel_ids = fields.Many2many(
comodel_name='mail.channel', string='Followers (Channels)',
- compute='_get_followers', search='_search_follower_channels')
+ compute='_get_followers', search='_search_follower_channels',
+ groups='base.group_user')
message_ids = fields.One2many(
'mail.message', 'res_id', string='Messages',
domain=lambda self: [('message_type', '!=', 'user_notification')], auto_join=True)
@@ -258,17 +260,16 @@ class MailThread(models.AbstractModel):
if self._context.get('tracking_disable'):
return super(MailThread, self).create(vals_list)
+ threads = super(MailThread, self).create(vals_list)
# subscribe uid unless asked not to
if not self._context.get('mail_create_nosubscribe'):
- default_followers = self.env['mail.followers']._add_default_followers(
- self._name, [], self.env.user.partner_id.ids, customer_ids=[],
- check_existing=False, existing_policy='skip')[0][0]
- for values in vals_list:
- message_follower_ids = values.get('message_follower_ids') or []
- message_follower_ids += [(0, 0, fol_vals) for fol_vals in default_followers]
- values['message_follower_ids'] = message_follower_ids
-
- threads = super(MailThread, self).create(vals_list)
+ for thread in threads:
+ self.env['mail.followers']._insert_followers(
+ thread._name, thread.ids, self.env.user.partner_id.ids,
+ None, None, None,
+ customer_ids=[],
+ check_existing=False
+ )
# auto_subscribe: take values and defaults into account
create_values_list = {}
diff --git a/addons/mail/security/ir.model.access.csv b/addons/mail/security/ir.model.access.csv
index eb52637ff2e..2f21338e9f4 100644
--- a/addons/mail/security/ir.model.access.csv
+++ b/addons/mail/security/ir.model.access.csv
@@ -6,9 +6,8 @@ access_mail_mail_all,mail.mail.all,model_mail_mail,,0,0,0,0
access_mail_mail_portal,mail.mail.portal,model_mail_mail,base.group_portal,0,0,0,0
access_mail_mail_user,mail.mail.user,model_mail_mail,base.group_user,0,0,0,0
access_mail_mail_system,mail.mail.system,model_mail_mail,base.group_system,1,1,1,1
-access_mail_followers_all,mail.followers.all,model_mail_followers,,1,0,0,0
-access_mail_followers_portal,mail.followers.portal,model_mail_followers,base.group_portal,1,1,1,0
-access_mail_followers_user,mail.followers.user,model_mail_followers,base.group_user,1,1,1,0
+access_mail_followers_all,mail.followers.all,model_mail_followers,,0,0,0,0
+access_mail_followers_user,mail.followers.user,model_mail_followers,base.group_user,1,0,0,0
access_mail_followers_system,mail.followers.system,model_mail_followers,base.group_system,1,1,1,1
access_mail_notification_portal,mail.notification.portal,model_mail_notification,base.group_portal,1,0,0,0
access_mail_notification_user,mail.notification.user,model_mail_notification,base.group_user,1,1,1,0
diff --git a/addons/mail/security/mail_security.xml b/addons/mail/security/mail_security.xml
index 3ffe43e35eb..3a98e1bddb2 100644
--- a/addons/mail/security/mail_security.xml
+++ b/addons/mail/security/mail_security.xml
@@ -14,16 +14,6 @@
</record>
</data>
<data noupdate="1">
- <record id="mail_followers_read_write_own" model="ir.rule">
- <field name="name">mail.followers: write its own entries</field>
- <field name="model_id" ref="model_mail_followers"/>
- <field name="groups" eval="[(4, ref('base.group_user')), (4, ref('base.group_portal'))]"/>
- <field name="domain_force">[('partner_id', '=', user.partner_id.id)]</field>
- <field name="perm_create" eval="False"/>
- <field name="perm_unlink" eval="False"/>
- <field name="perm_read" eval="False"/>
- </record>
-
<record id="ir_rule_mail_notifications_group_user" model="ir.rule">
<field name="name">mail.notifications: group_user: write its own entries</field>
<field name="model_id" ref="model_mail_notification"/>
diff --git a/addons/mail/static/src/js/followers.js b/addons/mail/static/src/js/followers.js
index cbe20ba240e..7179b159663 100644
--- a/addons/mail/static/src/js/followers.js
+++ b/addons/mail/static/src/js/followers.js
@@ -6,6 +6,7 @@ var concurrency = require('web.concurrency');
var core = require('web.core');
var Dialog = require('web.Dialog');
var field_registry = require('web.field_registry');
+var session = require('web.session');
var _t = core._t;
var QWeb = core.qweb;
@@ -43,7 +44,6 @@ var Followers = AbstractField.extend({
this.subtypes = [];
this.data_subtype = {};
this._isFollower = undefined;
- var session = this.getSession();
this.partnerID = session.partner_id;
this.dp = new concurrency.DropPrevious();
@@ -113,14 +113,14 @@ var Followers = AbstractField.extend({
$(QWeb.render('mail.Followers.add_more', {widget: this})).appendTo($followers_list);
var $follower_li;
_.each(this.followers, function (record) {
- if(!record.active) {
+ if (!record.is_active) {
record.title = _.str.sprintf(_t('%s \n(inactive)'), record.name);
} else {
record.title = record.name;
}
$follower_li = $(QWeb.render('mail.Followers.partner', {
- 'record': _.extend(record, {'avatar_url': '/web/image/' + record.res_model + '/' + record.res_id + '/image_128'}),
+ 'record': record,
'widget': self})
);
$follower_li.appendTo($followers_list);
@@ -199,28 +199,37 @@ var Followers = AbstractField.extend({
return str;
},
_readFollowers: function () {
- var self = this;
var missing_ids = _.difference(this.value.res_ids, _.pluck(this.followers, 'id'));
var def;
if (missing_ids.length) {
def = this._rpc({
route: '/mail/read_followers',
- params: { follower_ids: missing_ids, res_model: this.model, context: {} } // empty context to be overridden in session.js with 'allowed_company_ids'
+ params: { follower_ids: missing_ids, context: {} } // empty context to be overridden in session.js with 'allowed_company_ids'
});
}
- return Promise.resolve(def).then(function (results) {
+ return Promise.resolve(def).then((results) => {
if (results) {
- self.followers = _.uniq(results.followers.concat(self.followers), 'id');
+ // Preprocess records
+ _.each(results.followers, (record) => {
+ var resModel = record.partner_id ? 'res.partner' : 'mail.channel';
+ var resId = record.partner_id ? record.partner_id : record.channel_id;
+ record.res_id = resId;
+ record.res_model = resModel;
+ record.avatar_url = '/web/image/' + resModel + '/' + resId + '/image_128';
+ });
+ this.followers = _.uniq(results.followers.concat(this.followers), 'id');
if (results.subtypes) { //read_followers will return False if current user is not in the list
- self.subtypes = results.subtypes;
+ this.subtypes = results.subtypes;
}
}
// filter out previously fetched followers that are no longer following
- self.followers = _.filter(self.followers, function (follower) {
- return _.contains(self.value.res_ids, follower.id);
+ this.followers = _.filter(this.followers, (follower) => {
+ return _.contains(this.value.res_ids, follower.id);
+ });
+ var userFollower = _.filter(this.followers, (rec) => {
+ return this.partnerID === rec.partner_id;
});
- var user_follower = _.filter(self.followers, function (rec) { return rec.is_uid; });
- self._isFollower = user_follower.length >= 1;
+ this._isFollower = userFollower.length >= 1;
});
},
_reload: function () {
@@ -361,7 +370,7 @@ var Followers = AbstractField.extend({
var follower_id = $currentTarget.data('follower-id'); // id of model mail_follower
this._rpc({
route: '/mail/read_subscription_data',
- params: {res_model: this.model, follower_id: follower_id},
+ params: {follower_id: follower_id},
})
.then(function (data) {
var res_id = $currentTarget.data('oe-id'); // id of model res_partner or mail_channel
diff --git a/addons/mail/static/src/xml/followers.xml b/addons/mail/static/src/xml/followers.xml
index 8a0914737a2..8789b424af2 100644
--- a/addons/mail/static/src/xml/followers.xml
+++ b/addons/mail/static/src/xml/followers.xml
@@ -30,12 +30,12 @@
Partner or channel following the record
-->
<t t-name="mail.Followers.partner">
- <div role="menuitem" t-attf-class="dropdown-item o_partner {{ !record.active ? 'o_inactive': '' }}">
+ <div role="menuitem" t-attf-class="dropdown-item o_partner {{ !record.is_active ? 'o_inactive': '' }}">
<a class="o_mail_redirect text-truncate"
href="#"
t-att-title="record.title"
- t-att-data-oe-model="record.res_model"
- t-att-data-oe-id="record.res_id">
+ t-att-data-oe-model="record.partner_id ? 'res.partner' : 'mail.channel'"
+ t-att-data-oe-id="record.partner_id ? record.partner_id : record.channel_id">
<img t-att-src="record.avatar_url" alt="Avatar" class="o_image_64_cover"/>
<t t-esc="record.name"/>
</a>
@@ -45,8 +45,8 @@
aria-label="Edit subscription"
role="img"
t-att-data-follower-id="record.id"
- t-att-data-oe-id="record.res_id"
- t-att-data-oe-model="record.res_model"/>
+ t-att-data-oe-id="record.partner_id ? record.partner_id : record.channel_id"
+ t-att-data-oe-model="record.partner_id ? 'res.partner' : 'mail.channel'"/>
<button t-if="widget.isEditable"
class="btn btn-icon fa fa-remove o_remove_follower"
aria-label="Remove this follower"
diff --git a/addons/mail/static/tests/chatter_tests.js b/addons/mail/static/tests/chatter_tests.js
index bc1ff44b746..f26dd096e62 100644
--- a/addons/mail/static/tests/chatter_tests.js
+++ b/addons/mail/static/tests/chatter_tests.js
@@ -2490,11 +2490,11 @@ QUnit.test('followers widget: follow/unfollow, edit subtypes', async function (a
this.data.partner.records[0].message_follower_ids = [1];
followers.push({
id: 1,
- is_uid: true,
name: "Admin",
email: "admin@example.com",
- res_id: resID,
- res_model: 'partner',
+ partner_id: partnerID,
+ channel_id: null,
+ is_active: true
});
}
return Promise.resolve(true);
@@ -2558,18 +2558,18 @@ QUnit.test('followers widget: follow/unfollow confirmation dialog', async functi
var partnerID = 2;
var followers = [{
id: 1,
- is_uid: true,
name: "Admin",
email: "admin@example.com",
- res_id: resID,
- res_model: 'res.partner',
+ partner_id: partnerID,
+ channel_id: null,
+ is_active: true
}, {
id: 2,
- is_uid: true,
name: "Demo",
email: "demo@example.com",
- res_id: 3,
- res_model: 'res.partner',
+ partner_id: 1,
+ channel_id: null,
+ is_active: true
}];
var form = await createView({
@@ -2624,12 +2624,14 @@ QUnit.test('followers widget: do not display follower duplications', async funct
this.data.partner.records[0].message_follower_ids = [1];
var resID = 2;
+ var partnerID = 1;
var followers = [{
id: 1,
name: "Admin",
email: "admin@example.com",
- res_id: resID,
- res_model: 'partner',
+ partner_id: partnerID,
+ channel_id: null,
+ is_active: true
}];
var def;
var form = await createView({
@@ -2657,17 +2659,18 @@ QUnit.test('followers widget: do not display follower duplications', async funct
return this._super.apply(this, arguments);
},
res_id: resID,
- session: {partner_id: 1},
+ session: {partner_id: partnerID},
});
followers.push({
id: 2,
- is_uid: false,
name: "A follower",
email: "follower@example.com",
res_id: resID,
- res_model: 'partner',
+ partner_id: 555,
+ channel_id: null,
+ is_active: true
});
this.data.partner.records[0].message_follower_ids.push(2);
@@ -2695,23 +2698,23 @@ QUnit.test('followers widget: display inactive followers with a different style'
id: 1,
name: "Admin",
email: "admin@example.com",
- res_id: 101,
- res_model: 'partner',
- active: true,
+ partner_id: 101,
+ channel_id: false,
+ is_active: true,
},{
id: 2,
name: "Active_partner",
email: "active_partner@example.com",
- res_id: 102,
- res_model: 'partner',
- active: true,
+ partner_id: 102,
+ channel_id: false,
+ is_active: true,
},{
id: 3,
name: "Inactive_partner",
email: "inactive_partner@example.com",
- res_id: 103,
- res_model: 'partner',
- active: false,
+ partner_id: 103,
+ channel_id: false,
+ is_active: false,
}];
var form = await createView({
@@ -3002,11 +3005,9 @@ QUnit.test('chatter: suggested partner auto-follow on message post', async funct
var followers = [];
followers.push({
id: 1,
- is_uid: true,
name: "Admin",
email: "admin@example.com",
- res_id: 5,
- res_model: 'partner',
+ partner_id: 5,
});
var form = await createView({
@@ -3045,11 +3046,11 @@ QUnit.test('chatter: suggested partner auto-follow on message post', async funct
self.data.partner.records[0].message_follower_ids.push(2);
followers.push({
id: 2,
- is_uid: true,
name: "Demo User",
email: "demo-user@example.com",
- res_id: 8,
- res_model: 'partner',
+ partner_id: 8,
+ channel_id: false,
+ is_active: true
});
// post a legit message so that it does not crashes
@@ -3187,14 +3188,16 @@ QUnit.test('chatter: mention prefetched partners (followers & employees)', async
id: 10,
name: 'FollowerUser1',
email: 'follower-user1@example.com',
- res_model: 'res.partner',
- res_id: 1,
+ partner_id: 1,
+ channel_id: null,
+ is_active: true
}, {
id: 20,
name: 'FollowerUser2',
email: 'follower-user2@example.com',
- res_model: 'res.partner',
- res_id: 2,
+ partner_id: 2,
+ channel_id: null,
+ is_active: true,
}],
subtypes: [],
});
diff --git a/addons/test_mail/tests/test_mail_channel.py b/addons/test_mail/tests/test_mail_channel.py
index 8869ac21442..2e3c7c2cb4b 100644
--- a/addons/test_mail/tests/test_mail_channel.py
+++ b/addons/test_mail/tests/test_mail_channel.py
@@ -99,13 +99,16 @@ class TestChannelAccessRights(TestMailCommon):
trigger_read = chell_pigs.name
for message in chell_pigs.message_ids:
trigger_read = message.subject
- for partner in chell_pigs.message_partner_ids:
+
+ with self.assertRaises(AccessError):
+ chell_pigs.message_partner_ids
+
+ for partner in self.group_private.message_partner_ids:
if partner.id == self.user_portal.partner_id.id:
# Chell can read her own partner record
continue
- # TODO Change the except_orm to Warning
- with self.assertRaises(except_orm):
- trigger_read = partner.name
+ with self.assertRaises(AccessError):
+ trigger_read = partner.with_user(self.user_portal).name
class TestChannelFeatures(TestMailCommon):
diff --git a/addons/website_mail/controllers/main.py b/addons/website_mail/controllers/main.py
index 6d00c064149..822373eb4d6 100644
--- a/addons/website_mail/controllers/main.py
+++ b/addons/website_mail/controllers/main.py
@@ -11,7 +11,12 @@ class WebsiteMail(http.Controller):
# TDE FIXME: check this method with new followers
res_id = int(id)
is_follower = message_is_follower == 'on'
- record = request.env[object].browse(res_id)
+ record = request.env[object].browse(res_id).exists()
+ if not record:
+ return False
+
+ record.check_access_rights('read')
+ record.check_access_rule('read')
# search partner_id
if request.env.user != request.website.user_id:
@@ -24,11 +29,9 @@ class WebsiteMail(http.Controller):
partner_ids = request.env['res.partner'].sudo().create({'name': name, 'email': email}).ids
# add or remove follower
if is_follower:
- record.check_access_rule('read')
record.sudo().message_unsubscribe(partner_ids)
return False
else:
- record.check_access_rule('read')
# add partner to session
request.session['partner_id'] = partner_ids[0]
record.sudo().message_subscribe(partner_ids)
@@ -48,14 +51,13 @@ class WebsiteMail(http.Controller):
'is_user': user != public_user,
'email': partner.email if partner else "",
'is_follower': False,
- 'alias_name': False,
}
- record = request.env[model].sudo().browse(int(res_id))
- if record and partner:
- values['is_follower'] = bool(request.env['mail.followers'].search_count([
+ record_sudo = request.env[model].sudo().browse(int(res_id))
+ if partner and record_sudo.exists():
+ values['is_follower'] = bool(request.env['mail.followers'].sudo().search_count([
('res_model', '=', model),
- ('res_id', '=', record.id),
+ ('res_id', '=', record_sudo.id),
('partner_id', '=', partner.id)
]))
return values