[IMP] point_of_sale, pos_*: Enable HTTPS in POS

HTTPS had been disabled on SaaS to allow the use of the IoT Box that
had no valid SSL certificate. As of V13.0, IoT Boxes connected to
Enterprise DBs have a valid certificate. POS can then use HTTPS.

Nginx is configured to redirect all requests to `/pos/web` to HTTP,
so we change the POS URL to `/pos/ui`, except when using a Six
payment terminal as it only works in HTTP.

closes odoo/odoo#56933

Taskid: 2191878
X-original-commit: 8aee4992778fee5e2f146c4cff8b35e83c7f56b3
Signed-off-by: pimodoo <pimodoo@users.noreply.github.com>
Signed-off-by: Antoine Prieëls <aprieels@users.noreply.github.com>
This commit is contained in:
Antoine Prieels
2020-09-02 10:53:34 +00:00
parent a0c7b35237
commit 3f138b9d3c
26 changed files with 68 additions and 45 deletions
+5 -2
View File
@@ -13,12 +13,15 @@ _logger = logging.getLogger(__name__)
class PosController(http.Controller):
@http.route('/pos/web', type='http', auth='user')
@http.route(['/pos/web', '/pos/ui'], type='http', auth='user')
def pos_web(self, config_id=False, **k):
"""Open a pos session for the given config.
The right pos session will be selected to open, if non is open yet a new session will be created.
/pos/ui and /pos/web both can be used to acces the POS. On the SaaS,
/pos/ui uses HTTPS while /pos/web uses HTTP.
:param debug: The debug mode to load the session in.
:type debug: str.
:param config_id: id of the config that has to be loaded.
@@ -56,7 +59,7 @@ class PosController(http.Controller):
}
return request.render('point_of_sale.index', qcontext=context)
@http.route('/pos/web/tests', type='http', auth="user")
@http.route('/pos/ui/tests', type='http', auth="user")
def test_suite(self, mod=None, **kwargs):
domain = [
('state', '=', 'opened'),
+7 -1
View File
@@ -565,6 +565,12 @@ class PosConfig(models.Model):
'params': {'wait': True}
}
def _force_http(self):
return False
def _get_pos_base_url(self):
return '/pos/web' if self._force_http() else '/pos/ui'
# Methods to open the POS
def open_ui(self):
"""Open the pos interface with config_id as an extra argument.
@@ -579,7 +585,7 @@ class PosConfig(models.Model):
self._validate_fields(set(self._fields) - {"cash_control"})
return {
'type': 'ir.actions.act_url',
'url': '/pos/web?config_id=%d' % self.id,
'url': self._get_pos_base_url() + '?config_id=%d' % self.id,
'target': 'self',
}
+1 -1
View File
@@ -1010,7 +1010,7 @@ class PosSession(models.Model):
return {
'type': 'ir.actions.act_url',
'target': 'self',
'url': '/pos/web?config_id=%d' % self.config_id.id,
'url': self.config_id._get_pos_base_url() + '?config_id=%d' % self.config_id.id,
}
def open_cashbox_pos(self):
@@ -13,7 +13,7 @@ odoo.define('point_of_sale.DebugManager.Backend', function(require) {
name: _t('JS Tests'),
target: 'new',
type: 'ir.actions.act_url',
url: '/pos/web/tests?mod=*',
url: '/pos/ui/tests?mod=*',
});
},
});
@@ -99,5 +99,5 @@ odoo.define('point_of_sale.tour.Chrome', function (require) {
PaymentScreen.do.clickValidate();
ReceiptScreen.check.isShown();
Tour.register('ChromeTour', { test: true, url: '/pos/web' }, getSteps());
Tour.register('ChromeTour', { test: true, url: '/pos/ui' }, getSteps());
});
@@ -134,5 +134,5 @@ odoo.define('point_of_sale.tour.OrderManagementScreen', function (require) {
OrderManagementScreen.do.closeReceipt();
OrderManagementScreen.check.isNotHidden();
Tour.register('OrderManagementScreenTour', { test: true, url: '/pos/web' }, getSteps());
Tour.register('OrderManagementScreenTour', { test: true, url: '/pos/ui' }, getSteps());
});
@@ -66,5 +66,5 @@ odoo.define('point_of_sale.tour.PaymentScreen', function (require) {
PaymentScreen.check.changeIs('0.0');
PaymentScreen.check.validateButtonIsHighlighted(true);
Tour.register('PaymentScreenTour', { test: true, url: '/pos/web' }, getSteps());
Tour.register('PaymentScreenTour', { test: true, url: '/pos/ui' }, getSteps());
});
@@ -62,5 +62,5 @@ odoo.define('point_of_sale.tour.ProductConfigurator', function (require) {
ProductConfigurator.do.confirmAttributes();
ProductScreen.check.selectedOrderlineHas('Configurable Chair (Blue, Metal, Leather)', '1.0', '10.0');
Tour.register('ProductConfiguratorTour', { test: true, url: '/pos/web' }, getSteps());
Tour.register('ProductConfiguratorTour', { test: true, url: '/pos/ui' }, getSteps());
});
@@ -101,5 +101,5 @@ odoo.define('point_of_sale.tour.ProductScreen', function (require) {
ProductScreen.do.pressNumpad('Backspace');
ProductScreen.check.orderIsEmpty();
Tour.register('ProductScreenTour', { test: true, url: '/pos/web' }, getSteps());
Tour.register('ProductScreenTour', { test: true, url: '/pos/ui' }, getSteps());
});
@@ -57,5 +57,5 @@ odoo.define('point_of_sale.tour.ReceiptScreen', function (require) {
ReceiptScreen.check.totalAmountContains('$ 30.00 + $ 1.00 tip');
ReceiptScreen.do.clickNextOrder();
Tour.register('ReceiptScreenTour', { test: true, url: '/pos/web' }, getSteps());
Tour.register('ReceiptScreenTour', { test: true, url: '/pos/ui' }, getSteps());
});
@@ -50,5 +50,5 @@ odoo.define('point_of_sale.tour.TicketScreen', function (require) {
TicketScreen.do.search('Receipt Number', '-0003');
TicketScreen.check.nthRowContains(2, 'Receipt');
Tour.register('TicketScreenTour', { test: true, url: '/pos/web' }, getSteps());
Tour.register('TicketScreenTour', { test: true, url: '/pos/ui' }, getSteps());
});
@@ -213,7 +213,7 @@ odoo.define('point_of_sale.tour.pricelist', function (require) {
run: function() {}, //it's a check,
}]);
Tour.register('pos_pricelist', { test: true, url: '/pos/web' }, steps);
Tour.register('pos_pricelist', { test: true, url: '/pos/ui' }, steps);
});
odoo.define('point_of_sale.tour.acceptance', function (require) {
@@ -430,6 +430,6 @@ odoo.define('point_of_sale.tour.acceptance', function (require) {
run: function() {}, //it's a check,
}]);
Tour.register('pos_basic_order', { test: true, url: '/pos/web' }, steps);
Tour.register('pos_basic_order', { test: true, url: '/pos/ui' }, steps);
});
+10 -10
View File
@@ -480,7 +480,7 @@ class TestUi(TestPointOfSaleHttpCommon):
'tip_product_id': self.tip.id,
})
# open a session, the /pos/web controller will redirect to it
# open a session, the /pos/ui controller will redirect to it
self.main_pos_config.open_session_cb(check_coa=False)
# needed because tests are run before the module is marked as
@@ -489,11 +489,11 @@ class TestUi(TestPointOfSaleHttpCommon):
# this you end up with js, css but no qweb.
self.env['ir.module.module'].search([('name', '=', 'point_of_sale')], limit=1).state = 'installed'
self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'pos_pricelist', login="admin")
self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'pos_basic_order', login="admin")
self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'ProductScreenTour', login="admin")
self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'PaymentScreenTour', login="admin")
self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'ReceiptScreenTour', login="admin")
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'pos_pricelist', login="admin")
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'pos_basic_order', login="admin")
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'ProductScreenTour', login="admin")
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'PaymentScreenTour', login="admin")
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'ReceiptScreenTour', login="admin")
for order in self.env['pos.order'].search([]):
self.assertEqual(order.state, 'paid', "Validated order has payment of " + str(order.amount_paid) + " and total of " + str(order.amount_total))
@@ -504,7 +504,7 @@ class TestUi(TestPointOfSaleHttpCommon):
def test_02_pos_with_invoiced(self):
self.main_pos_config.open_session_cb(check_coa=False)
self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'ChromeTour', login="admin", step_delay=50)
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'ChromeTour', login="admin", step_delay=50)
n_invoiced = self.env['pos.order'].search_count([('state', '=', 'invoiced')])
n_paid = self.env['pos.order'].search_count([('state', '=', 'paid')])
self.assertEqual(n_invoiced, 1, 'There should be 1 invoiced order.')
@@ -513,13 +513,13 @@ class TestUi(TestPointOfSaleHttpCommon):
def test_03_order_management(self):
self.main_pos_config.write({ 'manage_orders': True, 'module_account': True })
self.main_pos_config.open_session_cb(check_coa=False)
self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'OrderManagementScreenTour', login="admin", step_delay=50)
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'OrderManagementScreenTour', login="admin", step_delay=50)
def test_04_product_configurator(self):
self.main_pos_config.write({ 'product_configurator': True })
self.main_pos_config.open_session_cb(check_coa=False)
self.start_tour("/pos/web?config_id=%d" % self.main_pos_config, 'ProductConfiguratorTour', login="admin", step_delay=50)
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config, 'ProductConfiguratorTour', login="admin", step_delay=50)
def test_05_ticket_screen(self):
self.main_pos_config.open_session_cb(check_coa=False)
self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'TicketScreenTour', login="admin", step_delay=50)
self.start_tour("/pos/ui?config_id=%d" % self.main_pos_config.id, 'TicketScreenTour', login="admin", step_delay=50)
+2 -2
View File
@@ -13,10 +13,10 @@ class WebSuite(odoo.tests.HttpCase):
self.main_pos_config = env.ref('point_of_sale.pos_config_main')
def test_pos_js(self):
# open a session, the /pos/web controller will redirect to it
# open a session, the /pos/ui controller will redirect to it
self.main_pos_config.open_session_cb(check_coa=False)
# point_of_sale desktop test suite
self.browser_js(
"/pos/web/tests?mod=web&failfast", "", "", login="admin", timeout=1800
"/pos/ui/tests?mod=web&failfast", "", "", login="admin", timeout=1800
)
@@ -49,5 +49,5 @@ odoo.define('point_of_sale.tour.PosHr', function (require) {
NumberPopup.do.clickConfirm();
ProductScreen.check.isShown();
Tour.register('PosHrTour', { test: true, url: '/pos/web' }, getSteps());
Tour.register('PosHrTour', { test: true, url: '/pos/ui' }, getSteps());
});
+2 -2
View File
@@ -43,11 +43,11 @@ class TestPosHrHttpCommon(TestPointOfSaleHttpCommon):
@tagged("post_install", "-at_install")
class TestUi(TestPosHrHttpCommon):
def test_01_pos_hr_tour(self):
# open a session, the /pos/web controller will redirect to it
# open a session, the /pos/ui controller will redirect to it
self.main_pos_config.open_session_cb(check_coa=False)
self.start_tour(
"/pos/web?config_id=%d" % self.main_pos_config.id,
"/pos/ui?config_id=%d" % self.main_pos_config.id,
"PosHrTour",
login="admin",
)
@@ -44,5 +44,5 @@ odoo.define('pos_restaurant.tour.ControlButtons', function (require) {
BillScreen.check.isShown();
BillScreen.do.clickBack();
Tour.register('ControlButtonsTour', { test: true, url: '/pos/web' }, getSteps());
Tour.register('ControlButtonsTour', { test: true, url: '/pos/ui' }, getSteps());
});
@@ -105,5 +105,5 @@ odoo.define('pos_restaurant.tour.FloorScreen', function (require) {
FloorScreen.do.clickTable('T1');
Chrome.check.backToFloorTextIs('Second Floor', 'T1');
Tour.register('FloorScreenTour', { test: true, url: '/pos/web' }, getSteps());
Tour.register('FloorScreenTour', { test: true, url: '/pos/ui' }, getSteps());
});
@@ -120,5 +120,5 @@ odoo.define('pos_restaurant.tour.OrderManagementScreen', function (require) {
ProductScreen.check.totalAmountIs('44');
Chrome.check.backToFloorTextIs('Main Floor', 'T2');
Tour.register('PosResOrderManagementScreenTour', { test: true, url: '/pos/web' }, getSteps());
Tour.register('PosResOrderManagementScreenTour', { test: true, url: '/pos/ui' }, getSteps());
});
@@ -48,5 +48,5 @@ odoo.define('pos_restaurant.tour.SplitBillScreen', function (require) {
ProductScreen.do.clickOrderline('Water', '2.0')
ProductScreen.do.clickOrderline('Minute Maid', '3.0')
Tour.register('SplitBillScreenTour', { test: true, url: '/pos/web' }, getSteps());
Tour.register('SplitBillScreenTour', { test: true, url: '/pos/ui' }, getSteps());
});
@@ -40,5 +40,5 @@ odoo.define('pos_restaurant.tour.TicketScreen', function (require) {
ProductScreen.check.totalAmountIs('2.0');
Chrome.check.backToFloorTextIs('Main Floor', 'T2');
Tour.register('PosResTicketScreenTour', { test: true, url: '/pos/web' }, getSteps());
Tour.register('PosResTicketScreenTour', { test: true, url: '/pos/ui' }, getSteps());
});
@@ -119,5 +119,5 @@ odoo.define('pos_restaurant.tour.TipScreen', function (require) {
PaymentScreen.do.clickValidate();
ReceiptScreen.check.isShown();
Tour.register('PosResTipScreenTour', { test: true, url: '/pos/web' }, getSteps());
Tour.register('PosResTipScreenTour', { test: true, url: '/pos/ui' }, getSteps());
});
@@ -64,7 +64,7 @@ odoo.define('pos_reataurant.tour.synchronized_table_management', function (requi
// There should be 1 synced draft order.
FloorScreen.check.orderCountSyncedInTableIs('T5', '1');
Tour.register('pos_restaurant_sync', { test: true, url: '/pos/web' }, getSteps());
Tour.register('pos_restaurant_sync', { test: true, url: '/pos/ui' }, getSteps());
startSteps();
@@ -104,5 +104,5 @@ odoo.define('pos_reataurant.tour.synchronized_table_management', function (requi
Chrome.do.backToFloor();
FloorScreen.check.orderCountSyncedInTableIs('T4', '1');
Tour.register('pos_restaurant_sync_second_login', { test: true, url: '/pos/web' }, getSteps());
Tour.register('pos_restaurant_sync_second_login', { test: true, url: '/pos/ui' }, getSteps());
});
+8 -8
View File
@@ -158,12 +158,12 @@ class TestFrontend(odoo.tests.HttpCase):
self.pos_config.with_user(self.env.ref('base.user_admin')).open_session_cb(check_coa=False)
self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'pos_restaurant_sync', login="admin")
self.start_tour("/pos/ui?config_id=%d" % self.pos_config.id, 'pos_restaurant_sync', login="admin")
self.assertEqual(1, self.env['pos.order'].search_count([('amount_total', '=', 4.4), ('state', '=', 'draft')]))
self.assertEqual(1, self.env['pos.order'].search_count([('amount_total', '=', 4.4), ('state', '=', 'paid')]))
self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'pos_restaurant_sync_second_login', login="admin")
self.start_tour("/pos/ui?config_id=%d" % self.pos_config.id, 'pos_restaurant_sync_second_login', login="admin")
self.assertEqual(0, self.env['pos.order'].search_count([('amount_total', '=', 4.4), ('state', '=', 'draft')]))
self.assertEqual(1, self.env['pos.order'].search_count([('amount_total', '=', 2.2), ('state', '=', 'draft')]))
@@ -171,23 +171,23 @@ class TestFrontend(odoo.tests.HttpCase):
def test_02_others(self):
self.pos_config.with_user(self.env.ref('base.user_admin')).open_session_cb(check_coa=False)
self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'SplitBillScreenTour', login="admin")
self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'ControlButtonsTour', login="admin")
self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'FloorScreenTour', login="admin")
self.start_tour("/pos/ui?config_id=%d" % self.pos_config.id, 'SplitBillScreenTour', login="admin")
self.start_tour("/pos/ui?config_id=%d" % self.pos_config.id, 'ControlButtonsTour', login="admin")
self.start_tour("/pos/ui?config_id=%d" % self.pos_config.id, 'FloorScreenTour', login="admin")
def test_03_order_management_integration(self):
self.pos_config.write({'manage_orders': True})
self.pos_config.with_user(self.env.ref('base.user_admin')).open_session_cb(check_coa=False)
self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'PosResOrderManagementScreenTour', login="admin", step_delay=50)
self.start_tour("/pos/ui?config_id=%d" % self.pos_config.id, 'PosResOrderManagementScreenTour', login="admin", step_delay=50)
def test_04_ticket_screen(self):
self.pos_config.with_user(self.env.ref('base.user_admin')).open_session_cb(check_coa=False)
self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'PosResTicketScreenTour', login="admin", step_delay=50)
self.start_tour("/pos/ui?config_id=%d" % self.pos_config.id, 'PosResTicketScreenTour', login="admin", step_delay=50)
def test_05_tip_screen(self):
self.pos_config.write({'set_tip_after_payment': True, 'iface_tipproduct': True, 'tip_product_id': self.env.ref('point_of_sale.product_product_tip')})
self.pos_config.with_user(self.env.ref('base.user_admin')).open_session_cb(check_coa=False)
self.start_tour("/pos/web?config_id=%d" % self.pos_config.id, 'PosResTipScreenTour', login="admin", step_delay=50)
self.start_tour("/pos/ui?config_id=%d" % self.pos_config.id, 'PosResTipScreenTour', login="admin", step_delay=50)
order1 = self.env['pos.order'].search([('pos_reference', 'ilike', '%-0001')])
order2 = self.env['pos.order'].search([('pos_reference', 'ilike', '%-0002')])
+1
View File
@@ -1,4 +1,5 @@
# coding: utf-8
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import pos_config
from . import pos_payment_method
+13
View File
@@ -0,0 +1,13 @@
# coding: utf-8
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models
class PosConfig(models.Model):
_inherit = 'pos.config'
def _force_http(self):
if self.payment_method_ids.filtered(lambda pm: pm.use_payment_terminal == 'six'):
return True
return super(PosConfig, self)._force_http()