diff --git a/addons/test_website/controllers/main.py b/addons/test_website/controllers/main.py index ec94cbc3aee..1fc9f8e54e6 100644 --- a/addons/test_website/controllers/main.py +++ b/addons/test_website/controllers/main.py @@ -44,6 +44,14 @@ class WebsiteTest(Home): def test_company_context(self): return request.make_response(json.dumps(request.context.get('allowed_company_ids'))) + # Test Session + + @http.route('/test_get_dbname', type='json', auth='public', website=True) + def test_get_dbname(self, **kwargs): + return request.env.cr.dbname + + # Test Error + @http.route('/test_error_view', type='http', auth='public', website=True) def test_error_view(self, **kwargs): return request.render('test_website.test_error_view') diff --git a/addons/test_website/static/tests/tours/json_auth.js b/addons/test_website/static/tests/tours/json_auth.js new file mode 100644 index 00000000000..6c4df8e26de --- /dev/null +++ b/addons/test_website/static/tests/tours/json_auth.js @@ -0,0 +1,26 @@ +odoo.define('test_website.json_auth', function (require) { +'use strict'; + +var tour = require('web_tour.tour'); +var session = require('web.session') + +tour.register('test_json_auth', { + test: true, +}, [{ + trigger: 'body', + run: async function () { + await session.rpc('/test_get_dbname').then( function (result){ + return session.rpc("/web/session/authenticate", { + db: result, + login: 'admin', + password: 'admin' + }); + }); + window.location.href = window.location.origin; + }, +}, { + trigger: 'span:contains(Mitchell Admin)', + run: function () {}, +} +]); +}); diff --git a/addons/test_website/tests/__init__.py b/addons/test_website/tests/__init__.py index 8b8ec3e4e44..4fab1ec9b68 100644 --- a/addons/test_website/tests/__init__.py +++ b/addons/test_website/tests/__init__.py @@ -6,3 +6,4 @@ from . import test_reset_views from . import test_error from . import test_views_during_module_operation from . import test_multi_company +from . import test_session diff --git a/addons/test_website/tests/test_session.py b/addons/test_website/tests/test_session.py new file mode 100644 index 00000000000..22975ebdda4 --- /dev/null +++ b/addons/test_website/tests/test_session.py @@ -0,0 +1,9 @@ +import odoo.tests +from odoo.tools import mute_logger + + +@odoo.tests.common.tagged('post_install', '-at_install') +class TestWebsiteSession(odoo.tests.HttpCase): + + def test_01_run_test(self): + self.start_tour('/', 'test_json_auth') diff --git a/addons/test_website/views/templates.xml b/addons/test_website/views/templates.xml index ee6b500c5ca..23e71565a55 100644 --- a/addons/test_website/views/templates.xml +++ b/addons/test_website/views/templates.xml @@ -10,6 +10,7 @@ + diff --git a/addons/website/models/website_visitor.py b/addons/website/models/website_visitor.py index 21105582346..33f6b34526a 100644 --- a/addons/website/models/website_visitor.py +++ b/addons/website/models/website_visitor.py @@ -159,7 +159,7 @@ class WebsiteVisitor(models.Model): 'context': ctx, } - def _get_visitor_from_request(self): + def _get_visitor_from_request(self, force_create=False): """ Return the visitor as sudo from the request if there is a visitor_uuid cookie. It is possible that the partner has changed or has disconnected. In that case the cookie is still referencing the old visitor and need to be replaced @@ -167,7 +167,8 @@ class WebsiteVisitor(models.Model): # This function can be called in json with mobile app. # In case of mobile app, no uid is set on the jsonRequest env. - if not request or not request.env.uid: + # In case of multi db, _env is None on request, and request.env unbound. + if not request: return None Visitor = self.env['website.visitor'].sudo() visitor = Visitor @@ -175,27 +176,23 @@ class WebsiteVisitor(models.Model): if access_token: visitor = Visitor.with_context(active_test=False).search([('access_token', '=', access_token)]) - if not request.env.user._is_public(): - partner_id = request.env.user.partner_id - if not visitor or visitor.partner_id != partner_id: + if not self.env.user._is_public(): + partner_id = self.env.user.partner_id + if not visitor or visitor.partner_id and visitor.partner_id != partner_id: # Partner and no cookie or wrong cookie visitor = Visitor.with_context(active_test=False).search([('partner_id', '=', partner_id.id)]) elif visitor and visitor.partner_id: # Cookie associated to a Partner visitor = Visitor - return visitor - def _get_visitor_from_request_or_create(self): - """ Return a tuple (visitor, response), see _get_visitor_from_request - If there is no visitor creates it and ensure the consistancy of the cookie. """ - visitor_sudo = self._get_visitor_from_request() - if not visitor_sudo: - visitor_sudo = self._create_visitor() - return visitor_sudo + if force_create and not visitor: + visitor = self._create_visitor() + + return visitor def _handle_webpage_dispatch(self, response, website_page): # get visitor. Done here to avoid having to do it multiple times in case of override. - visitor_sudo = self._get_visitor_from_request_or_create() + visitor_sudo = self._get_visitor_from_request(force_create=True) if request.httprequest.cookies.get('visitor_uuid', '') != visitor_sudo.access_token: expiration_date = datetime.now() + timedelta(days=365) response.set_cookie('visitor_uuid', visitor_sudo.access_token, expires=expiration_date) diff --git a/addons/website_livechat/models/website_visitor.py b/addons/website_livechat/models/website_visitor.py index 84d52f54d47..059a1ca61da 100644 --- a/addons/website_livechat/models/website_visitor.py +++ b/addons/website_livechat/models/website_visitor.py @@ -84,7 +84,7 @@ class WebsiteVisitor(models.Model): This will only happen if the mail channel linked to the chat request already has a message. So that empty livechat channel won't pop up at client side. """ super(WebsiteVisitor, self)._handle_website_page_visit(response, website_page, visitor_sudo) - visitor_id = self.env['website.visitor']._get_visitor_from_request().id if not visitor_sudo else visitor_sudo.id + visitor_id = visitor_sudo.id or self.env['website.visitor']._get_visitor_from_request().id if visitor_id: # get active chat_request linked to visitor chat_request_channel = self.env['mail.channel'].sudo().search([('livechat_visitor_id', '=', visitor_id), ('livechat_active', '=', True)], order='create_date desc', limit=1) @@ -101,5 +101,5 @@ class WebsiteVisitor(models.Model): "uuid": chat_request_channel.uuid, "type": "chat_request" }) - expiration_date = datetime.now() + timedelta(days=100*365) # never expire + expiration_date = datetime.now() + timedelta(days=100 * 365) # never expire response.set_cookie('im_livechat_session', livechat_session, expires=expiration_date.timestamp()) diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index c231cdbb4ed..a11124e8207 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -1255,10 +1255,11 @@ class WebsiteSale(http.Controller): @http.route('/shop/products/recently_viewed_update', type='json', auth='public', website=True) def products_recently_viewed_update(self, product_id, **kwargs): res = {} - visitor_sudo = request.env['website.visitor']._get_visitor_from_request_or_create() - if request.httprequest.cookies.get('visitor_uuid', '') != visitor_sudo.access_token: - res['visitor_uuid'] = visitor_sudo.access_token - visitor_sudo._add_viewed_product(product_id) + visitor_sudo = request.env['website.visitor']._get_visitor_from_request(force_create=True) + if visitor_sudo: + if request.httprequest.cookies.get('visitor_uuid', '') != visitor_sudo.access_token: + res['visitor_uuid'] = visitor_sudo.access_token + visitor_sudo._add_viewed_product(product_id) return res @http.route('/shop/products/recently_viewed_delete', type='json', auth='public', website=True)