openerp-dev-web team mailing list archive
-
openerp-dev-web team
-
Mailing list archive
-
Message #04402
lp:~openerp-dev/openobject-client-web/proto61-login-and-session-persistence-xmo into lp:~openerp-dev/openobject-client-web/trunk-proto61
Xavier (Open ERP) has proposed merging lp:~openerp-dev/openobject-client-web/proto61-login-and-session-persistence-xmo into lp:~openerp-dev/openobject-client-web/trunk-proto61.
Requested reviews:
Antony Lesuisse (al-openerp)
For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-client-web/proto61-login-and-session-persistence-xmo/+merge/54003
Fixed session name generation, login process (including reload of menu) and backed OpenERP sessions in CherryPy sessions so they don't die when the server does (and are harder to highjack)
--
https://code.launchpad.net/~openerp-dev/openobject-client-web/proto61-login-and-session-persistence-xmo/+merge/54003
Your team OpenERP R&D Team is subscribed to branch lp:~openerp-dev/openobject-client-web/trunk-proto61.
=== modified file 'addons/base/controllers/main.py'
--- addons/base/controllers/main.py 2011-03-17 15:01:53 +0000
+++ addons/base/controllers/main.py 2011-03-18 14:33:10 +0000
@@ -95,11 +95,10 @@
@openerpweb.jsonrequest
def login(self, req, db, login, password):
req.session.login(db, login, password)
- res = {
+ return {
"session_id" : req.session_id,
"uid": req.session._uid,
}
- return res
@openerpweb.jsonrequest
def modules(self, req):
=== modified file 'addons/base/static/openerp/js/base_chrome.js'
--- addons/base/static/openerp/js/base_chrome.js 2011-03-17 17:08:08 +0000
+++ addons/base/static/openerp/js/base_chrome.js 2011-03-18 14:33:10 +0000
@@ -124,10 +124,12 @@
this.password = "";
this.uid = false;
this.session_id = false;
+ this.load_local();
this.module_list = [];
this.module_loaded = {"base": true};
this.context = {};
},
+<<<<<<< TREE
on_log: function() {
// TODO this should move to Console and be active only in debug
// TODO $element should be for error not log
@@ -140,6 +142,82 @@
}
});
},
+=======
+ /**
+ * Reloads uid and session_id from local storage, if they exist
+ */
+ load_local: function () {
+ this.uid = this.get_cookie('uid');
+ this.session_id = this.get_cookie('session_id');
+ },
+ /**
+ * Saves the session id and uid locally
+ */
+ save_local: function () {
+ this.set_local('uid', this.uid);
+ this.set_local('session_id', this.session_id);
+ },
+ // TODO: clear_local
+
+ /**
+ * Retrieves and return the value indexed by the key name from local
+ * storage, if it finds it.
+ * @param name the name of the value to get
+ */
+ get_local: function (name) {
+ if(window.localStorage) {
+ return localStorage.getItem(name);
+ }
+ return this.get_cookie(name);
+ },
+ /**
+ * Sets the value at the key name in local storage.
+ *
+ * The value has to be a String.
+ *
+ * @param name key to set the value at
+ * @param value value to store
+ */
+ set_local: function (name, value) {
+ if(window.localStorage) {
+ localStorage.setItem(name, String(value));
+ }
+ return this.set_cookie(name, value);
+ },
+
+ /**
+ * Fetches a cookie stored by an openerp session
+ *
+ * @param name the cookie's name
+ */
+ get_cookie: function (name) {
+ var nameEQ = this.element_id + '|' + name + '=';
+ var cookies = document.cookie.split(';');
+ for(var i=0; i<cookies.length; ++i) {
+ var cookie = cookies[i].replace(/^\s*/, '');
+ if(cookie.indexOf(nameEQ) === 0) {
+ return decodeURIComponent(cookie.substring(nameEQ.length));
+ }
+ }
+ return null;
+ },
+ /**
+ * Create a new secure cookie with the provided name and value
+ *
+ * @param name the cookie's name
+ * @param value the cookie's value
+ * @param ttl the cookie's time to live, 1 year by default, set to
+ * -1 to delete
+ */
+ set_cookie: function (name, value, ttl) {
+ ttl = ttl || 24*60*60*365;
+ document.cookie = [
+ this.element_id + '|' + name + '=' + encodeURIComponent(value),
+ 'max-age=' + ttl,
+ 'expires=' + new Date(new Date().getTime() + ttl*1000).toGMTString()
+ ].join(';');
+ },
+>>>>>>> MERGE-SOURCE
rpc: function(url, params, success_callback, error_callback) {
// Construct a JSON-RPC2 request, method is currently unused
params.session_id = this.session_id;
@@ -172,7 +250,7 @@
if (response.error.data.type == "session_invalid") {
self.uid = false;
self.on_session_invalid(function() {
- self.rpc(url, params, success_callback, error_callback);
+ self.rpc(url, payload.params, success_callback, error_callback);
});
} else {
error_callback(response.error);
@@ -214,6 +292,7 @@
this.rpc("/base/session/login", params, function(result) {
self.session_id = result.session_id;
self.uid = result.uid;
+ self.save_local();
self.session_check_modules();
if (success_callback)
success_callback();
@@ -230,7 +309,6 @@
self.rpc('/base/session/jslist', {"mods": self.module_list.join(',')}, self.debug ? self.do_session_load_modules_debug : self.do_session_load_modules_prod);
openerp._modules_loaded = true;
});
- this.uid = false;
},
do_session_load_modules_debug: function(result) {
var self = this;
@@ -320,22 +398,22 @@
},
start: function() {
this.$element.html(QWeb.render("Login", {}));
- //this.on_login_invalid();
this.$element.find("form").submit(this.on_submit);
},
on_login_invalid: function() {
- var $e = this.$element;
- $e.removeClass("login_valid");
- $e.addClass("login_invalid");
- $e.show();
+ this.$element
+ .removeClass("login_valid")
+ .addClass("login_invalid")
+ .show();
},
on_login_valid: function() {
- var $e = this.$element;
- $e.removeClass("oe_login_invalid");
- $e.addClass("login_valid");
- $e.hide();
+ this.$element
+ .addClass("login_valid")
+ .removeClass("login_invalid")
+ .hide();
},
on_submit: function(ev) {
+ ev.preventDefault();
var self = this;
var $e = this.$element;
var db = $e.find("form input[name=db]").val();
@@ -350,17 +428,14 @@
self.on_login_invalid();
}
});
- return false;
},
do_ask_login: function(continuation) {
this.on_login_invalid();
- this.on_submit.add({
+ this.on_login_valid.add({
position: "last",
unique: true,
- callback: function() {
- if(continuation) continuation();
- return false;
- }});
+ callback: continuation
+ });
}
});
=== modified file 'openerpweb/openerpweb.py'
--- openerpweb/openerpweb.py 2011-03-17 15:47:46 +0000
+++ openerpweb/openerpweb.py 2011-03-18 14:33:10 +0000
@@ -2,6 +2,7 @@
import functools
import optparse, os, re, sys, traceback, xmlrpclib
+import uuid
import cherrypy
import cherrypy.lib.static
@@ -64,7 +65,6 @@
#----------------------------------------------------------
# OpenERP Web RequestHandler
#----------------------------------------------------------
-session_store = {}
class JsonRequest(object):
""" JSON-RPC2 over HTTP POST using non standard POST encoding.
@@ -84,8 +84,8 @@
def parse(self, request):
self.params = request.get("params",{})
- self.session_id = self.params.pop("session_id", None) or "random.random"
- self.session = session_store.setdefault(self.session_id, OpenERPSession())
+ self.session_id = self.params.pop("session_id", None) or uuid.uuid4().hex
+ self.session = cherrypy.session.setdefault(self.session_id, OpenERPSession())
self.context = self.params.pop('context', None)
return self.params
@@ -148,7 +148,11 @@
print "<--", response
print
- return simplejson.dumps(response)
+
+ content = simplejson.dumps(response)
+ cherrypy.response.headers['Content-Type'] = 'application/json'
+ cherrypy.response.headers['Content-Length'] = len(content)
+ return content
def jsonrequest(f):
@cherrypy.expose
@@ -245,17 +249,24 @@
return m(**kw)
else:
- return '<a href="/base/static/openerp/base.html">/base/static/openerp/base.html</a>'
+ raise cherrypy.HTTPRedirect('/base/static/openerp/base.html', 301)
default.exposed = True
def main(argv):
# optparse
+ SESSIONS_STORAGE_DIRECTORY = '/tmp/cpsessions'
+ if not os.path.exists(SESSIONS_STORAGE_DIRECTORY):
+ # 10#448 == 8#700
+ os.mkdir(SESSIONS_STORAGE_DIRECTORY, 448)
config = {
'server.socket_port': 8002,
#'server.socket_host': '64.72.221.48',
#'server.thread_pool' = 10,
'tools.sessions.on': True,
+ 'tools.sessions.storage_type': 'file',
+ 'tools.sessions.storage_path': SESSIONS_STORAGE_DIRECTORY,
+ 'tools.sessions.timeout': 60
}
cherrypy.tree.mount(Root())
Follow ups