[FIX] website: allow authenticate in json multidb

Before this commit launch a server with --db-filter that match at least 2 dbs name
Try to authenticate

You will have an error request is unbound when you try to access request.env

Now we retrieve the user from self instead of the request.

New test to ensure rpc authentication is tested.

Related to commit 245ef4b1

closes odoo/odoo#38969

X-original-commit: 4b3400c430bec7539aada0619fd203978daca2d8
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
This commit is contained in:
Jeremy Kersten
2019-10-17 15:35:11 +00:00
committed by fw-bot
parent 734f0af61f
commit 3a7033463e
8 changed files with 63 additions and 20 deletions
+8
View File
@@ -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')
@@ -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 () {},
}
]);
});
+1
View File
@@ -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
@@ -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')
+1
View File
@@ -10,6 +10,7 @@
<xpath expr="." position="inside">
<script type="text/javascript" src="/test_website/static/tests/tours/reset_views.js"></script>
<script type="text/javascript" src="/test_website/static/tests/tours/error_views.js"></script>
<script type="text/javascript" src="/test_website/static/tests/tours/json_auth.js"></script>
</xpath>
</template>
</odoo>
+11 -14
View File
@@ -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)
@@ -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())
+5 -4
View File
@@ -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)