[FIX] *: use auth='public' in controllers that use request.env

The following trick used to work, because `sudo()` was actually making
an environment for the superuser to operate upon:

request.env[...].sudo().method(...)

It no longer works in general, since `sudo()` now makes an environment
in superuser mode but with `uid=None`!  It may still work by accident
for operations that never use `env.uid`, but is broken in general.

Using `auth='public'` fixes the problem by using the public user when no
user is available.

closes odoo/odoo#34297

Signed-off-by: Olivier Dony (odo) <odo@openerp.com>
This commit is contained in:
Raphael Collet
2019-07-04 11:32:22 +00:00
parent 6230f72d2b
commit caf900e89e
14 changed files with 28 additions and 28 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ from odoo.http import Controller, Response, request, route
class website_gengo(Controller):
@route('/website/gengo_callback', type='http', auth='none', csrf=False)
@route('/website/gengo_callback', type='http', auth='public', csrf=False)
def gengo_callback(self, **post):
IrTranslationSudo = request.env['ir.translation'].sudo()
if post and post.get('job') and post.get('pgk'):
+1 -1
View File
@@ -13,7 +13,7 @@ class LivechatController(http.Controller):
# Note: the `cors` attribute on many routes is meant to allow the livechat
# to be embedded in an external website.
@http.route('/im_livechat/external_lib.<any(css,js):ext>', type='http', auth='none')
@http.route('/im_livechat/external_lib.<any(css,js):ext>', type='http', auth='public')
def livechat_lib(self, ext, **kwargs):
# _get_asset return the bundle html code (script and link list) but we want to use the attachment content
xmlid = 'im_livechat.external_lib'
+1 -1
View File
@@ -9,7 +9,7 @@ from odoo.http import request
class LinkTracker(http.Controller):
@http.route('/r/<string:code>', type='http', auth='none', website=True)
@http.route('/r/<string:code>', type='http', auth='public', website=True)
def full_url_redirect(self, code, **post):
country_code = request.session.geoip and request.session.geoip.get('country_code') or False
request.env['link.tracker.click'].sudo().add_click(
+2 -2
View File
@@ -34,7 +34,7 @@ class MailChatController(BusController):
# --------------------------
# Anonymous routes (Common Methods)
# --------------------------
@route('/mail/chat_post', type="json", auth="none", cors="*")
@route('/mail/chat_post', type="json", auth="public", cors="*")
def mail_chat_post(self, uuid, message_content, **kwargs):
# find the author from the user session, which can be None
author_id = False # message_post accept 'False' author_id, but not 'None'
@@ -46,7 +46,7 @@ class MailChatController(BusController):
message = mail_channel.sudo().with_context(mail_create_nosubscribe=True).message_post(author_id=author_id, email_from=False, body=body, message_type='comment', subtype='mail.mt_comment')
return message and message.id or False
@route(['/mail/chat_history'], type="json", auth="none", cors="*")
@route(['/mail/chat_history'], type="json", auth="public", cors="*")
def mail_chat_history(self, uuid, last_id=False, limit=20):
channel = request.env["mail.channel"].sudo().search([('uuid', '=', uuid)], limit=1)
if not channel:
+1 -1
View File
@@ -189,7 +189,7 @@ class MailController(http.Controller):
subtypes_list = sorted(subtypes_list, key=lambda it: (it['parent_model'] or '', it['res_model'] or '', it['internal'], it['sequence']))
return subtypes_list
@http.route('/mail/view', type='http', auth='none')
@http.route('/mail/view', type='http', auth='public')
def mail_action_view(self, model=None, res_id=None, access_token=None, **kwargs):
""" Generic access point from notification emails. The heuristic to
choose where to redirect the user is the following :
+7 -7
View File
@@ -80,7 +80,7 @@ class MassMailController(http.Controller):
})
return request.redirect('/web')
@http.route('/mail/mailing/unsubscribe', type='json', auth='none')
@http.route('/mail/mailing/unsubscribe', type='json', auth='public')
def unsubscribe(self, mailing_id, opt_in_ids, opt_out_ids, email, res_id, token):
mailing = request.env['mail.mass_mailing'].sudo().browse(mailing_id)
if mailing.exists():
@@ -91,7 +91,7 @@ class MassMailController(http.Controller):
return True
return 'error'
@http.route('/mail/track/<int:mail_id>/blank.gif', type='http', auth='none')
@http.route('/mail/track/<int:mail_id>/blank.gif', type='http', auth='public')
def track_mail_open(self, mail_id, **post):
""" Email tracking. """
request.env['mail.mail.statistics'].sudo().set_opened(mail_mail_ids=[mail_id])
@@ -101,7 +101,7 @@ class MassMailController(http.Controller):
return response
@http.route('/r/<string:code>/m/<int:stat_id>', type='http', auth="none")
@http.route('/r/<string:code>/m/<int:stat_id>', type='http', auth="public")
def full_url_redirect(self, code, stat_id, **post):
# don't assume geoip is set, it is part of the website module
# which mass_mailing doesn't depend on
@@ -115,7 +115,7 @@ class MassMailController(http.Controller):
)
return werkzeug.utils.redirect(request.env['link.tracker'].get_url_from_code(code), 301)
@http.route('/mailing/blacklist/check', type='json', auth='none')
@http.route('/mailing/blacklist/check', type='json', auth='public')
def blacklist_check(self, mailing_id, res_id, email, token):
if not self._valid_unsubscribe_token(mailing_id, res_id, email, token):
return 'unauthorized'
@@ -126,7 +126,7 @@ class MassMailController(http.Controller):
return False
return 'error'
@http.route('/mailing/blacklist/add', type='json', auth='none')
@http.route('/mailing/blacklist/add', type='json', auth='public')
def blacklist_add(self, mailing_id, res_id, email, token):
if not self._valid_unsubscribe_token(mailing_id, res_id, email, token):
return 'unauthorized'
@@ -138,7 +138,7 @@ class MassMailController(http.Controller):
return True
return 'error'
@http.route('/mailing/blacklist/remove', type='json', auth='none')
@http.route('/mailing/blacklist/remove', type='json', auth='public')
def blacklist_remove(self, mailing_id, res_id, email, token):
if not self._valid_unsubscribe_token(mailing_id, res_id, email, token):
return 'unauthorized'
@@ -150,7 +150,7 @@ class MassMailController(http.Controller):
return True
return 'error'
@http.route('/mailing/feedback', type='json', auth='none')
@http.route('/mailing/feedback', type='json', auth='public')
def send_feedback(self, mailing_id, res_id, email, feedback, token):
mailing = request.env['mail.mass_mailing'].sudo().browse(mailing_id)
if mailing.exists() and email:
+2 -2
View File
@@ -16,7 +16,7 @@ class AdyenController(http.Controller):
@http.route([
'/payment/adyen/return',
], type='http', auth='none', csrf=False)
], type='http', auth='public', csrf=False)
def adyen_return(self, **post):
_logger.info('Beginning Adyen form_feedback with post data %s', pprint.pformat(post)) # debug
if post.get('authResult') not in ['CANCELLED']:
@@ -25,7 +25,7 @@ class AdyenController(http.Controller):
@http.route([
'/payment/adyen/notification',
], type='http', auth='none', methods=['POST'], csrf=False)
], type='http', auth='public', methods=['POST'], csrf=False)
def adyen_notification(self, **post):
tx = post.get('merchantReference') and request.env['payment.transaction'].sudo().search([('reference', 'in', [post.get('merchantReference')])], limit=1)
if post.get('eventCode') in ['AUTHORISATION'] and tx:
+2 -2
View File
@@ -49,14 +49,14 @@ class AlipayController(http.Controller):
return 'success'
return ""
@http.route('/payment/alipay/return', type='http', auth="none", methods=['GET', 'POST'])
@http.route('/payment/alipay/return', type='http', auth="public", methods=['GET', 'POST'])
def alipay_return(self, **post):
""" Alipay return """
_logger.info('Beginning Alipay form_feedback with post data %s', pprint.pformat(post))
self._alipay_validate_data(**post)
return werkzeug.utils.redirect('/payment/process')
@http.route('/payment/alipay/notify', type='http', auth='none', methods=['POST'], csrf=False)
@http.route('/payment/alipay/notify', type='http', auth='public', methods=['POST'], csrf=False)
def alipay_notify(self, **post):
""" Alipay Notify """
_logger.info('Beginning Alipay notification form_feedback with post data %s', pprint.pformat(post))
+1 -1
View File
@@ -21,7 +21,7 @@ class BuckarooController(http.Controller):
'/payment/buckaroo/cancel',
'/payment/buckaroo/error',
'/payment/buckaroo/reject',
], type='http', auth='none', csrf=False)
], type='http', auth='public', csrf=False)
def buckaroo_return(self, **post):
""" Buckaroo."""
_logger.info('Buckaroo: entering form_feedback with post data %s', pprint.pformat(post)) # debug
+3 -3
View File
@@ -23,7 +23,7 @@ class OgoneController(http.Controller):
'/payment/ogone/decline', '/payment/ogone/test/decline',
'/payment/ogone/exception', '/payment/ogone/test/exception',
'/payment/ogone/cancel', '/payment/ogone/test/cancel',
], type='http', auth='none')
], type='http', auth='public')
def ogone_form_feedback(self, **post):
""" Ogone contacts using GET, at least for accept """
_logger.info('Ogone: entering form_feedback with post data %s', pprint.pformat(post)) # debug
@@ -110,13 +110,13 @@ class OgoneController(http.Controller):
'/payment/ogone/validate/accept',
'/payment/ogone/validate/decline',
'/payment/ogone/validate/exception',
], type='http', auth='none')
], type='http', auth='public')
def ogone_validation_form_feedback(self, **post):
""" Feedback from 3d secure for a bank card validation """
request.env['payment.transaction'].sudo().form_feedback(post, 'ogone')
return werkzeug.utils.redirect("/payment/process")
@http.route(['/payment/ogone/s2s/feedback'], auth='none', csrf=False)
@http.route(['/payment/ogone/s2s/feedback'], auth='public', csrf=False)
def feedback(self, **kwargs):
try:
tx = request.env['payment.transaction'].sudo()._ogone_form_get_tx_from_data(kwargs)
+3 -3
View File
@@ -86,7 +86,7 @@ class PaypalController(http.Controller):
tx.sudo()._set_transaction_error('Unrecognized error from Paypal. Please contact your administrator.')
return res
@http.route('/payment/paypal/ipn/', type='http', auth='none', methods=['POST'], csrf=False)
@http.route('/payment/paypal/ipn/', type='http', auth='public', methods=['POST'], csrf=False)
def paypal_ipn(self, **post):
""" Paypal IPN. """
_logger.info('Beginning Paypal IPN form_feedback with post data %s', pprint.pformat(post)) # debug
@@ -96,7 +96,7 @@ class PaypalController(http.Controller):
_logger.exception('Unable to validate the Paypal payment')
return ''
@http.route('/payment/paypal/dpn', type='http', auth="none", methods=['POST', 'GET'], csrf=False)
@http.route('/payment/paypal/dpn', type='http', auth="public", methods=['POST', 'GET'], csrf=False)
def paypal_dpn(self, **post):
""" Paypal DPN """
_logger.info('Beginning Paypal DPN form_feedback with post data %s', pprint.pformat(post)) # debug
@@ -106,7 +106,7 @@ class PaypalController(http.Controller):
_logger.exception('Unable to validate the Paypal payment')
return werkzeug.utils.redirect('/payment/process')
@http.route('/payment/paypal/cancel', type='http', auth="none", csrf=False)
@http.route('/payment/paypal/cancel', type='http', auth="public", csrf=False)
def paypal_cancel(self, **post):
""" When the user cancels its Paypal payment: GET on this route """
_logger.info('Beginning Paypal cancel with post data %s', pprint.pformat(post)) # debug
+2 -2
View File
@@ -27,14 +27,14 @@ class SipsController(http.Controller):
@http.route([
'/payment/sips/ipn/'],
type='http', auth='none', methods=['POST'], csrf=False)
type='http', auth='public', methods=['POST'], csrf=False)
def sips_ipn(self, **post):
""" Sips IPN. """
self.sips_validate_data(**post)
return ''
@http.route([
'/payment/sips/dpn'], type='http', auth="none", methods=['POST'], csrf=False)
'/payment/sips/dpn'], type='http', auth="public", methods=['POST'], csrf=False)
def sips_dpn(self, **post):
""" Sips DPN """
try:
+1 -1
View File
@@ -14,7 +14,7 @@ class OgoneController(http.Controller):
@http.route([
'/payment/transfer/feedback',
], type='http', auth='none', csrf=False)
], type='http', auth='public', csrf=False)
def transfer_form_feedback(self, **post):
_logger.info('Beginning form_feedback with post data %s', pprint.pformat(post)) # debug
request.env['payment.transaction'].sudo().form_feedback(post, 'transfer')
+1 -1
View File
@@ -619,7 +619,7 @@ class WebClient(http.Controller):
return {"modules": translations_per_module,
"lang_parameters": None}
@http.route('/web/webclient/translations/<string:unique>', type='http', auth="none")
@http.route('/web/webclient/translations/<string:unique>', type='http', auth="public")
def translations(self, unique, mods=None, lang=None):
"""
Load the translations for the specified language and modules