diff --git a/addons/base_import/static/src/xml/base_import.xml b/addons/base_import/static/src/xml/base_import.xml index 951002b279f..c475a30036d 100644 --- a/addons/base_import/static/src/xml/base_import.xml +++ b/addons/base_import/static/src/xml/base_import.xml @@ -3,8 +3,6 @@
-
', type='http', auth='none') 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 @@ -26,6 +29,17 @@ class LivechatController(http.Controller): headers.append(('Content-Length', len(content_base64))) return request.make_response(content_base64, headers) + @http.route('/im_livechat/load_templates', type='json', auth='none', cors="*") + def load_templates(self, **kwargs): + base_url = request.httprequest.base_url + templates = [ + 'mail/static/src/xml/abstract_thread_window.xml', + 'mail/static/src/xml/discuss.xml', + 'mail/static/src/xml/thread.xml', + 'im_livechat/static/src/xml/im_livechat.xml', + ] + return [tools.file_open(tmpl, 'rb').read() for tmpl in templates] + @http.route('/im_livechat/support/', type='http', auth='public') def support_page(self, channel_id, **kwargs): channel = request.env['im_livechat.channel'].sudo().browse(channel_id) @@ -38,7 +52,7 @@ class LivechatController(http.Controller): info = request.env['im_livechat.channel'].get_livechat_info(channel.id, username=username) return request.render('im_livechat.loader', {'info': info, 'web_session_required': True}, headers=[('Content-Type', 'application/javascript')]) - @http.route('/im_livechat/init', type='json', auth="public") + @http.route('/im_livechat/init', type='json', auth="public", cors="*") def livechat_init(self, channel_id): LivechatChannel = request.env['im_livechat.channel'] available = len(LivechatChannel.browse(channel_id).get_available_users()) @@ -66,7 +80,7 @@ class LivechatController(http.Controller): 'rule': rule, } - @http.route('/im_livechat/get_session', type="json", auth='public') + @http.route('/im_livechat/get_session', type="json", auth='public', cors="*") def get_session(self, channel_id, anonymous_name, **kwargs): user_id = None country_id = None @@ -83,7 +97,7 @@ class LivechatController(http.Controller): anonymous_name, country_id = _("%s (%s)") % (anonymous_name, country.name), country.id return request.env["im_livechat.channel"].with_context(lang=False).get_mail_channel(channel_id, anonymous_name, user_id, country_id) - @http.route('/im_livechat/feedback', type='json', auth='public') + @http.route('/im_livechat/feedback', type='json', auth='public', cors="*") def feedback(self, uuid, rate, reason=None, **kwargs): Channel = request.env['mail.channel'] Rating = request.env['rating.rating'] @@ -114,7 +128,7 @@ class LivechatController(http.Controller): return rating.id return False - @http.route('/im_livechat/history', type="json", auth="public") + @http.route('/im_livechat/history', type="json", auth="public", cors="*") def history_pages(self, pid, channel_uuid, page_history=None): partner_ids = (pid, request.env.user.partner_id.id) channel = request.env['mail.channel'].sudo().search([('uuid', '=', channel_uuid), ('channel_partner_ids', 'in', partner_ids)]) @@ -122,7 +136,7 @@ class LivechatController(http.Controller): channel._send_history_message(pid, page_history) return True - @http.route('/im_livechat/notify_typing', type='json', auth='public') + @http.route('/im_livechat/notify_typing', type='json', auth='public', cors="*") def notify_typing(self, uuid, is_typing): """ Broadcast the typing notification of the website user to other channel members :param uuid: (string) the UUID of the livechat channel diff --git a/addons/im_livechat/static/src/js/im_livechat.js b/addons/im_livechat/static/src/js/im_livechat.js index f59a03e2040..964e9ef5d3e 100644 --- a/addons/im_livechat/static/src/js/im_livechat.js +++ b/addons/im_livechat/static/src/js/im_livechat.js @@ -190,15 +190,11 @@ var LivechatButton = Widget.extend({ * @private */ _loadQWebTemplate: function () { - var xml_files = ['/mail/static/src/xml/abstract_thread_window.xml', - '/mail/static/src/xml/thread.xml', - '/im_livechat/static/src/xml/im_livechat.xml']; - var defs = _.map(xml_files, function (tmpl) { - return session.rpc('/web/proxy/load', { path: tmpl }).then(function (xml) { - QWeb.add_template(xml); + return session.rpc('/im_livechat/load_templates').then(function (templates) { + _.each(templates, function (template) { + QWeb.add_template(template); }); }); - return $.when.apply($, defs); }, /** * @private diff --git a/addons/im_livechat/views/im_livechat_channel_templates.xml b/addons/im_livechat/views/im_livechat_channel_templates.xml index 85861a185fa..d029ae32478 100644 --- a/addons/im_livechat/views/im_livechat_channel_templates.xml +++ b/addons/im_livechat/views/im_livechat_channel_templates.xml @@ -194,7 +194,7 @@ odoo.define('web.session', function (require) { var Session = require('web.Session'); var modules = odoo._modules; - return new Session(undefined, "", {modules:modules, use_cors: false}); + return new Session(undefined, "", {modules:modules, use_cors: true}); }); diff --git a/addons/mail/controllers/bus.py b/addons/mail/controllers/bus.py index c900604ab06..912aae3cacd 100644 --- a/addons/mail/controllers/bus.py +++ b/addons/mail/controllers/bus.py @@ -34,7 +34,7 @@ class MailChatController(BusController): # -------------------------- # Anonymous routes (Common Methods) # -------------------------- - @route('/mail/chat_post', type="json", auth="none") + @route('/mail/chat_post', type="json", auth="none", 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") + @route(['/mail/chat_history'], type="json", auth="none", 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: diff --git a/addons/mail/static/src/xml/activity.xml b/addons/mail/static/src/xml/activity.xml index dafad00b008..217e1a39f5c 100644 --- a/addons/mail/static/src/xml/activity.xml +++ b/addons/mail/static/src/xml/activity.xml @@ -98,7 +98,6 @@ /web/binary/upload_attachment - diff --git a/addons/mail/static/src/xml/composer.xml b/addons/mail/static/src/xml/composer.xml index b9de0194e93..f405617affa 100644 --- a/addons/mail/static/src/xml/composer.xml +++ b/addons/mail/static/src/xml/composer.xml @@ -37,7 +37,6 @@ -
diff --git a/addons/mail/static/src/xml/web_kanban_activity.xml b/addons/mail/static/src/xml/web_kanban_activity.xml index 698091e9875..4d6c290f11f 100644 --- a/addons/mail/static/src/xml/web_kanban_activity.xml +++ b/addons/mail/static/src/xml/web_kanban_activity.xml @@ -92,7 +92,6 @@ /web/binary/upload_attachment - diff --git a/addons/project/static/src/xml/project.xml b/addons/project/static/src/xml/project.xml index ea69825c5a7..4be07b70fcd 100644 --- a/addons/project/static/src/xml/project.xml +++ b/addons/project/static/src/xml/project.xml @@ -15,7 +15,6 @@ /web/binary/upload_attachment - diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 59b427cfe65..cf87240484c 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -640,22 +640,6 @@ class WebClient(http.Controller): class Proxy(http.Controller): - @http.route('/web/proxy/load', type='json', auth="none") - def load(self, path): - """ Proxies an HTTP request through a JSON request. - - It is strongly recommended to not request binary files through this, - as the result will be a binary data blob as well. - - :param path: actual request path - :return: file content - """ - from werkzeug.test import Client - from werkzeug.wrappers import BaseResponse - - base_url = request.httprequest.base_url - return Client(request.httprequest.app, BaseResponse).get(path, base_url=base_url).data - @http.route('/web/proxy/post/', type='http', auth='user', methods=['GET']) def post(self, path): """Effectively execute a POST request that was hooked through user login""" diff --git a/addons/web/models/ir_http.py b/addons/web/models/ir_http.py index e42c780d31e..414df12d8c5 100644 --- a/addons/web/models/ir_http.py +++ b/addons/web/models/ir_http.py @@ -23,7 +23,6 @@ class Http(models.AbstractModel): display_switch_company_menu = user.has_group('base.group_multi_company') and len(user.company_ids) > 1 version_info = odoo.service.common.exp_version() return { - "session_id": request.session.sid, "uid": request.session.uid, "is_system": user._is_system() if request.session.uid else False, "is_admin": user._is_admin() if request.session.uid else False, diff --git a/addons/web/static/src/js/core/ajax.js b/addons/web/static/src/js/core/ajax.js index 1821d5a3be4..509126498bc 100644 --- a/addons/web/static/src/js/core/ajax.js +++ b/addons/web/static/src/js/core/ajax.js @@ -45,7 +45,6 @@ function genericJsonRpc (fct_name, params, settings, fct) { var def = $.Deferred(); return def.reject.apply(def, ["communication"].concat(_.toArray(arguments))); }); - // FIXME: jsonp? deferred.abort = function () { deferred.reject({message: "XmlHttpRequestError abort"}, $.Event('abort')); if (xhr.abort) { @@ -106,80 +105,6 @@ function jsonRpc(url, fct_name, params, settings) { }); } -function jsonpRpc(url, fct_name, params, settings) { - settings = settings || {}; - return genericJsonRpc(fct_name, params, settings, function(data) { - var payload_str = JSON.stringify(data, time.date_to_utc); - var payload_url = $.param({r:payload_str}); - var force2step = settings.force2step || false; - delete settings.force2step; - var session_id = settings.session_id || null; - delete settings.session_id; - if (payload_url.length < 2000 && ! force2step) { - return $.ajax(url, _.extend({}, settings, { - url: url, - dataType: 'jsonp', - jsonp: 'jsonp', - type: 'GET', - cache: false, - data: {r: payload_str, session_id: session_id} - })); - } else { - var args = {session_id: session_id, id: data.id}; - var ifid = _.uniqueId('oe_rpc_iframe'); - var html = ""; - var $iframe = $(html); - var nurl = 'jsonp=1&' + $.param(args); - nurl = url.indexOf("?") !== -1 ? url + "&" + nurl : url + "?" + nurl; - var $form = $('') - .attr('method', 'POST') - .attr('target', ifid) - .attr('enctype', "multipart/form-data") - .attr('action', nurl) - .append($('').attr('value', payload_str)) - .hide() - .appendTo($('body')); - var cleanUp = function() { - if ($iframe) { - $iframe.unbind("load").remove(); - } - $form.remove(); - }; - var deferred = $.Deferred(); - // the first bind is fired up when the iframe is added to the DOM - $iframe.bind('load', function() { - // the second bind is fired up when the result of the form submission is received - $iframe.unbind('load').bind('load', function() { - $.ajax({ - url: url, - dataType: 'jsonp', - jsonp: 'jsonp', - type: 'GET', - cache: false, - data: {session_id: session_id, id: data.id} - }).always(function() { - cleanUp(); - }).done(function() { - deferred.resolve.apply(deferred, arguments); - }).fail(function() { - deferred.reject.apply(deferred, arguments); - }); - }); - // now that the iframe can receive data, we fill and submit the form - $form.submit(); - }); - // append the iframe to the DOM (will trigger the first load) - $form.after($iframe); - if (settings.timeout) { - realSetTimeout(function() { - deferred.reject({}); - }, settings.timeout); - } - return deferred; - } - }); -} - // helper function to make a rpc with a function name hardcoded to 'call' function rpc(url, params, settings) { return jsonRpc(url, 'call', params, settings); @@ -312,7 +237,7 @@ function get_file(options) { xhr.open('POST', options.url); data = new FormData(); _.each(options.data || {}, function (v, k) { - data.append(k, v) + data.append(k, v); }); } data.append('token', 'dummy-because-api-expects-one'); @@ -360,7 +285,7 @@ function get_file(options) { name: String(xhr.status), title: nodes.length > 0 ? nodes[0].textContent : '', } - } + }; } options.error(err); }; @@ -375,7 +300,7 @@ function get_file(options) { } }; if (options.complete) { - xhr.onloadend = function () { options.complete(); } + xhr.onloadend = function () { options.complete(); }; } xhr.send(data); @@ -596,7 +521,6 @@ function loadLibs (libs) { var ajax = { jsonRpc: jsonRpc, - jsonpRpc: jsonpRpc, rpc: rpc, loadCSS: loadCSS, loadJS: loadJS, diff --git a/addons/web/static/src/js/core/session.js b/addons/web/static/src/js/core/session.js index 694285cccdc..7212b8ad76e 100644 --- a/addons/web/static/src/js/core/session.js +++ b/addons/web/static/src/js/core/session.js @@ -22,11 +22,8 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, { or `null` if the server to contact is the origin server. @param {Dict} options A dictionary that can contain the following options: - * "override_session": Default to false. If true, the current session object will - not try to re-use a previously created session id stored in a cookie. - * "session_id": Default to null. If specified, the specified session_id will be used - by this session object. Specifying this option automatically implies that the option - "override_session" is set to true. + * "modules" + * "use_cors" */ init: function (parent, origin, options) { mixins.EventDispatcherMixin.init.call(this); @@ -34,8 +31,6 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, { options = options || {}; this.module_list = (options.modules && options.modules.slice()) || (window.odoo._modules && window.odoo._modules.slice()) || []; this.server = null; - this.session_id = options.session_id || null; - this.override_session = options.override_session || !!options.session_id || false; this.avoid_recursion = false; this.use_cors = options.use_cors || false; this.setup(origin); @@ -61,7 +56,6 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, { this.origin = origin; this.prefix = this.origin; this.server = this.origin; // keep chs happy - this.origin_server = this.origin === window_origin; options = options || {}; if ('use_cors' in options) { this.use_cors = options.use_cors; @@ -139,7 +133,6 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, { if (!result.uid) { return $.Deferred().reject(); } - delete result.session_id; _.extend(self, result); }); }, @@ -276,9 +269,6 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, { return this.currencies[currency_id]; }, get_file: function (options) { - if (this.override_session){ - options.data.session_id = this.session_id; - } options.session = this; return ajax.get_file(options); }, @@ -290,29 +280,9 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, { */ session_reload: function () { var result = _.extend({}, window.odoo.session_info); - delete result.session_id; _.extend(this, result); return $.when(); }, - check_session_id: function () { - var self = this; - if (this.avoid_recursion) - return $.when(); - if (this.session_id) - return $.when(); // we already have the session id - if (!this.use_cors && (this.override_session || ! this.origin_server)) { - // If we don't use the origin server we consider we should always create a new session. - // Even if some browsers could support cookies when using jsonp that behavior is - // not consistent and the browser creators are tending to removing that feature. - this.avoid_recursion = true; - return this.rpc("/gen_session_id", {}).then(function (result) { - self.session_id = result; - }).always(function () { - self.avoid_recursion = false; - }); - } - return $.when(); - }, /** * Executes an RPC call, registering the provided callbacks. * @@ -333,57 +303,19 @@ var Session = core.Class.extend(mixins.EventDispatcherMixin, { options.headers["X-Debug-Mode"] = $.deparam($.param.querystring()).debug; } - var deferred = self.check_session_id(); - var aborted = false; - var xhrDef; - deferred.abort = function () { - if (xhrDef) { - xhrDef.abort(); - } else { - aborted = true; - } - }; + // TODO: remove + if (! _.isString(url)) { + _.extend(options, url); + url = url.url; + } + if (self.use_cors) { + url = self.url(url, null); + } - var promise = deferred.then(function () { - if (aborted) { - var def = $.Deferred().reject({message: "XmlHttpRequestError abort"}, $.Event('abort')); - def.abort = function () {}; - return def; - } - // TODO: remove - if (! _.isString(url)) { - _.extend(options, url); - url = url.url; - } - var fct; - if (self.origin_server) { - fct = ajax.jsonRpc; - if (self.override_session) { - options.headers["X-Openerp-Session-Id"] = self.session_id || ''; - } - } else if (self.use_cors) { - fct = ajax.jsonRpc; - url = self.url(url, null); - options.session_id = self.session_id || ''; - if (self.override_session) { - options.headers["X-Openerp-Session-Id"] = self.session_id || ''; - } - } else { - fct = ajax.jsonpRpc; - url = self.url(url, null); - options.session_id = self.session_id || ''; - } - xhrDef = fct(url, "call", params, options); - return xhrDef; - }); - - promise.abort = deferred.abort; - return promise; + return ajax.jsonRpc(url, "call", params, options); }, url: function (path, params) { params = _.extend(params || {}); - if (this.override_session || (! this.origin_server)) - params.session_id = this.session_id; var qs = $.param(params); if (qs.length > 0) qs = "?" + qs; diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index b3cd17a38ee..ae080f45a11 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -1446,7 +1446,6 @@ var AbstractFieldBinary = AbstractField.extend({ self.on_file_uploaded(file.size, file.name, file.type, data); }; } else { - this.$('form.o_form_binary_form input[name=session_id]').val(this.getSession().session_id); this.$('form.o_form_binary_form').submit(); } this.$('.o_form_binary_progress').show(); diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 5e2f27ccc66..dc40c962333 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -378,7 +378,6 @@ - Add... @@ -998,7 +997,6 @@ - @@ -1042,7 +1040,6 @@ - @@ -1567,7 +1564,6 @@ - diff --git a/addons/website_sale/static/src/js/website_sale_tour_shop_customize.js b/addons/website_sale/static/src/js/website_sale_tour_shop_customize.js index 009eb44b436..da48b761560 100644 --- a/addons/website_sale/static/src/js/website_sale_tour_shop_customize.js +++ b/addons/website_sale/static/src/js/website_sale_tour_shop_customize.js @@ -47,8 +47,8 @@ odoo.define('website_sale.tour_shop_customize', function (require) { args: ['product.group_product_variant', false], kwargs: {} }; - ajax.jsonpRpc('/web/dataset/call_kw', 'call', get_group_payload).then(function(group_id) { - ajax.jsonpRpc('/web/dataset/call_kw', 'call', { + ajax.jsonRpc('/web/dataset/call_kw', 'call', get_group_payload).then(function(group_id) { + ajax.jsonRpc('/web/dataset/call_kw', 'call', { model: 'res.groups', method: 'write', args: [group_id, {'users': [[4, 1]]}], diff --git a/odoo/http.py b/odoo/http.py index 3b44a7d2054..886fecc48ba 100644 --- a/odoo/http.py +++ b/odoo/http.py @@ -302,7 +302,7 @@ class WebRequest(object): def _handle_exception(self, exception): """Called within an except block to allow converting exceptions to abitrary responses. Anything returned (except None) will - be used as response.""" + be used as response.""" self._failed = exception # prevent tx commit if not isinstance(exception, NO_POSTMORTEM) \ and not isinstance(exception, werkzeug.exceptions.HTTPException): @@ -579,34 +579,14 @@ class JsonRequest(WebRequest): def __init__(self, *args): super(JsonRequest, self).__init__(*args) - self.jsonp_handler = None self.params = {} args = self.httprequest.args - jsonp = args.get('jsonp') - self.jsonp = jsonp request = None request_id = args.get('id') - - if jsonp and self.httprequest.method == 'POST': - # jsonp 2 steps step1 POST: save call - def handler(): - self.session['jsonp_request_%s' % (request_id,)] = self.httprequest.form['r'] - self.session.modified = True - headers=[('Content-Type', 'text/plain; charset=utf-8')] - r = werkzeug.wrappers.Response(request_id, headers=headers) - return r - self.jsonp_handler = handler - return - elif jsonp and args.get('r'): - # jsonp method GET - request = args.get('r') - elif jsonp and request_id: - # jsonp 2 steps step2 GET: run and return result - request = self.session.pop('jsonp_request_%s' % (request_id,), '{}') - else: - # regular jsonrpc2 - request = self.httprequest.get_data().decode(self.httprequest.charset) + + # regular jsonrpc2 + request = self.httprequest.get_data().decode(self.httprequest.charset) # Read POST content or POST Form Data named "request" try: @@ -630,16 +610,8 @@ class JsonRequest(WebRequest): if result is not None: response['result'] = result - if self.jsonp: - # If we use jsonp, that's mean we are called from another host - # Some browser (IE and Safari) do no allow third party cookies - # We need then to manage http sessions manually. - response['session_id'] = self.session.sid - mime = 'application/javascript' - body = "%s(%s);" % (self.jsonp, json.dumps(response, default=date_utils.json_default)) - else: - mime = 'application/json' - body = json.dumps(response, default=date_utils.json_default) + mime = 'application/json' + body = json.dumps(response, default=date_utils.json_default) return Response( body, status=error and error.pop('http_status', 200) or 200, @@ -674,8 +646,6 @@ class JsonRequest(WebRequest): return self._json_response(error=error) def dispatch(self): - if self.jsonp_handler: - return self.jsonp_handler() try: rpc_request_flag = rpc_request.isEnabledFor(logging.DEBUG) rpc_response_flag = rpc_response.isEnabledFor(logging.DEBUG) @@ -1388,8 +1358,6 @@ class Root(object): def get_request(self, httprequest): # deduce type of request - if httprequest.args.get('jsonp'): - return JsonRequest(httprequest) if httprequest.mimetype in ("application/json", "application/json-rpc"): return JsonRequest(httprequest) else: @@ -1647,15 +1615,5 @@ def content_disposition(filename): return "attachment; filename*=UTF-8''%s" % escaped -#---------------------------------------------------------- -# RPC controller -#---------------------------------------------------------- -class CommonController(Controller): - - @route('/gen_session_id', type='json', auth="none") - def gen_session_id(self): - nsession = root.session_store.new() - return nsession.sid - # main wsgi handler root = Root()