[FIX][IMP] various: unsudo mail/view controller and get_access_action
mail/view controller is a generic controller that redirects the user to a given view, depending on the record and the user. Users may be redirected to the backend form view, or to a website view. This is done notably by calling get_access_action method that gives the action to perform (act_window or url). Previously this method was called using SUPERUSER. However it was therefore impossible to know who the user was. This method is now called using the current user. Various overrides of get_access_action have been updated to add some logic and access rights check directly in the method allowing more fine-grain behavior of the access action.
This commit is contained in:
@@ -114,35 +114,37 @@ class MailController(http.Controller):
|
||||
return self._redirect_to_messaging()
|
||||
|
||||
# find the access action using sudo to have the details about the access link
|
||||
RecordModel = request.env[model]
|
||||
record_sudo = RecordModel.sudo().browse(res_id).exists()
|
||||
if not record_sudo:
|
||||
RecordModel = request.env[model].sudo(uid)
|
||||
record = RecordModel.browse(res_id).exists()
|
||||
if not record:
|
||||
# record does not seem to exist -> redirect to login
|
||||
return self._redirect_to_messaging()
|
||||
record_action = record_sudo.get_access_action()
|
||||
record_action = record.get_access_action()
|
||||
|
||||
# only URL redirections or window actions supported currently
|
||||
if not record_action['type'] in ('ir.actions.act_url', 'ir.actions.act_window'):
|
||||
return self._redirect_to_messaging()
|
||||
|
||||
# the record has an URL redirection: use it directly
|
||||
if record_action['type'] == 'ir.actions.act_url':
|
||||
return werkzeug.utils.redirect(record_action['url'])
|
||||
# other choice: act_window (no support of anything else currently)
|
||||
elif not record_action['type'] == 'ir.actions.act_window':
|
||||
return self._redirect_to_messaging()
|
||||
|
||||
# the record has a window redirection: check access rights
|
||||
if not RecordModel.sudo(uid).check_access_rights('read', raise_exception=False):
|
||||
if not RecordModel.check_access_rights('read', raise_exception=False):
|
||||
return self._redirect_to_messaging()
|
||||
try:
|
||||
RecordModel.sudo(uid).browse(res_id).exists().check_access_rule('read')
|
||||
record.check_access_rule('read')
|
||||
except AccessError:
|
||||
return self._redirect_to_messaging()
|
||||
|
||||
# at this point user can read the document so no issue with get_formview_id
|
||||
query = {}
|
||||
url_params = {
|
||||
'view_type': record_action['view_type'],
|
||||
'model': model,
|
||||
'id': res_id,
|
||||
'active_id': res_id,
|
||||
'view_id': record_sudo.get_formview_id(),
|
||||
'view_id': record.get_formview_id(),
|
||||
'action': record_action.get('id'),
|
||||
}
|
||||
url = '/web?%s#%s' % (url_encode(query), url_encode(url_params))
|
||||
|
||||
@@ -197,9 +197,11 @@ class BlogPost(models.Model):
|
||||
|
||||
@api.multi
|
||||
def get_access_action(self):
|
||||
""" Override method that generated the link to access the document. Instead
|
||||
of the classic form view, redirect to the post on the website directly """
|
||||
""" Instead of the classic form view, redirect to the post on website
|
||||
directly if user is an employee or if the post is published. """
|
||||
self.ensure_one()
|
||||
if self.env.user.share and not self.sudo().website_published:
|
||||
return super(BlogPost, self).get_access_action()
|
||||
return {
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': '/blog/%s/post/%s' % (self.blog_id.id, self.id),
|
||||
|
||||
@@ -780,8 +780,7 @@ class Post(models.Model):
|
||||
|
||||
@api.multi
|
||||
def get_access_action(self):
|
||||
""" Override method that generated the link to access the document. Instead
|
||||
of the classic form view, redirect to the post on the website directly """
|
||||
""" Instead of the classic form view, redirect to the post on the website directly """
|
||||
self.ensure_one()
|
||||
return {
|
||||
'type': 'ir.actions.act_url',
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import account_invoice
|
||||
import sale_order
|
||||
import payment
|
||||
|
||||
+15
-9
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, models
|
||||
from odoo import api, exceptions, models
|
||||
|
||||
|
||||
class AccountInvoice(models.Model):
|
||||
@@ -20,12 +20,18 @@ class AccountInvoice(models.Model):
|
||||
|
||||
@api.multi
|
||||
def get_access_action(self):
|
||||
""" Override method that generated the link to access the document. Instead
|
||||
of the classic form view, redirect to the online invoice if exists. """
|
||||
""" Instead of the classic form view, redirect to the online invoice for portal users. """
|
||||
self.ensure_one()
|
||||
return {
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': '/my/invoices', # No controller /my/invoices/<int>, only a report pdf
|
||||
'target': 'self',
|
||||
'res_id': self.id,
|
||||
}
|
||||
if self.env.user.share:
|
||||
try:
|
||||
self.check_access_rule('read')
|
||||
except exceptions.AccessError:
|
||||
pass
|
||||
else:
|
||||
return {
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': '/my/invoices', # No controller /my/invoices/<int>, only a report pdf
|
||||
'target': 'self',
|
||||
'res_id': self.id,
|
||||
}
|
||||
return super(AccountInvoice, self).get_access_action()
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, models
|
||||
from odoo import api, exceptions, models
|
||||
|
||||
|
||||
class SaleOrder(models.Model):
|
||||
@@ -10,17 +10,25 @@ class SaleOrder(models.Model):
|
||||
|
||||
@api.multi
|
||||
def get_access_action(self):
|
||||
""" Override method that generated the link to access the document. Instead
|
||||
of the classic form view, redirect to the online quote if exists. """
|
||||
""" Instead of the classic form view, redirect to the online quote for
|
||||
portal users that have access to a confirmed order. """
|
||||
# TDE note: read access on sale order to portal users granted to followed sale orders
|
||||
self.ensure_one()
|
||||
if self.state in ['draft', 'cancel']:
|
||||
return super(SaleOrder, self).get_access_action()
|
||||
return {
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': '/my/orders/%s' % self.id,
|
||||
'target': 'self',
|
||||
'res_id': self.id,
|
||||
}
|
||||
if self.env.user.share:
|
||||
try:
|
||||
self.check_access_rule('read')
|
||||
except exceptions.AccessError:
|
||||
pass
|
||||
else:
|
||||
return {
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': '/my/orders/%s' % self.id,
|
||||
'target': 'self',
|
||||
'res_id': self.id,
|
||||
}
|
||||
return super(SaleOrder, self).get_access_action()
|
||||
|
||||
def _force_lines_to_invoice_policy_order(self):
|
||||
for line in self.order_line:
|
||||
@@ -28,4 +36,3 @@ class SaleOrder(models.Model):
|
||||
line.qty_to_invoice = line.product_uom_qty - line.qty_invoiced
|
||||
else:
|
||||
line.qty_to_invoice = 0
|
||||
|
||||
|
||||
@@ -1,22 +1,29 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, models
|
||||
from odoo import api, exceptions, models
|
||||
|
||||
class Project(models.Model):
|
||||
_inherit = ['project.project']
|
||||
|
||||
@api.multi
|
||||
def get_access_action(self):
|
||||
""" Override method that generated the link to access the document. Instead
|
||||
of the classic form view, redirect to the post on the website directly """
|
||||
""" Instead of the classic form view, redirect to website for portal users
|
||||
that can read the project. """
|
||||
self.ensure_one()
|
||||
return {
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': '/my/project/%s' % self.id,
|
||||
'target': 'self',
|
||||
'res_id': self.id,
|
||||
}
|
||||
if self.env.user.share:
|
||||
try:
|
||||
self.check_access_rule('read')
|
||||
except exceptions.AccessError:
|
||||
pass
|
||||
else:
|
||||
return {
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': '/my/project/%s' % self.id,
|
||||
'target': 'self',
|
||||
'res_id': self.id,
|
||||
}
|
||||
return super(Project, self).get_access_action()
|
||||
|
||||
@api.multi
|
||||
def _notification_group_recipients(self, message, recipients, done_ids, group_data):
|
||||
@@ -35,15 +42,22 @@ class Task(models.Model):
|
||||
|
||||
@api.multi
|
||||
def get_access_action(self):
|
||||
""" Override method that generated the link to access the document. Instead
|
||||
of the classic form view, redirect to the post on the website directly """
|
||||
""" Instead of the classic form view, redirect to website for portal users
|
||||
that can read the task. """
|
||||
self.ensure_one()
|
||||
return {
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': '/my/task/%s' % self.id,
|
||||
'target': 'self',
|
||||
'res_id': self.id,
|
||||
}
|
||||
if self.env.user.share:
|
||||
try:
|
||||
self.check_access_rule('read')
|
||||
except exceptions.AccessError:
|
||||
pass
|
||||
else:
|
||||
return {
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': '/my/task/%s' % self.id,
|
||||
'target': 'self',
|
||||
'res_id': self.id,
|
||||
}
|
||||
return super(Task, self).get_access_action()
|
||||
|
||||
@api.multi
|
||||
def _notification_group_recipients(self, message, recipients, done_ids, group_data):
|
||||
@@ -55,4 +69,3 @@ class Task(models.Model):
|
||||
group_data['user'] |= recipient
|
||||
done_ids.add(recipient.id)
|
||||
return super(Task, self)._notification_group_recipients(message, recipients, done_ids, group_data)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, models
|
||||
from odoo import api, exceptions, models
|
||||
|
||||
|
||||
class Issue(models.Model):
|
||||
@@ -10,15 +10,22 @@ class Issue(models.Model):
|
||||
|
||||
@api.multi
|
||||
def get_access_action(self):
|
||||
""" Override method that generated the link to access the document. Instead
|
||||
of the classic form view, redirect to the post on the website directly """
|
||||
""" Instead of the classic form view, redirect to website for portal users
|
||||
that can read the issue. """
|
||||
self.ensure_one()
|
||||
return {
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': '/my/issues/%s' % self.id,
|
||||
'target': 'self',
|
||||
'res_id': self.id,
|
||||
}
|
||||
if self.env.user.share:
|
||||
try:
|
||||
self.check_access_rule('read')
|
||||
except exceptions.AccessError:
|
||||
pass
|
||||
else:
|
||||
return {
|
||||
'type': 'ir.actions.act_url',
|
||||
'url': '/my/issues/%s' % self.id,
|
||||
'target': 'self',
|
||||
'res_id': self.id,
|
||||
}
|
||||
return super(Issue, self).get_access_action()
|
||||
|
||||
@api.multi
|
||||
def _notification_group_recipients(self, message, recipients, done_ids, group_data):
|
||||
|
||||
@@ -148,8 +148,7 @@ class SaleOrder(models.Model):
|
||||
|
||||
@api.multi
|
||||
def get_access_action(self):
|
||||
""" Override method that generated the link to access the document. Instead
|
||||
of the classic form view, redirect to the online quote if exists. """
|
||||
""" Instead of the classic form view, redirect to the online quote if it exists. """
|
||||
self.ensure_one()
|
||||
if not self.template_id:
|
||||
return super(SaleOrder, self).get_access_action()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import account_invoice
|
||||
import ir_http
|
||||
import rating
|
||||
import product
|
||||
|
||||
@@ -425,9 +425,7 @@ class Slide(models.Model):
|
||||
|
||||
@api.multi
|
||||
def get_access_action(self):
|
||||
""" Override method that generated the link to access the document. Instead
|
||||
of the classic form view, redirect to the slide on the website directly
|
||||
if it is published. """
|
||||
""" Instead of the classic form view, redirect to website if it is published. """
|
||||
self.ensure_one()
|
||||
if self.website_published:
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user