summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Delavallée <tde@odoo.com>2016-09-15 11:22:53 +0200
committerThibault Delavallée <tde@odoo.com>2016-09-26 14:42:25 +0200
commitfcd6813dc9ae3cc93ea5ffff04045aed1a03a378 (patch)
tree00dbb840126390eeb088bb03ef2e61d275794dd0
parentd59d95107e61a238acfdfeb117f2f0c4d7b20e02 (diff)
[FIX][IMP] various: unsudo mail/view controller and get_access_action
This is a backport of saas-13 commit a9bd9ab16087142e27076c63ef60a0467f0bcfad. 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.
-rw-r--r--addons/mail/controllers/main.py22
-rw-r--r--addons/website_blog/models/website_blog.py5
-rw-r--r--addons/website_forum/models/forum.py3
-rw-r--r--addons/website_portal_sale/models/__init__.py1
-rw-r--r--addons/website_portal_sale/models/account_invoice.py (renamed from addons/website_sale/models/account_invoice.py)24
-rw-r--r--addons/website_portal_sale/models/sale_order.py27
-rw-r--r--addons/website_project/models/project.py49
-rw-r--r--addons/website_project_issue/models/project_issue.py25
-rw-r--r--addons/website_sale/models/__init__.py1
-rw-r--r--addons/website_slides/models/slides.py4
10 files changed, 98 insertions, 63 deletions
diff --git a/addons/mail/controllers/main.py b/addons/mail/controllers/main.py
index 3fdcb922407..3831edbb851 100644
--- a/addons/mail/controllers/main.py
+++ b/addons/mail/controllers/main.py
@@ -113,35 +113,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))
diff --git a/addons/website_blog/models/website_blog.py b/addons/website_blog/models/website_blog.py
index eb919985971..415e0355ac8 100644
--- a/addons/website_blog/models/website_blog.py
+++ b/addons/website_blog/models/website_blog.py
@@ -264,7 +264,10 @@ class BlogPost(osv.Model):
def get_access_action(self, cr, uid, ids, context=None):
""" Override method that generated the link to access the document. Instead
of the classic form view, redirect to the post on the website directly """
- post = self.browse(cr, uid, ids[0], context=context)
+ post = self.browse(cr, SUPERUSER_ID, ids[0], context=context)
+ user = self.pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context)
+ if user.share and not post.website_published:
+ return super(BlogPost, self).get_access_action(cr, uid, ids, context=context)
return {
'type': 'ir.actions.act_url',
'url': '/blog/%s/post/%s' % (post.blog_id.id, post.id),
diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py
index 84c1f48766a..508ec6972f2 100644
--- a/addons/website_forum/models/forum.py
+++ b/addons/website_forum/models/forum.py
@@ -782,8 +782,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',
diff --git a/addons/website_portal_sale/models/__init__.py b/addons/website_portal_sale/models/__init__.py
index 97f7899573c..501e7457bdb 100644
--- a/addons/website_portal_sale/models/__init__.py
+++ b/addons/website_portal_sale/models/__init__.py
@@ -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
diff --git a/addons/website_sale/models/account_invoice.py b/addons/website_portal_sale/models/account_invoice.py
index 8011fab497f..a42947c59e8 100644
--- a/addons/website_sale/models/account_invoice.py
+++ b/addons/website_portal_sale/models/account_invoice.py
@@ -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()
diff --git a/addons/website_portal_sale/models/sale_order.py b/addons/website_portal_sale/models/sale_order.py
index 944f7b6a6f7..2f6091c95a9 100644
--- a/addons/website_portal_sale/models/sale_order.py
+++ b/addons/website_portal_sale/models/sale_order.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from openerp import api, models
+from openerp import api, exceptions, models
class sale_order(models.Model):
@@ -9,17 +9,25 @@ class sale_order(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(sale_order, 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(sale_order, self).get_access_action()
def _force_lines_to_invoice_policy_order(self):
for line in self.order_line:
@@ -27,4 +35,3 @@ class sale_order(models.Model):
line.qty_to_invoice = line.product_uom_qty - line.qty_invoiced
else:
line.qty_to_invoice = 0
-
diff --git a/addons/website_project/models/project.py b/addons/website_project/models/project.py
index e44a9f5f131..101b7abb82c 100644
--- a/addons/website_project/models/project.py
+++ b/addons/website_project/models/project.py
@@ -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)
-
diff --git a/addons/website_project_issue/models/project_issue.py b/addons/website_project_issue/models/project_issue.py
index ff0888b4887..b30a375e075 100644
--- a/addons/website_project_issue/models/project_issue.py
+++ b/addons/website_project_issue/models/project_issue.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from openerp import api, models
+from openerp 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):
diff --git a/addons/website_sale/models/__init__.py b/addons/website_sale/models/__init__.py
index 3f8dbc63ee7..a40ad2379a6 100644
--- a/addons/website_sale/models/__init__.py
+++ b/addons/website_sale/models/__init__.py
@@ -1,4 +1,3 @@
-import account_invoice
import ir_http
import rating
import product
diff --git a/addons/website_slides/models/slides.py b/addons/website_slides/models/slides.py
index b4127f232d3..ba357b150a7 100644
--- a/addons/website_slides/models/slides.py
+++ b/addons/website_slides/models/slides.py
@@ -422,9 +422,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 {