Skip to content

Commit

Permalink
Merge PR #1057 into 15.0
Browse files Browse the repository at this point in the history
Signed-off-by pedrobaeza
  • Loading branch information
OCA-git-bot committed Feb 2, 2023
2 parents f618699 + e996d10 commit fd900e2
Show file tree
Hide file tree
Showing 16 changed files with 132 additions and 83 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
/** @odoo-module **/
import {patch} from "web.utils";
import {ChatterTopbar} from "@mail/components/chatter_topbar/chatter_topbar";
import {patch} from "web.utils";
const components = {ChatterTopbar};
// Import {rpc}
import rpc from "web.rpc";

patch(
Expand Down
1 change: 0 additions & 1 deletion mail_tracking/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@

from . import models
from . import controllers
from .hooks import pre_init_hook
1 change: 0 additions & 1 deletion mail_tracking/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,4 @@
],
},
"demo": ["demo/demo.xml"],
"pre_init_hook": "pre_init_hook",
}
7 changes: 5 additions & 2 deletions mail_tracking/controllers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def _request_metadata(self):
"ua_family": request.user_agent.browser or False,
}

# TODO Remove useless controller
@http.route(
[
"/mail/tracking/all/<string:db>",
Expand Down Expand Up @@ -80,8 +81,10 @@ def mail_tracking_open(self, db, tracking_email_id, token=False, **kw):
metadata = self._request_metadata()
with db_env(db) as env:
try:
tracking_email = env["mail.tracking.email"].search(
[("id", "=", tracking_email_id), ("token", "=", token)]
tracking_email = (
env["mail.tracking.email"]
.sudo()
.search([("id", "=", tracking_email_id), ("token", "=", token)])
)
if not tracking_email:
_logger.warning(
Expand Down
32 changes: 0 additions & 32 deletions mail_tracking/hooks.py

This file was deleted.

1 change: 1 addition & 0 deletions mail_tracking/models/mail_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class MailMessage(models.Model):
mail_tracking_ids = fields.One2many(
comodel_name="mail.tracking.email",
inverse_name="mail_message_id",
auto_join=True,
string="Mail Trackings",
)
mail_tracking_needs_action = fields.Boolean(
Expand Down
89 changes: 85 additions & 4 deletions mail_tracking/models/mail_tracking_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
import uuid
from datetime import datetime

from odoo import api, fields, models, tools
from odoo import _, api, fields, models, tools
from odoo.exceptions import AccessError
from odoo.tools import email_split

_logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -138,11 +139,90 @@ def write(self, vals):
self.mapped("mail_message_id").write({"mail_tracking_needs_action": True})
return res

def _find_allowed_tracking_ids(self):
"""Filter trackings based on related records ACLs"""
# Admins passby this filter
if not self or self.env.user.has_group("base.group_system"):
return self.ids
# Override ORM to get the values directly
self._cr.execute(
"""
SELECT id, mail_message_id, partner_id
FROM mail_tracking_email WHERE id IN %s
""",
(tuple(self.ids),),
)
msg_linked = self._cr.fetchall()
if not msg_linked:
return []
_, msg_ids, partner_ids = zip(*msg_linked)
# Filter messages with their ACL rules avoiding False values fetched in the set
msg_ids = self.env["mail.message"]._search(
[("id", "in", [x for x in msg_ids if x])]
)
partner_ids = self.env["res.partner"]._search(
[("id", "in", [x for x in partner_ids if x])]
)
return [
x[0]
for x in msg_linked
if (x[1] in msg_ids) # We can read the linked message
or (
not any({x[1], x[2]}) and x[3] in partner_ids
) # No linked msg/mail but we can read the linked partner
or (not any({x[1], x[2], x[3]})) # No linked record
]

@api.model
def _search(
self,
args,
offset=0,
limit=None,
order=None,
count=False,
access_rights_uid=None,
):
"""Filter ids based on related records ACLs"""
ids = super()._search(
args, offset, limit, order, count=count, access_rights_uid=access_rights_uid
)
if not self.env.user.has_group("base.group_system") and not count:
ids = self.browse(ids)._find_allowed_tracking_ids()
return ids

def check_access_rule(self, operation):
"""Rely on related messages ACLs"""
super().check_access_rule(operation)
allowed_ids = self._search([("id", "in", self._find_allowed_tracking_ids())])
disallowed_ids = set(self.exists().ids).difference(set(allowed_ids))
if not disallowed_ids:
return
raise AccessError(
_(
"The requested operation cannot be completed due to security "
"restrictions. Please contact your system administrator.\n\n"
"(Document type: %(desc)s, Operation: %(operation)s)"
)
% {"desc": self._description, "operation": operation}
+ " - ({} {}, {} {})".format(
_("Records:"), list(disallowed_ids), _("User:"), self._uid
)
)

def read(self, fields=None, load="_classic_read"):
"""Override to explicitly call check_access_rule, that is not called
by the ORM. It instead directly fetches ir.rules and apply them.
"""
if not self.env.user.has_group("base.group_system"):
self.check_access_rule("read")
return super().read(fields=fields, load=load)

@api.model
def email_is_bounced(self, email):
if not email:
return False
res = self._email_last_tracking_state(email)
res = self.sudo()._email_last_tracking_state(email)
return res and res[0].get("state", "") in {
"rejected",
"error",
Expand All @@ -163,13 +243,13 @@ def _email_last_tracking_state(self, email):
def email_score_from_email(self, email):
if not email:
return 0.0
data = self.read_group(
data = self.sudo().read_group(
[("recipient_address", "=", email.lower())],
["recipient_address", "state"],
["state"],
)
mapped_data = {state["state"]: state["state_count"] for state in data}
return self.with_context(mt_states=mapped_data).email_score()
return self.with_context(mt_states=mapped_data).sudo().email_score()

@api.model
def _email_score_weights(self):
Expand Down Expand Up @@ -382,6 +462,7 @@ def event_create(self, event_type, metadata):
_logger.debug("Concurrent event '%s' discarded", event_type)
return event_ids

# TODO Remove useless method
@api.model
def event_process(self, request, post, metadata, event_type=None):
# Generic event process hook, inherit it and
Expand Down
4 changes: 4 additions & 0 deletions mail_tracking/models/mail_tracking_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ def _process_bounce(self, tracking_email, metadata, event_type, state):
)
return self._process_data(tracking_email, metadata, event_type, state)

@api.model
def process_sent(self, tracking_email, metadata):
return self._process_status(tracking_email, metadata, "sent", "sent")

@api.model
def process_delivered(self, tracking_email, metadata):
return self._process_status(tracking_email, metadata, "delivered", "delivered")
Expand Down
18 changes: 10 additions & 8 deletions mail_tracking/models/res_partner.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ class ResPartner(models.Model):

@api.depends("email")
def _compute_email_score_and_count(self):
self.email_score = 50.0
self.tracking_emails_count = 0
partners_mail = self.filtered("email")
mail_tracking_obj = self.env["mail.tracking.email"]
mt_obj = self.env["mail.tracking.email"].sudo()
for partner in partners_mail:
partner.email_score = self.env[
"mail.tracking.email"
].email_score_from_email(partner.email)
partner.tracking_emails_count = mail_tracking_obj.search_count(
[("recipient_address", "=", partner.email.lower())]
partner.email_score = mt_obj.email_score_from_email(partner.email)
# We don't want performance issues due to heavy ACLs check for large
# recordsets. Our option is to hide the number for regular users.
if not self.env.user.has_group("base.group_system"):
continue
partner.tracking_emails_count = len(
mt_obj._search([("recipient_address", "=", partner.email.lower())])
)
partners_no_mail = self - partners_mail
partners_no_mail.update({"email_score": 50.0, "tracking_emails_count": 0})
3 changes: 1 addition & 2 deletions mail_tracking/static/src/js/chatter.esm.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
/** @odoo-module **/

import {attr} from "@mail/model/model_field";
import {
registerFieldPatchModel,
registerInstancePatchModel,
} from "@mail/model/model_core";
import {attr} from "@mail/model/model_field";

registerInstancePatchModel(
"mail.chatter",
Expand Down
3 changes: 2 additions & 1 deletion mail_tracking/static/src/js/discuss/discuss.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ registerInstancePatchModel(
} else {
this.messaging.update({
userSetting: insertAndReplace({
id: -1, // Fake id for guest
// Fake id for guest
id: -1,
}),
});
}
Expand Down
10 changes: 0 additions & 10 deletions mail_tracking/static/src/js/failed_message/mail_failed_box.esm.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
/** @odoo-module **/

// const chatter = require("mail/static/src/models/chatter/chatter.js");
// const useStore = require("mail/static/src/component_hooks/use_store/use_store.js");
import {registerMessagingComponent} from "@mail/utils/messaging_component";
const {Component} = owl;

export class MessageFailedBox extends Component {
constructor(...args) {
super(...args);
}

// Get chatter() {
// return this.env.models["mail.chatter"].get(this.props.chatterLocalId);
// }

_onClickTitle() {
this.chatter.toggleMessageFailedBoxVisibility();
}
Expand Down
8 changes: 4 additions & 4 deletions mail_tracking/static/src/js/models/thread.esm.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
/** @odoo-module **/
import {registerNewModel} from "@mail/model/model_core";
import {attr, many2one} from "@mail/model/model_field";
import {registerNewModel} from "@mail/model/model_core";

function factory(dependencies) {
class MessageFailed extends dependencies["mail.model"] {
static convertData(data) {
const data2 = {};
if ("author" in data) {
if (!data.author) {
data2.author = [["unlink-all"]];
} else {
if (data.author) {
data2.author = data.author[1];
data2.author_id = data.author[0];
} else {
data2.author = [["unlink-all"]];
}
}
if ("body" in data) {
Expand Down
28 changes: 17 additions & 11 deletions mail_tracking/tests/test_mail_tracking.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import psycopg2.errorcodes

from odoo import http
from odoo.tests import users
from odoo.tests.common import TransactionCase
from odoo.tools import mute_logger

Expand Down Expand Up @@ -74,19 +75,24 @@ def test_recipient_address_compute(self):
tracking.write({"recipient": False})
self.assertEqual(False, tracking.recipient_address)

@users("admin", "demo")
def test_message_post(self):
# This message will generate a notification for recipient
message = self.env["mail.message"].create(
{
"subject": "Message test",
"author_id": self.sender.id,
"email_from": self.sender.email,
"message_type": "comment",
"model": "res.partner",
"res_id": self.recipient.id,
"partner_ids": [(4, self.recipient.id)],
"body": "<p>This is a test message</p>",
}
message = (
self.env["mail.message"]
.sudo()
.create(
{
"subject": "Message test",
"author_id": self.sender.id,
"email_from": self.sender.email,
"message_type": "comment",
"model": "res.partner",
"res_id": self.recipient.id,
"partner_ids": [(4, self.recipient.id)],
"body": "<p>This is a test message</p>",
}
)
)
if message.is_thread_message():
self.env[message.model].browse(message.res_id)._notify_thread(message)
Expand Down
6 changes: 1 addition & 5 deletions mail_tracking/views/mail_tracking_email_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,7 @@
<field name="name" string="Subject" />
<field name="time" string="Time" />
<field name="date" string="Date" />
<filter
name="sent"
string="Sent"
domain="[('state', 'in', ('sent',))]"
/>
<filter name="sent" string="Sent" domain="[('state', '=', 'sent')]" />
<filter
name="deferred"
string="Deferred"
Expand Down
1 change: 1 addition & 0 deletions mail_tracking/views/res_partner_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
name="tracking_emails_count"
widget="statinfo"
string="Tracking emails"
attrs="{'invisible': [('tracking_emails_count', '=', False)]}"
/>
</button>
</div>
Expand Down

0 comments on commit fd900e2

Please sign in to comment.