diff --git a/addons/web/__openerp__.py b/addons/web/__openerp__.py index 09347eea24c..212a8a57cc6 100644 --- a/addons/web/__openerp__.py +++ b/addons/web/__openerp__.py @@ -12,7 +12,10 @@ This module provides the core of the OpenERP Web Client. 'depends': ['base'], 'auto_install': True, 'post_load': 'wsgi_postload', - 'js' : [ + 'data': [ + 'views/webclient_templates.xml', + ], + 'js': [ "static/lib/es5-shim/es5-shim.min.js", "static/lib/datejs/globalization/en-US.js", "static/lib/datejs/core.js", diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index a7a5625afe9..49bc2a7a1c3 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -6,6 +6,7 @@ import csv import functools import glob import itertools +import jinja2 import logging import operator import datetime @@ -16,8 +17,6 @@ import simplejson import time import urllib import urllib2 -import urlparse -import xmlrpclib import zlib from xml.etree import ElementTree from cStringIO import StringIO @@ -33,13 +32,18 @@ except ImportError: import openerp import openerp.modules.registry from openerp.tools.translate import _ -from openerp.tools import config from openerp import http -from openerp.http import request, serialize_exception as _serialize_exception +from openerp.http import request, serialize_exception as _serialize_exception, LazyResponse _logger = logging.getLogger(__name__) +env = jinja2.Environment( + loader=jinja2.PackageLoader('openerp.addons.web', "views"), + autoescape=True +) +env.filters["json"] = simplejson.dumps + #---------------------------------------------------------- # OpenERP Web helpers #---------------------------------------------------------- @@ -108,12 +112,13 @@ def serialize_exception(f): return werkzeug.exceptions.InternalServerError(simplejson.dumps(error)) return wrap -def redirect_with_hash(url, code=303): - # Most IE and Safari versions decided not to preserve location.hash upon - # redirect. And even if IE10 pretends to support it, it still fails - # inexplicably in case of multiple redirects (and we do have some). - # See extensive test page at http://greenbytes.de/tech/tc/httpredirects/ - return "
" % url +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 module_topological_sort(modules): """ Return a list of module names sorted so that their dependencies of the @@ -512,6 +517,8 @@ def content_disposition(filename): # OpenERP Web web Controllers #---------------------------------------------------------- +# TODO: to remove once the database manager has been migrated server side +# and `edi` + `pos` addons has been adapted to use render_bootstrap_template() html_template = """ @@ -538,53 +545,89 @@ html_template = """ """ +def render_bootstrap_template(db, template, values=None, debug=False, lazy=False, **kw): + if request and request.debug: + debug = True + if values is None: + values = {} + values.update(kw) + values['debug'] = debug + + for res in ['js', 'css']: + if res not in values: + values[res] = manifest_list(res, db=db, debug=debug) + + if 'modules' not in values: + values['modules'] = module_boot(db=db) + values['modules'] = simplejson.dumps(values['modules']) + + def callback(template, values): + registry = openerp.modules.registry.RegistryManager.get(db) + with registry.cursor() as cr: + view_obj = registry["ir.ui.view"] + return view_obj.render(cr, openerp.SUPERUSER_ID, template, values) + if lazy: + return LazyResponse(callback, template=template, values=values) + else: + return callback(template, values) + class Home(http.Controller): @http.route('/', type='http', auth="none") - def index(self, s_action=None, db=None, debug=False, **kw): - query = dict(urlparse.parse_qsl(request.httprequest.query_string, keep_blank_values=True)) - redirect = '/web' + '?' + urllib.urlencode(query) - return redirect_with_hash(redirect) + def index(self, s_action=None, db=None, **kw): + return http.local_redirect('/web', query=request.params) @http.route('/web', type='http', auth="none") - def web_client(self, s_action=None, db=None, debug=False, **kw): - debug = debug != False + def web_client(self, s_action=None, db=None, **kw): + # if db not provided, use the session one + if not db: + db = request.session.db - lst = http.db_list(True) - if db not in lst: - db = None - guessed_db = http.db_monodb(request.httprequest) - if guessed_db is None and len(lst) > 0: - guessed_db = lst[0] + # if no database provided and no database in session, use monodb + if not db: + db = http.db_monodb(request.httprequest) - def redirect(db): - query = dict(urlparse.parse_qsl(request.httprequest.query_string, keep_blank_values=True)) - query['db'] = db - redirect = request.httprequest.path + '?' + urllib.urlencode(query) - return redirect_with_hash(redirect) + # 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: + return http.local_redirect('/web/database/selector') - if db is None and guessed_db is not None: - return redirect(guessed_db) + # always switch the session to the computed db + if db != request.session.db: + request.session.logout() + request.session.db = db - if db is not None and db != request.session.db: + if request.session.uid: + html = render_bootstrap_template(db, "web.webclient_bootstrap") + return request.make_response(html, {'Cache-Control': 'no-cache', 'Content-Type': 'text/html; charset=utf-8'}) + else: + return http.local_redirect('/web/login', query=request.params) + + @http.route('/web/login', type='http', auth="none") + def web_login(self, redirect=None, db=None, **kw): + if db and db != request.session.db: request.session.logout() request.session.db = db - guessed_db = db + request.params.pop('db', None) + return http.local_redirect('/web/login', query=request.params) - js = "\n ".join('' % i for i in manifest_list('js', db=guessed_db, debug=debug)) - css = "\n ".join('' % i for i in manifest_list('css', db=guessed_db, debug=debug)) + if not request.session.db and not db: + return http.local_redirect('/web/database/selector') - r = html_template % { - 'js': js, - 'css': css, - 'modules': simplejson.dumps(module_boot(db=guessed_db)), - 'init': 'var wc = new s.web.WebClient();wc.appendTo($(document.body));' - } - return request.make_response(r, {'Cache-Control': 'no-cache', 'Content-Type': 'text/html; charset=utf-8'}) + values = request.params.copy() + if not redirect: + redirect = '/web?' + request.httprequest.query_string + values['redirect'] = redirect + if request.httprequest.method == 'POST': + uid = request.session.authenticate(request.session.db, request.params['login'], request.params['password']) + if uid is not False: + return http.redirect_with_hash(redirect) + values['error'] = "Wrong login/password" + return render_bootstrap_template(request.session.db, 'web.login', values, lazy=True) @http.route('/login', type='http', auth="none") - def login(self, db, login, key): - return login_and_redirect(db, login, key) + def login(self, db, login, key, redirect="/web", **kw): + return login_and_redirect(db, login, key, redirect_url=redirect) class WebClient(http.Controller): @@ -754,6 +797,37 @@ class Proxy(http.Controller): class Database(http.Controller): + @http.route('/web/database/selector', type='http', auth="none") + def selector(self, **kw): + try: + dbs = http.db_list() + if not dbs: + return http.local_redirect('/web/database/manager') + except openerp.exceptions.AccessDenied: + dbs = False + return env.get_template("database_selector.html").render({ + 'databases': dbs, + 'debug': request.debug, + }) + + @http.route('/web/database/manager', type='http', auth="none") + def manager(self, **kw): + # TODO: migrate the webclient's database manager to server side views + request.session.logout() + js = "\n ".join('' % i for i in manifest_list('js', debug=request.debug)) + css = "\n ".join('' % i for i in manifest_list('css', debug=request.debug)) + + r = html_template % { + 'js': js, + 'css': css, + 'modules': simplejson.dumps(module_boot()), + 'init': """ + var wc = new s.web.WebClient(null, { action: 'database_manager' }); + wc.appendTo($(document.body)); + """ + } + return r + @http.route('/web/database/get_list', type='json', auth="none") def get_list(self): # TODO change js to avoid calling this method if in monodb mode @@ -768,12 +842,15 @@ class Database(http.Controller): @http.route('/web/database/create', type='json', auth="none") def create(self, fields): params = dict(map(operator.itemgetter('name', 'value'), fields)) - return request.session.proxy("db").create_database( + db_created = request.session.proxy("db").create_database( params['super_admin_pwd'], params['db_name'], bool(params.get('demo_data')), params['db_lang'], params['create_admin_pwd']) + if db_created: + request.session.authenticate(params['db_name'], 'admin', params['create_admin_pwd']) + return db_created @http.route('/web/database/duplicate', type='json', auth="none") def duplicate(self, fields): @@ -942,7 +1019,7 @@ class Session(http.Controller): def destroy(self): request.session.logout() - @http.route('/web/session/logout', type='http', auth="user") + @http.route('/web/session/logout', type='http', auth="none") def logout(self, redirect='/web'): request.session.logout() return werkzeug.utils.redirect(redirect, 303) diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index ae3ce185f73..ea57a7b8bdb 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -874,153 +874,6 @@ padding: 5px; width: 32px; } -.openerp .oe_login { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAKUlEQVQIHWO8e/fufwYsgAUkJigoiCIF5DMyoYggcUiXgNnBiGQKmAkARpcEQeriln4AAAAASUVORK5CYII=); - text-align: center; - font-size: 14px; - height: 100%; -} -.openerp .oe_login ul, .openerp .oe_login li { - margin: 0; - list-style-type: none; - padding: 0 0 4px 0; -} -.openerp .oe_login button { - cursor: pointer; - padding: 6px 16px; - border: 1px solid #222222; - color: white; - margin: 0; - background-color: #8c1313; - background-image: -webkit-gradient(linear, left top, left bottom, from(#b92020), to(#600606)); - background-image: -webkit-linear-gradient(top, #b92020, #600606); - background-image: -moz-linear-gradient(top, #b92020, #600606); - background-image: -ms-linear-gradient(top, #b92020, #600606); - background-image: -o-linear-gradient(top, #b92020, #600606); - background-image: linear-gradient(to bottom, #b92020, #600606); - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - border-radius: 4px; - -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(155, 155, 155, 0.4) inset; - -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(155, 155, 155, 0.4) inset; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(155, 155, 155, 0.4) inset; -} -.openerp .oe_login input, .openerp .oe_login select { - width: 252px; - font-family: "Lucida Grande", Helvetica, Verdana, Arial; - border: 1px solid #999999; - background: whitesmoke; - -moz-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.4); - -webkit-box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.4); - box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.4); - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; -} -.openerp .oe_login input { - margin-bottom: 9px; - padding: 5px 6px; -} -.openerp .oe_login select { - padding: 1px; -} -.openerp .oe_login .oe_login_dbpane { - position: fixed; - top: 0; - right: 8px; - padding: 5px 10px; - color: #eeeeee; - border: solid 1px #333333; - background: #1e1e1e; - background: rgba(30, 30, 30, 0.94); - -moz-border-radius: 0 0 8px 8px; - -webkit-border-radius: 0 0 8px 8px; - border-radius: 0 0 8px 8px; -} -.openerp .oe_login .oe_login_dbpane input { - padding: 2px 4px; - margin: 4px 0; -} -.openerp .oe_login .oe_login_bottom { - position: absolute; - top: 50%; - left: 0; - right: 0; - bottom: 0; - text-shadow: 0 1px 1px #999999; - background-color: #8a0e0e; - background-image: -webkit-gradient(linear, left top, left bottom, from(#b41616), to(#600606)); - background-image: -webkit-linear-gradient(top, #b41616, #600606); - background-image: -moz-linear-gradient(top, #b41616, #600606); - background-image: -ms-linear-gradient(top, #b41616, #600606); - background-image: -o-linear-gradient(top, #b41616, #600606); - background-image: linear-gradient(to bottom, #b41616, #600606); -} -.openerp .oe_login .oe_login_pane { - position: absolute; - top: 50%; - left: 50%; - margin: -160px -166px; - border: solid 1px #333333; - background: #1e1e1e; - background: rgba(30, 30, 30, 0.94); - padding: 22px 32px; - color: #eeeeee; - text-align: left; - -moz-border-radius: 8px; - -webkit-border-radius: 8px; - border-radius: 8px; - -moz-box-shadow: 0 0 18px rgba(0, 0, 0, 0.9); - -webkit-box-shadow: 0 0 18px rgba(0, 0, 0, 0.9); - box-shadow: 0 0 18px rgba(0, 0, 0, 0.9); -} -.openerp .oe_login .oe_login_pane h2 { - margin-top: 0; - font-size: 18px; -} -.openerp .oe_login .oe_login_logo { - position: absolute; - top: -70px; - left: 0; - width: 100%; - margin: 0 auto; - text-align: center; -} -.openerp .oe_login .oe_login_footer { - position: absolute; - bottom: -40px; - left: 0; - width: 100%; - text-align: center; -} -.openerp .oe_login .oe_login_footer a { - color: #eeeeee; - margin: 0 6px; -} -.openerp .oe_login .oe_login_footer a:hover { - text-decoration: underline; -} -.openerp .oe_login .oe_login_footer span { - font-weight: bold; - font-size: 16px; -} -.openerp .oe_login .oe_login_error_message { - display: none; - background-color: #b41616; - color: #eeeeee; - padding: 14px 18px; - margin-top: 15px; - text-align: center; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - border-radius: 4px; - -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.8); - -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.8); - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.8); -} -.openerp .oe_login_invalid .oe_login_error_message { - display: inline-block; -} .openerp .oe_database_manager { background: white; color: black; @@ -1050,7 +903,7 @@ background-image: -moz-linear-gradient(top, #fc8787, maroon); background-image: -ms-linear-gradient(top, #fc8787, maroon); background-image: -o-linear-gradient(top, #fc8787, maroon); - background-image: linear-gradient(to bottom, #fc8787, maroon); + background-image: linear-gradient(to bottom, #fc8787, #800000); } .openerp .navbar .oe_topbar_anonymous_login a { display: block; @@ -3385,6 +3238,33 @@ div.ui-widget-overlay { padding-bottom: 10px !important; } +body.oe_single_form { + background: #eeeeee url(/web/static/src/img/form_sheetbg.png); + height: 100%; +} +body.oe_single_form .oe_single_form_logo { + padding: 10px; + text-align: center; + margin-bottom: 10px; +} +body.oe_single_form .oe_single_form_footer { + position: absolute; + bottom: -30px; + right: 0px; + width: 100%; + text-align: center; +} +body.oe_single_form .oe_single_form_container { + padding: 10px; + position: absolute; + left: 50%; + top: 50%; + width: 400px; + /* Set margins to offset 50% of the w/h */ + margin-top: -200px; + margin-left: -200px; +} + .openerp_ie .placeholder { color: #afafb6 !important; font-style: italic !important; diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index 4ed3a10870f..b280c8209a4 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -747,108 +747,6 @@ $sheet-padding: 16px padding: 5px width: 32px // }}} - // Login {{{ - .oe_login - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAKUlEQVQIHWO8e/fufwYsgAUkJigoiCIF5DMyoYggcUiXgNnBiGQKmAkARpcEQeriln4AAAAASUVORK5CYII=) - text-align: center - font-size: 14px - height: 100% - ul, li - margin: 0 - list-style-type: none - padding: 0 0 4px 0 - button - cursor: pointer - padding: 6px 16px - border: 1px solid #222 - color: white - margin: 0 - @include vertical-gradient(#b92020, #600606) - @include radius(4px) - @include box-shadow((0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 1px rgba(155, 155, 155, 0.4) inset)) - input, select - width: 252px - font-family: "Lucida Grande", Helvetica, Verdana, Arial - border: 1px solid #999999 - background: whitesmoke - @include box-shadow(inset 0 1px 4px rgba(0, 0, 0, 0.4)) - @include radius(3px) - input - margin-bottom: 9px - padding: 5px 6px - select - padding: 1px - .oe_login_dbpane - position: fixed - top: 0 - right: 8px - padding: 5px 10px - color: #eee - border: solid 1px #333 - background: #1e1e1e - background: rgba(30,30,30,0.94) - @include radius(0 0 8px 8px) - input - padding: 2px 4px - margin: 4px 0 - .oe_login_bottom - position: absolute - top: 50% - left: 0 - right: 0 - bottom: 0 - text-shadow: 0 1px 1px #999999 - @include vertical-gradient(#b41616, #600606) - .oe_login_pane - position: absolute - top: 50% - left: 50% - margin: -160px -166px - border: solid 1px #333333 - background: #1e1e1e - background: rgba(30,30,30,0.94) - padding: 22px 32px - color: #eee - text-align: left - @include radius(8px) - @include box-shadow(0 0 18px rgba(0, 0, 0, 0.9)) - h2 - margin-top: 0 - font-size: 18px - .oe_login_logo - position: absolute - top: -70px - left: 0 - width: 100% - margin: 0 auto - text-align: center - .oe_login_footer - position: absolute - bottom: -40px - left: 0 - width: 100% - text-align: center - a - color: #eee - margin: 0 6px - &:hover - text-decoration: underline - span - font-weight: bold - font-size: 16px - .oe_login_error_message - display: none - background-color: #b41616 - color: #eee - padding: 14px 18px - margin-top: 15px - text-align: center - @include radius(4px) - @include box-shadow(0 1px 4px rgba(0, 0, 0, 0.8)) - .oe_login_invalid - .oe_login_error_message - display: inline-block - // }}} // DatabaseManager {{{ .oe_database_manager background: #fff @@ -2698,6 +2596,38 @@ div.ui-widget-overlay td padding-bottom: 10px !important +// Server side single forms {{{ +@mixin single-form($width: 400px) + padding: 10px + position: absolute + left: 50% + top: 50% + width: $width + /* Set margins to offset 50% of the w/h */ + margin-top: -($width / 2) + margin-left: -($width / 2) + +body.oe_single_form + background: #eee url(/web/static/src/img/form_sheetbg.png) + height: 100% + + .oe_single_form_logo + padding: 10px + text-align: center + margin-bottom: 10px + + .oe_single_form_footer + position: absolute + bottom: -30px + right: 0px + width: 100% + text-align: center + + .oe_single_form_container + @include single-form(400px) + +// }}} + // Internet Explorer 9+ specifics {{{ .openerp_ie .placeholder diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 4ac351707d0..afa761d7025 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -475,19 +475,6 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ this.$el.find('#db-create, #db-drop, #db-backup, #db-restore, #db-change-password, #back-to-login').unbind('click').end().empty(); this._super(); }, - /** - * Converts a .serializeArray() result into a dict. Does not bother folding - * multiple identical keys into an array, last key wins. - * - * @param {Array} array - */ - to_object: function (array) { - var result = {}; - _(array).each(function (record) { - result[record.name] = record.value; - }); - return result; - }, /** * Blocks UI and replaces $.unblockUI by a noop to prevent third parties * from unblocking the UI @@ -525,25 +512,11 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ var self = this; var fields = $(form).serializeArray(); self.rpc("/web/database/create", {'fields': fields}).done(function(result) { - var form_obj = self.to_object(fields); - var client_action = { - type: 'ir.actions.client', - tag: 'login', - params: { - 'db': form_obj['db_name'], - 'login': 'admin', - 'password': form_obj['create_admin_pwd'], - 'login_successful': function() { - var url = '/web?db=' + form_obj['db_name']; - if (self.session.debug) { - url += '&debug'; - } - instance.web.redirect(url); - }, - }, - _push_me: false, - }; - self.do_action(client_action); + if (result) { + instance.web.redirect('/web') + } else { + alert("Failed to create database"); + } }); }, do_duplicate: function(form) { @@ -641,156 +614,20 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ }, do_exit: function () { this.$el.remove(); - instance.webclient.show_login(); + instance.web.redirect('/web'); } }); instance.web.client_actions.add("database_manager", "instance.web.DatabaseManager"); -instance.web.Login = instance.web.Widget.extend({ - template: "Login", - remember_credentials: true, - events: { - 'change input[name=db],select[name=db]': function(ev) { - this.set('database_selector', $(ev.currentTarget).val()); - }, - }, +instance.web.login = function() { + instance.web.redirect('/web/login'); +}; +instance.web.client_actions.add("login", "instance.web.login"); - init: function(parent, action) { - this._super(parent); - this.has_local_storage = typeof(localStorage) != 'undefined'; - this.db_list = null; - this.selected_db = null; - this.selected_login = null; - this.params = action.params || {}; - if (_.isEmpty(this.params)) { - this.params = $.bbq.getState(true); - } - if (action && action.params && action.params.db) { - this.params.db = action.params.db; - } else if ($.deparam.querystring().db) { - this.params.db = $.deparam.querystring().db; - } - if (this.params.db) { - this.selected_db = this.params.db; - } - - if (this.params.login_successful) { - this.on('login_successful', this, this.params.login_successful); - } - // some cleanup to remove any trace of that last login feature - if (typeof(localStorage) != 'undefined') { - var toRemove = []; - _.each(_.range(localStorage.length), function(i) { - var key = localStorage.key(i); - if (key.match(/^.*?\|last_password$/)) { - toRemove.push(key); - } - }); - _.each(toRemove, function(k) { - localStorage.removeItem(k); - }); - } - }, - start: function() { - var self = this; - self.$el.find("form").submit(self.on_submit); - self.$el.find('.oe_login_manage_db').click(function() { - self.do_action("database_manager"); - }); - self.on('change:database_selector', this, function() { - this.database_selected(this.get('database_selector')); - }); - var d = $.when(); - if ($.param.fragment().token) { - self.params.token = $.param.fragment().token; - } - // used by dbmanager.do_create via internal client action - if (self.params.db && self.params.login && self.params.password) { - d = self.do_login(self.params.db, self.params.login, self.params.password); - } else { - d = self.rpc("/web/database/get_list", {}) - .done(self.on_db_loaded) - .fail(self.on_db_failed) - .always(function() { - if (self.selected_db && self.has_local_storage && self.remember_credentials) { - self.$("[name=login]").val(localStorage.getItem(self.selected_db + '|last_login') || ''); - } - }); - } - return d; - }, - database_selected: function(db) { - var params = $.deparam.querystring(); - params.db = db; - this.$('.oe_login_dbpane').empty().text(_t('Loading...')); - this.$('[name=login], [name=password]').prop('readonly', true); - instance.web.redirect('/web?' + $.param(params)); - }, - on_db_loaded: function (result) { - var self = this; - this.db_list = result; - if (!this.selected_db) { - this.selected_db = result[0]; - } - this.$("[name=db]").replaceWith(QWeb.render('Login.dblist', { db_list: this.db_list, selected_db: this.selected_db})); - if(this.db_list.length === 0) { - this.do_action("database_manager"); - } else if(this.db_list.length === 1) { - this.$('div.oe_login_dbpane').hide(); - } else { - this.$('div.oe_login_dbpane').show(); - } - }, - on_db_failed: function (error, event) { - if (error.data.name === 'openerp.exceptions.AccessDenied') { - event.preventDefault(); - } - }, - on_submit: function(ev) { - if(ev) { - ev.preventDefault(); - } - var db = this.$("form [name=db]").val(); - if (!db) { - this.do_warn(_t("Login"), _t("No database selected !")); - return false; - } - var login = this.$("form input[name=login]").val(); - var password = this.$("form input[name=password]").val(); - - this.do_login(db, login, password); - }, - /** - * Performs actual login operation, and UI-related stuff - * - * @param {String} db database to log in - * @param {String} login user login - * @param {String} password user password - */ - do_login: function (db, login, password) { - var self = this; - self.hide_error(); - self.$(".oe_login_pane").fadeOut("slow"); - return this.session.session_authenticate(db, login, password).then(function() { - if (self.has_local_storage && self.remember_credentials) { - localStorage.setItem(db + '|last_login', login); - } - self.trigger('login_successful'); - }, function () { - self.$(".oe_login_pane").fadeIn("fast", function() { - self.show_error(_t("Invalid username or password")); - }); - }); - }, - show_error: function(message) { - this.$el.addClass("oe_login_invalid"); - this.$(".oe_login_error_message").text(message); - }, - hide_error: function() { - this.$el.removeClass('oe_login_invalid'); - }, -}); -instance.web.client_actions.add("login", "instance.web.Login"); +instance.web.logout = function() { + instance.web.redirect('/web/session/logout'); +}; +instance.web.client_actions.add("logout", "instance.web.logout"); /** @@ -1246,6 +1083,7 @@ instance.web.FullscreenWidget = instance.web.Widget.extend({ instance.web.Client = instance.web.Widget.extend({ init: function(parent, origin) { instance.client = instance.webclient = this; + this.client_options = {}; this._super(parent); this.origin = origin; }, @@ -1316,8 +1154,11 @@ instance.web.WebClient = instance.web.Client.extend({ events: { 'click .oe_logo_edit_admin': 'logo_edit' }, - init: function(parent) { + init: function(parent, client_options) { this._super(parent); + if (client_options) { + _.extend(this.client_options, client_options); + } this._current_state = null; this.menu_dm = new instance.web.DropMisordered(); this.action_mutex = new $.Mutex(); @@ -1331,11 +1172,13 @@ instance.web.WebClient = instance.web.Client.extend({ if (jQuery.deparam !== undefined && jQuery.deparam(jQuery.param.querystring()).kitten !== undefined) { self.to_kitten(); } - if (!self.session.session_is_valid()) { - self.show_login(); - } else { + if (self.session.session_is_valid()) { self.show_application(); } + if (self.client_options.action) { + self.action_manager.do_action(self.client_options.action); + delete(self.client_options.action); + } }); }, to_kitten: function() { @@ -1385,25 +1228,6 @@ instance.web.WebClient = instance.web.Client.extend({ }); }; }, - show_login: function() { - this.toggle_bars(false); - - var state = $.bbq.getState(true); - var action = { - type: 'ir.actions.client', - tag: 'login', - _push_me: false, - }; - - this.action_manager.do_action(action); - this.action_manager.inner_widget.on('login_successful', this, function() { - if ('redirect' in state) { - openerp.web.redirect(state.redirect); - } else { - this.show_application(); // will load the state we just pushed - } - }); - }, show_application: function() { var self = this; self.toggle_bars(true); @@ -1418,6 +1242,10 @@ instance.web.WebClient = instance.web.Client.extend({ self.bind_hashchange(); self.set_title(); self.check_timezone(); + if (self.client_options.action_post_login) { + self.action_manager.do_action(self.client_options.action_post_login); + delete(self.client_options.action_post_login); + } }, update_logo: function() { var img = this.session.url('/web/binary/company_logo'); @@ -1498,11 +1326,7 @@ instance.web.WebClient = instance.web.Client.extend({ on_logout: function() { var self = this; if (!this.has_uncommitted_changes()) { - this.session.session_logout().done(function () { - $(window).unbind('hashchange', self.on_hashchange); - self.do_push_state({}); - window.location.reload(); - }); + self.action_manager.do_action('logout'); } }, bind_hashchange: function() { @@ -1659,6 +1483,24 @@ instance.web.embed = function (origin, dbname, login, key, action, options) { client.insertAfter(currentScript); }; +openerp.web.LoginForm = openerp.web.Widget.extend({ + init: function ($form) { + this._super(/* no parent */); + this.setElement($form); + this.$el.on('submit', this.on_submit); + this.start(); + }, + start: function () { + if (location.hash) { + this.$el.attr('action', this.$el.attr('action') + location.hash); + } + return this._super(); + }, + on_submit: function () { + return true; + }, +}); + })(); // vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax: diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 81e029f5f87..b92ca1d3ba5 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -252,7 +252,7 @@ instance.web.Session.include( /** @lends instance.web.Session# */{ return !!this.uid; }, /** - * The session is validated either by login or by restoration of a previous session + * The session is validated by restoration of a previous session */ session_authenticate: function() { var self = this; diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 328783e5c91..fc9c2154d01 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -58,46 +58,6 @@ -