port auth_from_http_remote_user to 8.0

pull/34/head
Laurent Mignon 2014-07-30 10:23:52 +02:00
parent 7dd5bc685e
commit c893a706b8
5 changed files with 21 additions and 66 deletions

View File

@ -119,7 +119,6 @@ for a login and password outside OpenErp and are automatically logged in the sys
'website': 'http://www.acsone.eu', 'website': 'http://www.acsone.eu',
'depends': ['web'], 'depends': ['web'],
"license": "AGPL-3", "license": "AGPL-3",
"js": ['static/src/js/auth_from_http_remote_user.js'],
'data': [ 'data': [
'res_config_view.xml', 'res_config_view.xml',
'res_config_data.xml'], 'res_config_data.xml'],

View File

@ -19,4 +19,4 @@
# #
############################################################################## ##############################################################################
from . import session from . import main

View File

@ -21,9 +21,10 @@
from openerp import SUPERUSER_ID from openerp import SUPERUSER_ID
from openerp.addons.web import http import openerp
from openerp import http
from openerp.http import request
from openerp.addons.web.controllers import main from openerp.addons.web.controllers import main
from openerp.modules.registry import RegistryManager
from .. import utils from .. import utils
import random import random
@ -33,20 +34,17 @@ import openerp.tools.config as config
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
class Session(main.Session): class Home(main.Home):
_cp_path = "/web/session"
_REQUIRED_ATTRIBUTES = ['HTTP_REMOTE_USER'] _REQUIRED_ATTRIBUTES = ['HTTP_REMOTE_USER']
_OPTIONAL_ATTRIBUTES = [] _OPTIONAL_ATTRIBUTES = []
def _get_db(self, db): @http.route('/web', type='http', auth="none")
if db is not None and len(db) > 0: def web_client(self, s_action=None, **kw):
return db main.ensure_db()
db = config['db_name'] if not request.session.uid:
if db is None or len(db) == 0: self._bind_http_remote_user(http.request.session.db)
_logger.error("No db found for SSO. Specify one in the URL using parameter " return super(Home, self).web_client(s_action, **kw)
"db=? or provide a default one in the configuration")
raise http.AuthenticationError()
def _get_user_id_from_attributes(self, res_users, cr, attrs): def _get_user_id_from_attributes(self, res_users, cr, attrs):
login = attrs.get('HTTP_REMOTE_USER', None) login = attrs.get('HTTP_REMOTE_USER', None)
@ -56,12 +54,12 @@ class Session(main.Session):
return user_ids[0] return user_ids[0]
return None return None
def _get_attributes_form_header(self, req): def _get_attributes_form_header(self):
attrs = {} attrs = {}
all_attrs = self._REQUIRED_ATTRIBUTES + self._OPTIONAL_ATTRIBUTES all_attrs = self._REQUIRED_ATTRIBUTES + self._OPTIONAL_ATTRIBUTES
headers = req.httprequest.headers.environ headers = http.request.httprequest.headers.environ
for attr in all_attrs: for attr in all_attrs:
value = headers.get(attr, None) value = headers.get(attr, None)
@ -78,10 +76,9 @@ class Session(main.Session):
_logger.error("Required fields '%s' not found in http headers\n %s", missings, headers) _logger.error("Required fields '%s' not found in http headers\n %s", missings, headers)
return attrs return attrs
def _bind_http_remote_user(self, req, db_name): def _bind_http_remote_user(self, db_name):
db_name = self._get_db(db_name)
try: try:
registry = RegistryManager.get(db_name) registry = openerp.registry(db_name)
with registry.cursor() as cr: with registry.cursor() as cr:
modules = registry.get('ir.module.module') modules = registry.get('ir.module.module')
installed = modules.search_count(cr, SUPERUSER_ID, ['&', installed = modules.search_count(cr, SUPERUSER_ID, ['&',
@ -95,7 +92,7 @@ class Session(main.Session):
# get the user # get the user
res_users = registry.get('res.users') res_users = registry.get('res.users')
attrs = self._get_attributes_form_header(req) attrs = self._get_attributes_form_header()
user_id = self._get_user_id_from_attributes(res_users, cr, attrs) user_id = self._get_user_id_from_attributes(res_users, cr, attrs)
if user_id is None: if user_id is None:
@ -107,19 +104,13 @@ class Session(main.Session):
key = randomString(utils.KEY_LENGTH, '0123456789abcdef') key = randomString(utils.KEY_LENGTH, '0123456789abcdef')
res_users.write(cr, SUPERUSER_ID, [user_id], {'sso_key': key}) res_users.write(cr, SUPERUSER_ID, [user_id], {'sso_key': key})
login = res_users.browse(cr, SUPERUSER_ID, user_id).login login = res_users.browse(cr, SUPERUSER_ID, user_id).login
req.session.bind(db_name, user_id, login, key) request.session.authenticate(db_name, login=login, password=key, uid=user_id)
except http.AuthenticationError, e: except http.AuthenticationError, e:
raise e raise e
except Exception, e: except Exception, e:
_logger.error("Error binding Http Remote User session", exc_info=True) _logger.error("Error binding Http Remote User session", exc_info=True)
raise e raise e
@http.jsonrequest
def get_http_remote_user_session_info(self, req, db):
if not req.session._login:
self._bind_http_remote_user(req, db)
return self.session_info(req)
randrange = random.SystemRandom().randrange randrange = random.SystemRandom().randrange

View File

@ -1,36 +0,0 @@
openerp.auth_from_http_remote_user = function(instance) {
instance.web.Session.include({
session_load_response : function(response) {
//unregister the event since it must be called only if the rpc call
//is made by session_reload
this.off('response', this.session_load_response);
if (response.error && response.error.data.type === "session_invalid") {
$("body").html("<h1>Access Denied</h1>");
}
console.log("session_load_response called");
},
session_reload : function() {
var self = this;
// we need to register an handler for 'response' since
// by default, the rpc doesn't call callback function
// if the response is of error type 'session_invalid'
this.on('response', this, this.session_load_response);
return this.rpc("/web/session/get_http_remote_user_session_info", {
db : $.deparam.querystring().db
}).done(function(result) {
// If immediately follows a login (triggered by trying to
// restore
// an invalid session or no session at all), refresh session
// data
// (should not change, but just in case...)
_.extend(self, result);
}).fail(function(result){
$("body").html("<h1>Server error</h1>");
});
}
});
};

View File

@ -45,10 +45,11 @@ class test_res_users(common.TransactionCase):
def test_login(self): def test_login(self):
res_users_obj = self.registry('res.users') res_users_obj = self.registry('res.users')
uid = res = res_users_obj.login(common.DB, 'admin', 'admin') res = res_users_obj.authenticate(common.DB, 'admin', 'admin', None)
uid = res
self.assertTrue(res, "Basic login must works as expected") self.assertTrue(res, "Basic login must works as expected")
token = "123456" token = "123456"
res = res_users_obj.login(common.DB, 'admin', token) res = res_users_obj.authenticate(common.DB, 'admin', token, None)
self.assertFalse(res) self.assertFalse(res)
# mimic what the new controller do when it find a value in # mimic what the new controller do when it find a value in
# the http header (HTTP_REMODE_USER) # the http header (HTTP_REMODE_USER)
@ -61,7 +62,7 @@ class test_res_users(common.TransactionCase):
res_users_obj.check(common.DB, uid, token) res_users_obj.check(common.DB, uid, token)
# we are able to login with the new token # we are able to login with the new token
res = res_users_obj.login(common.DB, 'admin', token) res = res_users_obj.authenticate(common.DB, 'admin', token, None)
self.assertTrue(res) self.assertTrue(res)
@unittest.skipIf(os.environ.get('TRAVIS'), @unittest.skipIf(os.environ.get('TRAVIS'),