[IMP] *: always use Odoo Response

This branch adds request.redirect on all requests.
In case of a front end request, we do an url_for to the location.

We removed redirect_with_hash that was only for retro compatibility

local_redirect has been renamed to redirect_query, and param keep_hash has been
removed and moved.

Default code for redirect is 303 now instead of 302.

Now redirect and redirect_query make local redirect by default, you need to
pass local=False to make external redirect.

All werkeug.utils.redirect has been replaced by request.redirect.

Http.redirect now use an http.Response type, and it become easy to add an
override like 'set_cookies' e.g.

Dispatch of a website.page return an http.response too, so we first need to
check if it is a cached version before to check if it is an Odoo Response.

Migrate your code:

http.redirect -> request.redirect(location, code, local)
http.local_redirect -> request.redirect_query(location, query, code, local)
http.redirect_with_hash -> request.redirect

Courtesy of odony for help and review ;)

closes odoo/odoo#72599

Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
This commit is contained in:
Jeremy Kersten
2021-07-08 07:00:06 +00:00
parent 1bf9367c6f
commit 478068c829
44 changed files with 161 additions and 199 deletions
+2 -2
View File
@@ -88,7 +88,7 @@ class OAuthLogin(Home):
ensure_db()
if request.httprequest.method == 'GET' and request.session.uid and request.params.get('redirect'):
# Redirect if already logged in and redirect param is present
return http.redirect_with_hash(request.params.get('redirect'))
return request.redirect(request.params.get('redirect'))
providers = self.list_providers()
response = super(OAuthLogin, self).web_login(*args, **kw)
@@ -155,7 +155,7 @@ class OAuthController(http.Controller):
# oauth credentials not valid, user could be on a temporary session
_logger.info('OAuth2: access denied, redirect to main page in case a valid session exists, without setting cookies')
url = "/web/login?oauth_error=3"
redirect = werkzeug.utils.redirect(url, 303)
redirect = request.redirect(url, 303)
redirect.autocorrect_location_header = False
return redirect
except Exception as e:
+1 -1
View File
@@ -22,7 +22,7 @@ class AuthSignupHome(Home):
response.qcontext.update(self.get_auth_signup_config())
if request.httprequest.method == 'GET' and request.session.uid and request.params.get('redirect'):
# Redirect if already logged in and redirect param is present
return http.redirect_with_hash(request.params.get('redirect'))
return request.redirect(request.params.get('redirect'))
return response
@http.route('/web/signup', type='http', auth='public', website=True, sitemap=False)
+3 -3
View File
@@ -15,10 +15,10 @@ class Home(odoo.addons.web.controllers.main.Home):
)
def web_totp(self, redirect=None, **kwargs):
if request.session.uid:
return http.redirect_with_hash(self._login_redirect(request.session.uid, redirect=redirect))
return request.redirect(self._login_redirect(request.session.uid, redirect=redirect))
if not request.session.pre_uid:
return http.redirect_with_hash('/web/login')
return request.redirect('/web/login')
error = None
if request.httprequest.method == 'POST':
@@ -32,7 +32,7 @@ class Home(odoo.addons.web.controllers.main.Home):
error = _("Invalid authentication code format.")
else:
request.session.finalize()
return http.redirect_with_hash(self._login_redirect(request.session.uid, redirect=redirect))
return request.redirect(self._login_redirect(request.session.uid, redirect=redirect))
return request.render('auth_totp.auth_totp_form', {
'error': error,
+1 -3
View File
@@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import werkzeug
import odoo.http as http
from odoo.http import request
@@ -70,7 +68,7 @@ class CalendarController(http.Controller):
# If user is internal and logged, redirect to form view of event
# otherwise, display the simplifyed web page with event informations
if request.session.uid and request.env['res.users'].browse(request.session.uid).user_has_groups('base.group_user'):
return werkzeug.utils.redirect('/web?db=%s#id=%s&view_type=form&model=calendar.event' % (request.env.cr.dbname, id))
return request.redirect('/web?db=%s#id=%s&view_type=form&model=calendar.event' % (request.env.cr.dbname, id))
# NOTE : we don't use request.render() since:
# - we need a template rendering which is not lazy, to render before cursor closing
@@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import werkzeug
from odoo import http
from odoo.http import request
from odoo.tools import html2plaintext
@@ -36,7 +34,7 @@ class CrmClient(http.Controller):
for supporting older versions
"""
server_action = http.request.env.ref("crm_mail_plugin.lead_creation_prefilled_action")
return werkzeug.utils.redirect(
return request.redirect(
'/web#action=%s&model=crm.lead&partner_id=%s' % (server_action.id, int(partner_id)))
@http.route('/mail_plugin/lead/create', type='json', auth='outlook', cors="*")
@@ -61,4 +59,4 @@ class CrmClient(http.Controller):
"""
action = http.request.env.ref("crm.crm_lead_view_form")
url = '/web#id=%s&action=%s&model=crm.lead&edit=1&model=crm.lead' % (lead_id, action.id)
return werkzeug.utils.redirect(url)
return request.redirect(url)
+10 -12
View File
@@ -2,9 +2,8 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import json
from werkzeug.utils import redirect
from odoo import http, registry
from odoo import http
from odoo.http import request
@@ -18,13 +17,12 @@ class GoogleAuth(http.Controller):
service = state.get('s')
url_return = state.get('f')
with registry(dbname).cursor() as cr:
if kw.get('code'):
access_token, refresh_token, ttl = request.env['google.service']._get_google_tokens(kw['code'], service)
# LUL TODO only defined in google_calendar
request.env.user._set_auth_tokens(access_token, refresh_token, ttl)
return redirect(url_return)
elif kw.get('error'):
return redirect("%s%s%s" % (url_return, "?error=", kw['error']))
else:
return redirect("%s%s" % (url_return, "?error=Unknown_error"))
if kw.get('code'):
access_token, refresh_token, ttl = request.env['google.service']._get_google_tokens(kw['code'], service)
# LUL TODO only defined in google_calendar
request.env.user._set_auth_tokens(access_token, refresh_token, ttl)
return request.redirect(url_return)
elif kw.get('error'):
return request.redirect("%s%s%s" % (url_return, "?error=", kw['error']))
else:
return request.redirect("%s%s" % (url_return, "?error=Unknown_error"))
+9 -5
View File
@@ -423,7 +423,7 @@ class IrHttp(models.AbstractModel):
# handle // in url
if request.httprequest.method == 'GET' and '//' in request.httprequest.path:
new_url = request.httprequest.path.replace('//', '/') + '?' + request.httprequest.query_string.decode('utf-8')
return werkzeug.utils.redirect(new_url, 301)
return request.redirect(new_url, code=301)
# locate the controller method
try:
@@ -456,8 +456,6 @@ class IrHttp(models.AbstractModel):
# For website routes (only), add website params on `request`
if request.is_frontend:
request.redirect = lambda url, code=302: werkzeug.utils.redirect(url_for(url), code)
cls._add_dispatch_parameters(func)
path = request.httprequest.path.split('/')
@@ -493,7 +491,7 @@ class IrHttp(models.AbstractModel):
path = request.httprequest.path[:-1]
if request.httprequest.query_string:
path += '?' + request.httprequest.query_string.decode('utf-8')
return werkzeug.utils.redirect(path, code=301)
return request.redirect(path, code=301)
path.pop(1)
routing_error = None
return cls.reroute('/'.join(path) or '/')
@@ -521,6 +519,12 @@ class IrHttp(models.AbstractModel):
return result
@classmethod
def _redirect(cls, location, code=303):
if request and request.db and request.is_frontend:
location = url_for(location)
return super()._redirect(location, code)
@classmethod
def reroute(cls, path):
if not hasattr(request, 'rerouting'):
@@ -557,7 +561,7 @@ class IrHttp(models.AbstractModel):
path = '/' + request.lang.url_code + path
if request.httprequest.query_string:
path += '?' + request.httprequest.query_string.decode('utf-8')
return werkzeug.utils.redirect(path, code=301)
return request.redirect(path, code=301)
@classmethod
def _get_exception_code_values(cls, exception):
+1 -3
View File
@@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import werkzeug
from odoo import http
from odoo.http import request
@@ -18,4 +16,4 @@ class LinkTracker(http.Controller):
country_code=country_code
)
redirect_url = request.env['link.tracker'].get_url_from_code(code)
return werkzeug.utils.redirect(redirect_url or '', 301)
return request.redirect(redirect_url or '', code=301, local=False)
+3 -3
View File
@@ -23,7 +23,7 @@ class MailController(http.Controller):
@classmethod
def _redirect_to_messaging(cls):
url = '/web#%s' % url_encode({'action': 'mail.action_discuss'})
return werkzeug.utils.redirect(url)
return request.redirect(url)
@classmethod
def _check_token(cls, token):
@@ -106,7 +106,7 @@ class MailController(http.Controller):
record_action.pop('target_type', None)
# the record has an URL redirection: use it directly
if record_action['type'] == 'ir.actions.act_url':
return werkzeug.utils.redirect(record_action['url'])
return request.redirect(record_action['url'])
# other choice: act_window (no support of anything else currently)
elif not record_action['type'] == 'ir.actions.act_window':
return cls._redirect_to_messaging()
@@ -124,7 +124,7 @@ class MailController(http.Controller):
if cids:
url_params['cids'] = ','.join([str(cid) for cid in cids])
url = '/web?#%s' % url_encode(url_params)
return werkzeug.utils.redirect(url)
return request.redirect(url)
@http.route('/mail/read_followers', type='json', auth='user')
def read_followers(self, res_model, res_id):
@@ -50,7 +50,7 @@ class Authenticate(http.Controller):
else:
params.update({'success': 0, 'state': kw.get('state', '')})
updated_redirect = parsed_redirect.replace(query=werkzeug.urls.url_encode(params))
return werkzeug.utils.redirect(updated_redirect.to_url())
return request.redirect(updated_redirect.to_url())
# In this case, an exception will be thrown in case of preflight request if only POST is allowed.
@http.route(['/mail_client_extension/auth/access_token', '/mail_plugin/auth/access_token'], type='json', auth="none", cors="*",
+1 -1
View File
@@ -146,7 +146,7 @@ class MassMailController(http.Controller):
country_code=country_code,
mailing_trace_id=mailing_trace_id
)
return werkzeug.utils.redirect(request.env['link.tracker'].get_url_from_code(code), 301)
return request.redirect(request.env['link.tracker'].get_url_from_code(code), code=301, local=False)
@http.route('/mailing/blacklist/check', type='json', auth='public')
def blacklist_check(self, mailing_id, res_id, email, token):
+3 -5
View File
@@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import werkzeug
from odoo import http, _
from odoo.addons.phone_validation.tools import phone_validation
from odoo.http import request
@@ -30,7 +28,7 @@ class MailingSMSController(http.Controller):
def blacklist_page(self, mailing_id, trace_code, **post):
check_res = self._check_trace(mailing_id, trace_code)
if not check_res.get('trace'):
return werkzeug.utils.redirect('/web')
return request.redirect('/web')
return request.render('mass_mailing_sms.blacklist_main', {
'mailing_id': mailing_id,
'trace_code': trace_code,
@@ -40,7 +38,7 @@ class MailingSMSController(http.Controller):
def blacklist_number(self, mailing_id, trace_code, **post):
check_res = self._check_trace(mailing_id, trace_code)
if not check_res.get('trace'):
return werkzeug.utils.redirect('/web')
return request.redirect('/web')
country_code = request.session.get('geoip', False) and request.session.geoip.get('country_code', False) if request.session.get('geoip') else None
# parse and validate number
sms_number = post.get('sms_number', '').strip(' ')
@@ -102,4 +100,4 @@ class MailingSMSController(http.Controller):
country_code=country_code,
mailing_trace_id=trace_id
)
return werkzeug.utils.redirect(request.env['link.tracker'].get_url_from_code(code), 301)
return request.redirect(request.env['link.tracker'].get_url_from_code(code), code=301, local=False)
+9 -11
View File
@@ -2,9 +2,8 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import json
from werkzeug.utils import redirect
from odoo import http, registry
from odoo import http
from odoo.http import request
@@ -18,12 +17,11 @@ class MicrosoftAuth(http.Controller):
service = state.get('s')
url_return = state.get('f')
with registry(dbname).cursor() as cr:
if kw.get('code'):
access_token, refresh_token, ttl = request.env['microsoft.service']._get_microsoft_tokens(kw['code'], service)
request.env.user._set_microsoft_auth_tokens(access_token, refresh_token, ttl)
return redirect(url_return)
elif kw.get('error'):
return redirect("%s%s%s" % (url_return, "?error=", kw['error']))
else:
return redirect("%s%s" % (url_return, "?error=Unknown_error"))
if kw.get('code'):
access_token, refresh_token, ttl = request.env['microsoft.service']._get_microsoft_tokens(kw['code'], service)
request.env.user._set_microsoft_auth_tokens(access_token, refresh_token, ttl)
return request.redirect(url_return)
elif kw.get('error'):
return request.redirect("%s%s%s" % (url_return, "?error=", kw['error']))
else:
return request.redirect("%s%s" % (url_return, "?error=Unknown_error"))
+1 -1
View File
@@ -234,7 +234,7 @@ class AdyenController(http.Controller):
)
# Redirect the user to the status page
return werkzeug.utils.redirect('/payment/status')
return request.redirect('/payment/status')
@http.route('/payment/adyen/notification', type='json', auth='public')
def adyen_notification(self):
+1 -2
View File
@@ -4,7 +4,6 @@ import logging
import pprint
import requests
import werkzeug
from odoo import _, http
from odoo.exceptions import ValidationError
@@ -22,7 +21,7 @@ class AlipayController(http.Controller):
""" Alipay return """
_logger.info("received Alipay return data:\n%s", pprint.pformat(data))
request.env['payment.transaction'].sudo()._handle_feedback_data('alipay', data)
return werkzeug.utils.redirect('/payment/status')
return request.redirect('/payment/status')
@http.route(_notify_url, type='http', auth='public', methods=['POST'], csrf=False)
def alipay_notify(self, **post):
+1 -3
View File
@@ -3,8 +3,6 @@
import logging
import pprint
import werkzeug
from odoo import http
from odoo.http import request
@@ -22,4 +20,4 @@ class BuckarooController(http.Controller):
"""
_logger.info("received notification data:\n%s", pprint.pformat(data))
request.env['payment.transaction'].sudo()._handle_feedback_data('buckaroo', data)
return werkzeug.utils.redirect('/payment/status')
return request.redirect('/payment/status')
+2 -2
View File
@@ -95,7 +95,7 @@ class OgoneController(http.Controller):
else:
if tx_sudo.state in ('cancel', 'error'):
tx_sudo.token_id.active = False # The initial payment failed, archive the token
return werkzeug.utils.redirect('/payment/status')
return request.redirect('/payment/status')
@http.route(
[_directlink_return_url] + _backward_compatibility_urls, type='http', auth='public',
@@ -124,7 +124,7 @@ class OgoneController(http.Controller):
tx_sudo = request.env['payment.transaction'].sudo()._handle_feedback_data('ogone', data)
if tx_sudo.state in ('cancel', 'error'):
tx_sudo.token_id.active = False # The initial payment failed, archive the token
return werkzeug.utils.redirect('/payment/status')
return request.redirect('/payment/status')
def _homogenize_data(self, data):
""" Format keys to follow an homogenized convention inspired by Ogone Directlink API.
+1 -2
View File
@@ -4,7 +4,6 @@ import logging
import pprint
import requests
import werkzeug
from odoo import _, http
from odoo.exceptions import ValidationError
@@ -34,7 +33,7 @@ class PaypalController(http.Controller):
request.env['payment.transaction'].sudo()._handle_feedback_data('paypal', data)
else:
pass # The customer has cancelled the payment, don't do anything
return werkzeug.utils.redirect('/payment/status')
return request.redirect('/payment/status')
@http.route(_notify_url, type='http', auth='public', methods=['GET', 'POST'], csrf=False)
def paypal_ipn(self, **data):
+1 -3
View File
@@ -3,8 +3,6 @@
import logging
import pprint
import werkzeug
from odoo import http
from odoo.http import request
@@ -18,4 +16,4 @@ class PayuLatamController(http.Controller):
def payulatam_return(self, **data):
_logger.info("entering _handle_feedback_data with data:\n%s", pprint.pformat(data))
request.env['payment.transaction'].sudo()._handle_feedback_data('payulatam', data)
return werkzeug.utils.redirect('/payment/status')
return request.redirect('/payment/status')
+1 -3
View File
@@ -3,8 +3,6 @@
import logging
import pprint
import werkzeug
from odoo import http
from odoo.http import request
@@ -18,4 +16,4 @@ class PayUMoneyController(http.Controller):
def payumoney_return(self, **data):
_logger.info("entering handle_feedback_data with data:\n%s", pprint.pformat(data))
request.env['payment.transaction'].sudo()._handle_feedback_data('payumoney', data)
return werkzeug.utils.redirect('/payment/status')
return request.redirect('/payment/status')
+1 -3
View File
@@ -4,8 +4,6 @@
import logging
import pprint
import werkzeug
from odoo import http
from odoo.exceptions import ValidationError
from odoo.http import request
@@ -32,7 +30,7 @@ class SipsController(http.Controller):
request.env['payment.transaction'].sudo()._handle_feedback_data('sips', post)
except ValidationError:
pass
return werkzeug.utils.redirect('/payment/status')
return request.redirect('/payment/status')
@http.route(_notify_url, type='http', auth='public', methods=['POST'], csrf=False)
def sips_ipn(self, **post):
+2 -2
View File
@@ -45,7 +45,7 @@ class StripeController(http.Controller):
request.env['payment.transaction'].sudo()._handle_feedback_data('stripe', data)
# Redirect the user to the status page
return werkzeug.utils.redirect('/payment/status')
return request.redirect('/payment/status')
@http.route(_validation_return_url, type='http', auth='public', csrf=False)
def stripe_return_from_validation(self, **data):
@@ -71,7 +71,7 @@ class StripeController(http.Controller):
request.env['payment.transaction'].sudo()._handle_feedback_data('stripe', data)
# Redirect the user to the status page
return werkzeug.utils.redirect('/payment/status')
return request.redirect('/payment/status')
@http.route('/payment/stripe/webhook', type='json', auth='public')
def stripe_webhook(self):
+1 -3
View File
@@ -3,8 +3,6 @@
import logging
import pprint
import werkzeug
from odoo import http
from odoo.http import request
@@ -18,4 +16,4 @@ class TransferController(http.Controller):
def transfer_form_feedback(self, **post):
_logger.info("beginning _handle_feedback_data with post data %s", pprint.pformat(post))
request.env['payment.transaction'].sudo()._handle_feedback_data('transfer', post)
return werkzeug.utils.redirect('/payment/status')
return request.redirect('/payment/status')
+1 -2
View File
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
import json
import logging
import werkzeug.utils
from odoo import http
from odoo.http import request
@@ -49,7 +48,7 @@ class PosController(http.Controller):
pos_session = request.env['pos.session'].sudo().search(domain, limit=1)
if not pos_session:
return werkzeug.utils.redirect('/web#action=point_of_sale.action_client_pos_menu')
return request.redirect('/web#action=point_of_sale.action_client_pos_menu')
# The POS only work in one company, so we enforce the one of the session in the context
session_info = request.env['ir.http'].session_info()
session_info['user_context']['allowed_company_ids'] = pos_session.company_id.ids
+1 -2
View File
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import werkzeug
from werkzeug import urls
from werkzeug.exceptions import NotFound, Forbidden
@@ -241,5 +240,5 @@ class MailController(main.MailController):
url_params = url.decode_query()
url_params.update([("pid", pid), ("hash", hash)])
url = url.replace(query=urls.url_encode(url_params)).to_url()
return werkzeug.utils.redirect(url)
return request.redirect(url)
return super(MailController, cls)._redirect_to_record(model, res_id, access_token=access_token)
+2 -2
View File
@@ -11,7 +11,7 @@ class Home(main.Home):
@http.route()
def index(self, *args, **kw):
if request.session.uid and not request.env['res.users'].sudo().browse(request.session.uid).has_group('base.group_user'):
return http.local_redirect('/my', query=request.params, keep_hash=True)
return request.redirect_query('/my', query=request.params)
return super(Home, self).index(*args, **kw)
def _login_redirect(self, uid, redirect=None):
@@ -22,5 +22,5 @@ class Home(main.Home):
@http.route('/web', type='http', auth="none")
def web_client(self, s_action=None, **kw):
if request.session.uid and not request.env['res.users'].sudo().browse(request.session.uid).has_group('base.group_user'):
return http.local_redirect('/my', query=request.params, keep_hash=True)
return request.redirect_query('/my', query=request.params)
return super(Home, self).web_client(s_action, **kw)
+3 -3
View File
@@ -141,7 +141,7 @@ class TestAccessRightsControllers(HttpCase):
url='/my/orders/%s?report_type=pdf' % portal_so.id,
allow_redirects=False,
)
self.assertEqual(req.status_code, 302)
self.assertEqual(req.status_code, 303)
# or with a random token
req = self.url_open(
@@ -151,7 +151,7 @@ class TestAccessRightsControllers(HttpCase):
),
allow_redirects=False,
)
self.assertEqual(req.status_code, 302)
self.assertEqual(req.status_code, 303)
# but works fine with the right token
req = self.url_open(
@@ -177,4 +177,4 @@ class TestAccessRightsControllers(HttpCase):
url='/my/orders/%s?report_type=pdf' % private_so.id,
allow_redirects=False,
)
self.assertEqual(req.status_code, 302)
self.assertEqual(req.status_code, 303)
+6 -6
View File
@@ -141,7 +141,7 @@ class Survey(http.Controller):
elif error_key == 'answer_deadline' and answer_sudo.access_token:
return request.render("survey.survey_closed_expired", {'survey': survey_sudo})
return werkzeug.utils.redirect("/")
return request.redirect("/")
# ------------------------------------------------------------
# TEST / RETRY SURVEY ROUTES
@@ -155,7 +155,7 @@ class Survey(http.Controller):
try:
answer_sudo = survey_sudo._create_answer(user=request.env.user, test_entry=True)
except:
return werkzeug.utils.redirect('/')
return request.redirect('/')
return request.redirect('/survey/start/%s?%s' % (survey_sudo.access_token, keep_query('*', answer_token=answer_sudo.access_token)))
@http.route('/survey/retry/<string:survey_token>/<string:answer_token>', type='http', auth='public', website=True)
@@ -169,7 +169,7 @@ class Survey(http.Controller):
survey_sudo, answer_sudo = access_data['survey_sudo'], access_data['answer_sudo']
if not answer_sudo:
# attempts to 'retry' without having tried first
return werkzeug.utils.redirect("/")
return request.redirect("/")
try:
retry_answer_sudo = survey_sudo._create_answer(
@@ -181,7 +181,7 @@ class Survey(http.Controller):
**self._prepare_retry_additional_values(answer_sudo)
)
except:
return werkzeug.utils.redirect("/")
return request.redirect("/")
return request.redirect('/survey/start/%s?%s' % (survey_sudo.access_token, keep_query('*', answer_token=retry_answer_sudo.access_token)))
def _prepare_retry_additional_values(self, answer):
@@ -227,7 +227,7 @@ class Survey(http.Controller):
survey_sudo.with_user(request.env.user).check_access_rights('read')
survey_sudo.with_user(request.env.user).check_access_rule('read')
except:
return werkzeug.utils.redirect("/")
return request.redirect("/")
else:
return request.render("survey.survey_403_page", {'survey': survey_sudo})
@@ -598,7 +598,7 @@ class Survey(http.Controller):
if not survey:
# no certification found
return werkzeug.utils.redirect("/")
return request.redirect("/")
succeeded_attempt = request.env['survey.user_input'].sudo().search([
('partner_id', '=', request.env.user.partner_id.id),
@@ -3,7 +3,6 @@
import datetime
import json
import werkzeug
from dateutil.relativedelta import relativedelta
from werkzeug.exceptions import NotFound
@@ -177,9 +176,9 @@ class UserInputSession(http.Controller):
survey = self._fetch_from_session_code(session_code)
if survey and survey.session_state in ['ready', 'in_progress']:
return werkzeug.utils.redirect("/survey/start/%s" % survey.access_token)
return request.redirect("/survey/start/%s" % survey.access_token)
return werkzeug.utils.redirect("/s")
return request.redirect("/s")
@http.route('/survey/check_session_code/<string:session_code>', type='json', auth='public', website=True)
def survey_check_session_code(self, session_code):
+16 -24
View File
@@ -118,17 +118,9 @@ def serialize_exception(f):
return werkzeug.exceptions.InternalServerError(json.dumps(error))
return wrap
def redirect_with_hash(*args, **kw):
"""
.. deprecated:: 8.0
Use the ``http.redirect_with_hash()`` function instead.
"""
return http.redirect_with_hash(*args, **kw)
def abort_and_redirect(url):
r = request.httprequest
response = werkzeug.utils.redirect(url, 302)
response = request.redirect(url, 302)
response = r.app.get_response(r, response, explicit_session=False)
werkzeug.exceptions.abort(response)
@@ -173,7 +165,7 @@ def ensure_db(redirect='/web/database/selector'):
# if no db can be found til here, send to the database selector
# the database selector will redirect to database manager if needed
if not db:
werkzeug.exceptions.abort(werkzeug.utils.redirect(redirect, 303))
werkzeug.exceptions.abort(request.redirect(redirect, 303))
# always switch the session to the computed db
if db != request.session.db:
@@ -245,7 +237,7 @@ def login_and_redirect(db, login, key, redirect_url='/web'):
return set_cookie_and_redirect(redirect_url)
def set_cookie_and_redirect(redirect_url):
redirect = werkzeug.utils.redirect(redirect_url, 303)
redirect = request.redirect(redirect_url, 303)
redirect.autocorrect_location_header = False
return redirect
@@ -818,16 +810,16 @@ class Home(http.Controller):
@http.route('/', type='http', auth="none")
def index(self, s_action=None, db=None, **kw):
return http.local_redirect('/web', query=request.params, keep_hash=True)
return request.redirect_query('/web', query=request.params)
# ideally, this route should be `auth="user"` but that don't work in non-monodb mode.
@http.route('/web', type='http', auth="none")
def web_client(self, s_action=None, **kw):
ensure_db()
if not request.session.uid:
return werkzeug.utils.redirect('/web/login', 303)
return request.redirect('/web/login', 303)
if kw.get('redirect'):
return werkzeug.utils.redirect(kw.get('redirect'), 303)
return request.redirect(kw.get('redirect'), 303)
request.uid = request.session.uid
try:
@@ -836,7 +828,7 @@ class Home(http.Controller):
response.headers['X-Frame-Options'] = 'DENY'
return response
except AccessError:
return werkzeug.utils.redirect('/web/login?error=access')
return request.redirect('/web/login?error=access')
@http.route('/web/webclient/load_menus/<string:unique>', type='http', auth='user', methods=['GET'])
def web_load_menus(self, unique):
@@ -863,7 +855,7 @@ class Home(http.Controller):
ensure_db()
request.params['login_success'] = False
if request.httprequest.method == 'GET' and redirect and request.session.uid:
return http.redirect_with_hash(redirect)
return request.redirect(redirect)
if not request.uid:
request.uid = odoo.SUPERUSER_ID
@@ -879,7 +871,7 @@ class Home(http.Controller):
try:
uid = request.session.authenticate(request.session.db, request.params['login'], request.params['password'])
request.params['login_success'] = True
return http.redirect_with_hash(self._login_redirect(uid, redirect=redirect))
return request.redirect(self._login_redirect(uid, redirect=redirect))
except odoo.exceptions.AccessDenied as e:
request.uid = old_uid
if e.args == odoo.exceptions.AccessDenied().args:
@@ -909,7 +901,7 @@ class Home(http.Controller):
request.env['res.users'].clear_caches()
request.session.session_token = security.compute_session_token(request.session, request.env)
return http.local_redirect(self._login_redirect(uid), keep_hash=True)
return request.redirect(self._login_redirect(uid))
class WebClient(http.Controller):
@@ -1088,7 +1080,7 @@ class Database(http.Controller):
country_code = post.get('country_code') or False
dispatch_rpc('db', 'create_database', [master_pwd, name, bool(post.get('demo')), lang, password, post['login'], country_code, post['phone']])
request.session.authenticate(name, post['login'], password)
return http.local_redirect('/web/')
return request.redirect('/web')
except Exception as e:
error = "Database creation error: %s" % (str(e) or repr(e))
return self._render_template(error=error)
@@ -1103,7 +1095,7 @@ class Database(http.Controller):
raise Exception(_('Invalid database name. Only alphanumerical characters, underscore, hyphen and dot are allowed.'))
dispatch_rpc('db', 'duplicate_database', [master_pwd, name, new_name])
request._cr = None # duplicating a database leads to an unusable cursor
return http.local_redirect('/web/database/manager')
return request.redirect('/web/database/manager')
except Exception as e:
error = "Database duplication error: %s" % (str(e) or repr(e))
return self._render_template(error=error)
@@ -1116,7 +1108,7 @@ class Database(http.Controller):
try:
dispatch_rpc('db','drop', [master_pwd, name])
request._cr = None # dropping a database leads to an unusable cursor
return http.local_redirect('/web/database/manager')
return request.redirect('/web/database/manager')
except Exception as e:
error = "Database deletion error: %s" % (str(e) or repr(e))
return self._render_template(error=error)
@@ -1153,7 +1145,7 @@ class Database(http.Controller):
with tempfile.NamedTemporaryFile(delete=False) as data_file:
backup_file.save(data_file)
db.restore_db(name, data_file.name, str2bool(copy))
return http.local_redirect('/web/database/manager')
return request.redirect('/web/database/manager')
except Exception as e:
error = "Database restore error: %s" % (str(e) or repr(e))
return self._render_template(error=error)
@@ -1165,7 +1157,7 @@ class Database(http.Controller):
def change_password(self, master_pwd, master_pwd_new):
try:
dispatch_rpc('db', 'change_admin_password', [master_pwd, master_pwd_new])
return http.local_redirect('/web/database/manager')
return request.redirect('/web/database/manager')
except Exception as e:
error = "Master password update error: %s" % (str(e) or repr(e))
return self._render_template(error=error)
@@ -1276,7 +1268,7 @@ class Session(http.Controller):
@http.route('/web/session/logout', type='http', auth="none")
def logout(self, redirect='/web'):
request.session.logout(keep_db=True)
return werkzeug.utils.redirect(redirect, 303)
return request.redirect(redirect, 303)
class DataSet(http.Controller):
+5 -8
View File
@@ -91,9 +91,6 @@ class Website(Home):
session, AFTER landing on that website domain (if set) as this will be a
different session.
"""
parse = werkzeug.urls.url_parse
safe_path = parse(path).path
if not (request.env.user.has_group('website.group_multi_website')
and request.env.user.has_group('website.group_website_publisher')):
# The user might not be logged in on the forced website, so he won't
@@ -103,19 +100,19 @@ class Website(Home):
# Website 1 : 127.0.0.1 (admin)
# Website 2 : 127.0.0.2 (not logged in)
# Click on "Website 2" from Website 1
return request.redirect(safe_path)
return request.redirect(path)
website = request.env['website'].browse(website_id)
if not isredir and website.domain:
domain_from = request.httprequest.environ.get('HTTP_HOST', '')
domain_to = parse(website._get_http_domain()).netloc
domain_to = werkzeug.urls.url_parse(website._get_http_domain()).netloc
if domain_from != domain_to:
# redirect to correct domain for a correct routing map
url_to = werkzeug.urls.url_join(website._get_http_domain(), '/website/force/%s?isredir=1&path=%s' % (website.id, safe_path))
url_to = werkzeug.urls.url_join(website._get_http_domain(), '/website/force/%s?isredir=1&path=%s' % (website.id, path))
return request.redirect(url_to)
website._force()
return request.redirect(safe_path)
return request.redirect(path)
# ------------------------------------------------------
# Login - overwrite of the web login so that regular users are redirected to the backend
@@ -265,7 +262,7 @@ class Website(Home):
url = getattr(request.website, 'social_%s' % social, False)
if not url:
raise werkzeug.exceptions.NotFound()
return request.redirect(url)
return request.redirect(url, local=False)
@http.route('/website/get_suggested_links', type='json', auth="user", website=True)
def get_suggested_link(self, needle, limit=10):
+5 -5
View File
@@ -145,12 +145,12 @@ class Http(models.AbstractModel):
return False
template = False
if hasattr(response, 'qcontext'): # classic response
if hasattr(response, '_cached_page'):
website_page, template = response._cached_page, response._cached_template
elif hasattr(response, 'qcontext'): # classic response
main_object = response.qcontext.get('main_object')
website_page = getattr(main_object, '_name', False) == 'website.page' and main_object
template = response.qcontext.get('response_template')
elif hasattr(response, '_cached_page'):
website_page, template = response._cached_page, response._cached_template
view = template and request.env['website'].get_template(template)
if view and view.track:
@@ -276,7 +276,7 @@ class Http(models.AbstractModel):
path = '/' + request.lang.url_code + path
if request.httprequest.query_string:
path += '?' + request.httprequest.query_string.decode('utf-8')
return werkzeug.utils.redirect(path, code=301)
return request.redirect(path, code=301)
if page:
# prefetch all menus (it will prefetch website.page too)
@@ -297,7 +297,7 @@ class Http(models.AbstractModel):
try:
r = page._get_cache_response(cache_key)
if r['time'] + page.cache_time > time.time():
response = werkzeug.Response(r['content'], mimetype=r['contenttype'])
response = odoo.http.Response(r['content'], mimetype=r['contenttype'])
response._cached_template = r['template']
response._cached_page = page
return response
+1 -1
View File
@@ -54,7 +54,7 @@ class Crawler(HttpCaseWithUserDemo):
_logger.info("%s %s", msg, url)
r = self.url_open(url, allow_redirects=False)
if r.status_code in (301, 302):
if r.status_code in (301, 302, 303):
# check local redirect to avoid fetch externals pages
new_url = r.headers.get('Location')
current_url = r.url
+1 -1
View File
@@ -97,7 +97,7 @@ def MockRequest(
referrer='',
),
lang=env['res.lang']._lang_get(lang_code),
redirect=werkzeug.utils.redirect,
redirect=env['ir.http']._redirect,
session=DotDict(
geoip={'country_code': country_code},
debug=False,
+3 -3
View File
@@ -161,7 +161,7 @@ class WebsiteBlog(http.Controller):
blogs = Blog.search(request.website.website_domain(), order="create_date asc, id asc")
if not blog and len(blogs) == 1:
return werkzeug.utils.redirect('/blog/%s' % slug(blogs[0]), code=302)
return request.redirect('/blog/%s' % slug(blogs[0]), code=302)
date_begin, date_end, state = opt.get('date_begin'), opt.get('date_end'), opt.get('state')
@@ -289,7 +289,7 @@ class WebsiteBlog(http.Controller):
'blog_id': blog_id,
'is_published': False,
})
return werkzeug.utils.redirect("/blog/%s/%s?enable_editor=1" % (slug(new_blog_post.blog_id), slug(new_blog_post)))
return request.redirect("/blog/%s/%s?enable_editor=1" % (slug(new_blog_post.blog_id), slug(new_blog_post)))
@http.route('/blog/post_duplicate', type='http', auth="user", website=True, methods=['POST'])
def blog_post_copy(self, blog_post_id, **post):
@@ -300,4 +300,4 @@ class WebsiteBlog(http.Controller):
:return redirect to the new blog created
"""
new_blog_post = request.env['blog.post'].with_context(mail_create_nosubscribe=True).browse(int(blog_post_id)).copy()
return werkzeug.utils.redirect("/blog/%s/%s?enable_editor=1" % (slug(new_blog_post.blog_id), slug(new_blog_post)))
return request.redirect("/blog/%s/%s?enable_editor=1" % (slug(new_blog_post.blog_id), slug(new_blog_post)))
@@ -3,7 +3,6 @@
import logging
from werkzeug.exceptions import Forbidden, NotFound
from werkzeug.utils import redirect
from odoo import exceptions, http
from odoo.http import request
@@ -103,7 +102,7 @@ class WebsiteEventMeetController(EventCommunityController):
})
_logger.info("New meeting room (%s) created by %s (uid %s)" % (name, request.httprequest.remote_addr, request.env.uid))
return redirect(f"/event/{slug(event)}/meeting_room/{slug(meeting_room)}")
return request.redirect(f"/event/{slug(event)}/meeting_room/{slug(meeting_room)}")
@http.route(["/event/active_langs"], type="json", auth="public")
def active_langs(self):
+23 -23
View File
@@ -46,7 +46,7 @@ class WebsiteForum(WebsiteProfile):
domain = request.website.website_domain()
forums = request.env['forum.forum'].search(domain)
if len(forums) == 1:
return werkzeug.utils.redirect('/forum/%s' % slug(forums[0]), code=302)
return request.redirect('/forum/%s' % slug(forums[0]), code=302)
return request.render("website_forum.forum_all", {
'forums': forums
@@ -245,7 +245,7 @@ class WebsiteForum(WebsiteProfile):
if question.parent_id:
redirect_url = "/forum/%s/%s" % (slug(forum), slug(question.parent_id))
return werkzeug.utils.redirect(redirect_url, 301)
return request.redirect(redirect_url, 301)
filters = 'question'
values = self._prepare_user_values(forum=forum, searches=post)
values.update({
@@ -295,27 +295,27 @@ class WebsiteForum(WebsiteProfile):
if record.create_uid.id == request.uid:
answer = record
break
return werkzeug.utils.redirect("/forum/%s/post/%s/edit" % (slug(forum), slug(answer)))
return request.redirect("/forum/%s/post/%s/edit" % (slug(forum), slug(answer)))
@http.route('/forum/<model("forum.forum"):forum>/question/<model("forum.post"):question>/close', type='http', auth="user", methods=['POST'], website=True)
def question_close(self, forum, question, **post):
question.close(reason_id=int(post.get('reason_id', False)))
return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), slug(question)))
return request.redirect("/forum/%s/question/%s" % (slug(forum), slug(question)))
@http.route('/forum/<model("forum.forum"):forum>/question/<model("forum.post"):question>/reopen', type='http', auth="user", methods=['POST'], website=True)
def question_reopen(self, forum, question, **kwarg):
question.reopen()
return werkzeug.utils.redirect("/forum/%s/%s" % (slug(forum), slug(question)))
return request.redirect("/forum/%s/%s" % (slug(forum), slug(question)))
@http.route('/forum/<model("forum.forum"):forum>/question/<model("forum.post"):question>/delete', type='http', auth="user", methods=['POST'], website=True)
def question_delete(self, forum, question, **kwarg):
question.active = False
return werkzeug.utils.redirect("/forum/%s/%s" % (slug(forum), slug(question)))
return request.redirect("/forum/%s/%s" % (slug(forum), slug(question)))
@http.route('/forum/<model("forum.forum"):forum>/question/<model("forum.post"):question>/undelete', type='http', auth="user", methods=['POST'], website=True)
def question_undelete(self, forum, question, **kwarg):
question.active = True
return werkzeug.utils.redirect("/forum/%s/%s" % (slug(forum), slug(question)))
return request.redirect("/forum/%s/%s" % (slug(forum), slug(question)))
# Post
# --------------------------------------------------
@@ -323,7 +323,7 @@ class WebsiteForum(WebsiteProfile):
def forum_post(self, forum, **post):
user = request.env.user
if not user.email or not tools.single_email_re.match(user.email):
return werkzeug.utils.redirect("/forum/%s/user/%s/edit?email_required=1" % (slug(forum), request.session.uid))
return request.redirect("/forum/%s/user/%s/edit?email_required=1" % (slug(forum), request.session.uid))
values = self._prepare_user_values(forum=forum, searches={}, header={'ask_hide': True}, new_question=True)
return request.render("website_forum.new_question", values)
@@ -340,7 +340,7 @@ class WebsiteForum(WebsiteProfile):
post_tag_ids = forum._tag_to_write_vals(post.get('post_tags', ''))
if request.env.user.forum_waiting_posts_count:
return werkzeug.utils.redirect("/forum/%s/ask" % slug(forum))
return request.redirect("/forum/%s/ask" % slug(forum))
new_question = request.env['forum.post'].create({
'forum_id': forum.id,
@@ -349,7 +349,7 @@ class WebsiteForum(WebsiteProfile):
'parent_id': post_parent and post_parent.id or False,
'tag_ids': post_tag_ids
})
return werkzeug.utils.redirect("/forum/%s/%s" % (slug(forum), post_parent and slug(post_parent) or new_question.id))
return request.redirect("/forum/%s/%s" % (slug(forum), post_parent and slug(post_parent) or new_question.id))
@http.route('/forum/<model("forum.forum"):forum>/post/<model("forum.post"):post>/comment', type='http', auth="user", methods=['POST'], website=True)
def post_comment(self, forum, post, **kwargs):
@@ -361,7 +361,7 @@ class WebsiteForum(WebsiteProfile):
body=body,
message_type='comment',
subtype_xmlid='mail.mt_comment')
return werkzeug.utils.redirect("/forum/%s/%s" % (slug(forum), slug(question)))
return request.redirect("/forum/%s/%s" % (slug(forum), slug(question)))
@http.route('/forum/<model("forum.forum"):forum>/post/<model("forum.post"):post>/toggle_correct', type='json', auth="public", website=True)
def post_toggle_correct(self, forum, post, **kwargs):
@@ -380,8 +380,8 @@ class WebsiteForum(WebsiteProfile):
question = post.parent_id
post.unlink()
if question:
werkzeug.utils.redirect("/forum/%s/%s" % (slug(forum), slug(question)))
return werkzeug.utils.redirect("/forum/%s" % slug(forum))
request.redirect("/forum/%s/%s" % (slug(forum), slug(question)))
return request.redirect("/forum/%s" % slug(forum))
@http.route('/forum/<model("forum.forum"):forum>/post/<model("forum.post"):post>/edit', type='http', auth="user", website=True)
def post_edit(self, forum, post, **kwargs):
@@ -415,7 +415,7 @@ class WebsiteForum(WebsiteProfile):
vals['tag_ids'] = forum._tag_to_write_vals(kwargs.get('post_tags', ''))
post.write(vals)
question = post.parent_id if post.parent_id else post
return werkzeug.utils.redirect("/forum/%s/%s" % (slug(forum), slug(question)))
return request.redirect("/forum/%s/%s" % (slug(forum), slug(question)))
# JSON utilities
# --------------------------------------------------
@@ -513,7 +513,7 @@ class WebsiteForum(WebsiteProfile):
elif post.state == 'offensive':
url = "/forum/%s/offensive_posts" % (slug(forum))
post.validate()
return werkzeug.utils.redirect(url)
return request.redirect(url)
@http.route('/forum/<model("forum.forum"):forum>/post/<model("forum.post"):post>/refuse', type='http', auth="user", website=True)
def post_refuse(self, forum, post, **kwargs):
@@ -547,7 +547,7 @@ class WebsiteForum(WebsiteProfile):
url = "/forum/%s/%s/#answer-%s" % (slug(forum), post.parent_id.id, post.id)
else:
url = "/forum/%s/%s" % (slug(forum), slug(post))
return werkzeug.utils.redirect(url)
return request.redirect(url)
# User
# --------------------------------------------------
@@ -556,15 +556,15 @@ class WebsiteForum(WebsiteProfile):
if partner_id:
partner = request.env['res.partner'].sudo().search([('id', '=', partner_id)])
if partner and partner.user_ids:
return werkzeug.utils.redirect("/forum/%s/user/%d" % (slug(forum), partner.user_ids[0].id))
return werkzeug.utils.redirect("/forum/%s" % slug(forum))
return request.redirect("/forum/%s/user/%d" % (slug(forum), partner.user_ids[0].id))
return request.redirect("/forum/%s" % slug(forum))
# Profile
# -----------------------------------
@http.route(['/forum/<model("forum.forum"):forum>/user/<int:user_id>'], type='http', auth="public", website=True)
def view_user_forum_profile(self, forum, user_id, forum_origin, **post):
return werkzeug.utils.redirect('/profile/user/' + str(user_id) + '?forum_id=' + str(forum.id) + '&forum_origin=' + str(forum_origin))
return request.redirect('/profile/user/' + str(user_id) + '?forum_id=' + str(forum.id) + '&forum_origin=' + str(forum_origin))
def _prepare_user_profile_values(self, user, **post):
values = super(WebsiteForum, self)._prepare_user_profile_values(user, **post)
@@ -684,17 +684,17 @@ class WebsiteForum(WebsiteProfile):
def convert_comment_to_answer(self, forum, post, comment, **kwarg):
post = request.env['forum.post'].convert_comment_to_answer(comment.id)
if not post:
return werkzeug.utils.redirect("/forum/%s" % slug(forum))
return request.redirect("/forum/%s" % slug(forum))
question = post.parent_id if post.parent_id else post
return werkzeug.utils.redirect("/forum/%s/%s" % (slug(forum), slug(question)))
return request.redirect("/forum/%s/%s" % (slug(forum), slug(question)))
@http.route('/forum/<model("forum.forum"):forum>/post/<model("forum.post"):post>/convert_to_comment', type='http', auth="user", methods=['POST'], website=True)
def convert_answer_to_comment(self, forum, post, **kwarg):
question = post.parent_id
new_msg = post.convert_answer_to_comment()
if not new_msg:
return werkzeug.utils.redirect("/forum/%s" % slug(forum))
return werkzeug.utils.redirect("/forum/%s/%s" % (slug(forum), slug(question)))
return request.redirect("/forum/%s" % slug(forum))
return request.redirect("/forum/%s/%s" % (slug(forum), slug(question)))
@http.route('/forum/<model("forum.forum"):forum>/post/<model("forum.post"):post>/comment/<model("mail.message"):comment>/delete', type='json', auth="user", website=True)
def delete_comment(self, forum, post, comment, **kwarg):
+1 -3
View File
@@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import werkzeug
from odoo import http
from odoo.http import request
@@ -38,4 +36,4 @@ class WebsiteUrl(http.Controller):
if code:
return request.render("website_links.graphs", code.link_id.read()[0])
else:
return werkzeug.utils.redirect('/', 301)
return request.redirect('/', code=301)
+2 -2
View File
@@ -166,9 +166,9 @@ class WebsiteProfile(http.Controller):
whitelisted_values = {key: values[key] for key in user.SELF_WRITEABLE_FIELDS if key in values}
user.write(whitelisted_values)
if kwargs.get('url_param'):
return werkzeug.utils.redirect("/profile/user/%d?%s" % (user.id, kwargs['url_param']))
return request.redirect("/profile/user/%d?%s" % (user.id, kwargs['url_param']))
else:
return werkzeug.utils.redirect("/profile/user/%d" % user.id)
return request.redirect("/profile/user/%d" % user.id)
# Ranks and Badges
# ---------------------------------------------------
@@ -5,7 +5,6 @@ import base64
import io
import os
import mimetypes
from werkzeug.utils import redirect
from odoo import http
from odoo.http import request
@@ -66,7 +65,7 @@ class WebsiteSaleDigital(CustomerPortal):
if attachment:
attachment = attachment[0]
else:
return redirect(self.orders_page)
return request.redirect(self.orders_page)
# Check if the user has bought the associated product
res_model = attachment['res_model']
@@ -75,21 +74,21 @@ class WebsiteSaleDigital(CustomerPortal):
if res_model == 'product.product':
if res_id not in purchased_products:
return redirect(self.orders_page)
return request.redirect(self.orders_page)
# Also check for attachments in the product templates
elif res_model == 'product.template':
template_ids = request.env['product.product'].sudo().browse(purchased_products).mapped('product_tmpl_id').ids
if res_id not in template_ids:
return redirect(self.orders_page)
return request.redirect(self.orders_page)
else:
return redirect(self.orders_page)
return request.redirect(self.orders_page)
# The client has bought the product, otherwise it would have been blocked by now
if attachment["type"] == "url":
if attachment["url"]:
return redirect(attachment["url"])
return request.redirect(attachment["url"])
else:
return request.not_found()
elif attachment["datas"]:
+4 -4
View File
@@ -600,7 +600,7 @@ class WebsiteSlides(WebsiteProfile):
@http.route('/slides/channel/add', type='http', auth='user', methods=['POST'], website=True)
def slide_channel_create(self, *args, **kw):
channel = request.env['slide.channel'].create(self._slide_channel_prepare_values(**kw))
return werkzeug.utils.redirect("/slides/%s" % (slug(channel)))
return request.redirect("/slides/%s" % (slug(channel)))
def _slide_channel_prepare_values(self, **kw):
# `tag_ids` is a string representing a list of int with coma. i.e.: '2,5,7'
@@ -624,7 +624,7 @@ class WebsiteSlides(WebsiteProfile):
if not request.website.is_public_user():
channel = request.env['slide.channel'].browse(int(channel_id))
channel.action_add_member()
return werkzeug.utils.redirect("/slides/%s" % (slug(channel)))
return request.redirect("/slides/%s" % (slug(channel)))
@http.route(['/slides/channel/join'], type='json', auth='public', website=True)
def slide_channel_join(self, channel_id):
@@ -795,7 +795,7 @@ class WebsiteSlides(WebsiteProfile):
next_slide = None
if next_slide_id:
next_slide = self._fetch_slide(next_slide_id).get('slide', None)
return werkzeug.utils.redirect("/slides/slide/%s" % (slug(next_slide) if next_slide else slug(slide)))
return request.redirect("/slides/slide/%s" % (slug(next_slide) if next_slide else slug(slide)))
@http.route('/slides/slide/set_completed', website=True, type="json", auth="public")
def slide_set_completed(self, slide_id):
@@ -1041,7 +1041,7 @@ class WebsiteSlides(WebsiteProfile):
request.env['slide.slide'].create(self._get_new_slide_category_values(channel, name))
return werkzeug.utils.redirect("/slides/%s" % (slug(channel)))
return request.redirect("/slides/%s" % (slug(channel)))
# --------------------------------------------------
# SLIDE.UPLOAD
@@ -27,7 +27,7 @@ class WebsiteSlidesSurvey(WebsiteSlides):
certification_url = slide._generate_certification_url().get(slide.id)
if not certification_url:
raise werkzeug.exceptions.NotFound()
return werkzeug.utils.redirect(certification_url)
return request.redirect(certification_url)
@http.route(['/slides_survey/certification/search_read'], type='json', auth='user', methods=['POST'], website=True)
def slides_certification_search_read(self, fields):
+7 -4
View File
@@ -14,13 +14,12 @@ import traceback
import werkzeug
import werkzeug.exceptions
import werkzeug.routing
import werkzeug.urls
import werkzeug.utils
import odoo
from odoo import api, http, models, tools, SUPERUSER_ID
from odoo.exceptions import AccessDenied, AccessError, MissingError
from odoo.http import request, content_disposition
from odoo.http import request, content_disposition, Response
from odoo.tools import consteq, pycompat
from odoo.tools.mimetypes import guess_mimetype
from odoo.modules.module import get_resource_path, get_module_path
@@ -159,7 +158,7 @@ class IrHttp(models.AbstractModel):
if (not datas and name != request.httprequest.path and
name.startswith(('http://', 'https://', '/'))):
return werkzeug.utils.redirect(name, 301)
return request.redirect(name, 301, local=False)
response = werkzeug.wrappers.Response()
response.last_modified = wdate
@@ -243,6 +242,10 @@ class IrHttp(models.AbstractModel):
return result
@classmethod
def _redirect(cls, location, code=303):
return werkzeug.utils.redirect(location, code=code, Response=Response)
@classmethod
def _postprocess_args(cls, arguments, rule):
""" post process arg to set uid on browse records """
@@ -485,6 +488,6 @@ class IrHttp(models.AbstractModel):
if status == 304:
return werkzeug.wrappers.Response(status=status, headers=headers)
elif status == 301:
return werkzeug.utils.redirect(content, code=301)
return request.redirect(content, code=301, local=False)
elif status != 200:
return request.not_found()
+13 -16
View File
@@ -159,21 +159,6 @@ def dispatch_rpc(service_name, method, params):
odoo.tools.debugger.post_mortem(odoo.tools.config, sys.exc_info())
raise
def local_redirect(path, query=None, keep_hash=False, code=303):
# FIXME: drop the `keep_hash` param, now useless
url = path
if not query:
query = {}
if query:
url += '?' + urls.url_encode(query)
return werkzeug.utils.redirect(url, code)
def redirect_with_hash(url, code=303):
# Section 7.1.2 of RFC 7231 requires preservation of URL fragment through redirects,
# so we don't need any special handling anymore. This function could be dropped in the future.
# seealso : http://www.rfc-editor.org/info/rfc7231
# https://tools.ietf.org/html/rfc7231#section-7.1.2
return werkzeug.utils.redirect(url, code)
class WebRequest(object):
""" Parent class for all Odoo Web request types, mostly deals with
@@ -315,6 +300,18 @@ class WebRequest(object):
# callers to check & look at)
raise exception.with_traceback(None) from new_cause
def redirect(self, location, code=303, local=True):
if local:
location = urls.url_parse(location).replace(scheme='', netloc='').to_url()
if request and request.db:
return request.registry['ir.http']._redirect(location, code)
return werkzeug.utils.redirect(location, code, Response=Response)
def redirect_query(self, location, query=None, code=303, local=True):
if query:
location += '?' + urls.url_encode(query)
return self.redirect(location, code=code, local=local)
def _is_cors_preflight(self, endpoint):
return False
@@ -759,7 +756,7 @@ class HttpRequest(WebRequest):
query = werkzeug.urls.url_encode({
'redirect': redirect,
})
return werkzeug.utils.redirect('/web/login?%s' % query)
return request.redirect('/web/login?%s' % query)
except werkzeug.exceptions.HTTPException as e:
return e