Browse Source
[ADD] This module initialize the session by looking for the field HTTP_REMOTE_USER in the HEADER of the HTTP request and trying^Co bind the given value to a user
pull/34/head
[ADD] This module initialize the session by looking for the field HTTP_REMOTE_USER in the HEADER of the HTTP request and trying^Co bind the given value to a user
pull/34/head
Laurent Mignon
10 years ago
12 changed files with 649 additions and 0 deletions
-
24auth_from_http_remote_user/__init__.py
-
133auth_from_http_remote_user/__openerp__.py
-
22auth_from_http_remote_user/controllers/__init__.py
-
129auth_from_http_remote_user/controllers/session.py
-
60auth_from_http_remote_user/res_config.py
-
9auth_from_http_remote_user/res_config_data.xml
-
39auth_from_http_remote_user/res_config_view.xml
-
64auth_from_http_remote_user/res_users.py
-
36auth_from_http_remote_user/static/src/js/auth_from_http_remote_user.js
-
28auth_from_http_remote_user/tests/__init__.py
-
83auth_from_http_remote_user/tests/test_res_users.py
-
22auth_from_http_remote_user/utils.py
@ -0,0 +1,24 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Author: Laurent Mignon |
|||
# Copyright 2014 'ACSONE SA/NV' |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
|
|||
from . import controllers |
|||
from . import res_config |
|||
from . import res_users |
@ -0,0 +1,133 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Author: Laurent Mignon |
|||
# Copyright 2014 'ACSONE SA/NV' |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
{ |
|||
'name': 'Authenticate via HTTP Remote User', |
|||
'version': '1.0', |
|||
'category': 'Tools', |
|||
'description': """ |
|||
Allow users to be automatically logged in. |
|||
========================================== |
|||
|
|||
This module initialize the session by looking for the field HTTP_REMOTE_USER in |
|||
the HEADER of the HTTP request and trying to bind the given value to a user |
|||
This module must be loaded at startup; Add the *--load* parameter to the startup |
|||
command: :: |
|||
|
|||
--load=web,web_kanban,auth_from_http_remote_user, ... |
|||
|
|||
If the field is not found or no user matches the given one, it can lets the |
|||
system redirect to the login page (default) or issue a login error page depending |
|||
of the configuration. |
|||
|
|||
How to test the module with Apache [#]_ |
|||
---------------------------------------- |
|||
|
|||
Apache can be used as a reverse proxy providing the authentication and adding the |
|||
required field in the Http headers. |
|||
|
|||
Install apache: :: |
|||
|
|||
$ sudo apt-get install apache2 |
|||
|
|||
|
|||
Define a new vhost to Apache by putting a new file in /etc/apache2/sites-available: :: |
|||
|
|||
$ sudo vi /etc/apache2/sites-available/MY_VHOST.com |
|||
|
|||
with the following content: :: |
|||
|
|||
<VirtualHost *:80> |
|||
ServerName MY_VHOST.com |
|||
ProxyRequests Off |
|||
<Location /> |
|||
AuthType Basic |
|||
AuthName "Test OpenErp auth_from_http_remote_user" |
|||
AuthBasicProvider file |
|||
AuthUserFile /etc/apache2/MY_VHOST.htpasswd |
|||
Require valid-user |
|||
|
|||
RewriteEngine On |
|||
RewriteCond %{LA-U:REMOTE_USER} (.+) |
|||
RewriteRule . - [E=RU:%1] |
|||
RequestHeader set Remote-User "%{RU}e" env=RU |
|||
</Location> |
|||
|
|||
ProxyPass / http://127.0.0.1:8069/ retry=10 |
|||
ProxyPassReverse / http://127.0.0.1:8069/ |
|||
ProxyPreserveHost On |
|||
</VirtualHost> |
|||
|
|||
.. important:: The *RequestHeader* directive is used to add the *Remote-User* field |
|||
in the http headers. By default an *'Http-'* prefix is added to the field name. |
|||
In OpenErp, header's fields name are normalized. As result of this normalization, |
|||
the 'Http-Remote-User' is available as 'HTTP_REMOTE_USER'. If you don't know how |
|||
your specified field is seen by OpenErp, run your server in debug mode once the |
|||
module is activated and look for an entry like: :: |
|||
|
|||
DEBUG openerp1 openerp.addons.auth_from_http_remote_user.controllers.session: |
|||
Field 'HTTP_MY_REMOTE_USER' not found in http headers |
|||
{'HTTP_AUTHORIZATION': 'Basic YWRtaW46YWRtaW4=', ..., 'HTTP_REMOTE_USER': 'demo') |
|||
|
|||
Enable the required apache modules: :: |
|||
|
|||
$ sudo a2enmod headers |
|||
$ sudo a2enmod proxy |
|||
$ sudo a2enmod rewrite |
|||
$ sudo a2enmod proxy_http |
|||
|
|||
Enable your new vhost: :: |
|||
|
|||
$ sudo a2ensite MY_VHOST.com |
|||
|
|||
Create the *htpassword* file used by the configured basic authentication: :: |
|||
|
|||
$ sudo htpasswd -cb /etc/apache2/MY_VHOST.htpasswd admin admin |
|||
$ sudo htpasswd -b /etc/apache2/MY_VHOST.htpasswd demo demo |
|||
|
|||
For local test, add the *MY_VHOST.com* in your /etc/vhosts file. |
|||
|
|||
Finally reload the configuration: :: |
|||
|
|||
$ sudo service apache2 reload |
|||
|
|||
Open your browser and go to MY_VHOST.com. If everything is well configured, you are prompted |
|||
for a login and password outside OpenErp and are automatically logged in the system. |
|||
|
|||
.. [#] Based on a ubuntu 12.04 env |
|||
|
|||
""", |
|||
'author': 'Acsone SA/NV', |
|||
'maintainer': 'ACSONE SA/NV', |
|||
'website': 'http://www.acsone.eu', |
|||
'depends': ['web'], |
|||
"license": "AGPL-3", |
|||
"js": ['static/src/js/auth_from_http_remote_user.js'], |
|||
'data': [ |
|||
'res_config_view.xml', |
|||
'res_config_data.xml'], |
|||
"demo": [], |
|||
"test": [], |
|||
"active": False, |
|||
"license": "AGPL-3", |
|||
"installable": True, |
|||
"auto_install": False, |
|||
"application": False, |
|||
} |
@ -0,0 +1,22 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Author: Laurent Mignon |
|||
# Copyright 2014 'ACSONE SA/NV' |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
|
|||
from . import session |
@ -0,0 +1,129 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Author: Laurent Mignon |
|||
# Copyright 2014 'ACSONE SA/NV' |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
|
|||
from openerp import SUPERUSER_ID |
|||
|
|||
from openerp.addons.web import http |
|||
from openerp.addons.web.controllers import main |
|||
from openerp.modules.registry import RegistryManager |
|||
from .. import utils |
|||
|
|||
import random |
|||
import logging |
|||
import openerp.tools.config as config |
|||
|
|||
_logger = logging.getLogger(__name__) |
|||
|
|||
|
|||
class Session(main.Session): |
|||
_cp_path = "/web/session" |
|||
|
|||
_REQUIRED_ATTRIBUTES = ['HTTP_REMOTE_USER'] |
|||
_OPTIONAL_ATTRIBUTES = [] |
|||
|
|||
def _get_db(self, db): |
|||
if db is not None and len(db) > 0: |
|||
return db |
|||
db = config['db_name'] |
|||
if db is None or len(db) == 0: |
|||
_logger.error("No db found for SSO. Specify one in the URL using parameter " |
|||
"db=? or provide a default one in the configuration") |
|||
raise http.AuthenticationError() |
|||
|
|||
def _get_user_id_from_attributes(self, res_users, cr, attrs): |
|||
login = attrs.get('HTTP_REMOTE_USER', None) |
|||
user_ids = res_users.search(cr, SUPERUSER_ID, [('login', '=', login), ('active', '=', True)]) |
|||
assert len(user_ids) < 2 |
|||
if user_ids: |
|||
return user_ids[0] |
|||
return None |
|||
|
|||
def _get_attributes_form_header(self, req): |
|||
attrs = {} |
|||
|
|||
all_attrs = self._REQUIRED_ATTRIBUTES + self._OPTIONAL_ATTRIBUTES |
|||
|
|||
headers = req.httprequest.headers.environ |
|||
|
|||
for attr in all_attrs: |
|||
value = headers.get(attr, None) |
|||
if value is not None: |
|||
attrs[attr] = value |
|||
|
|||
attrs_found = set(attrs.keys()) |
|||
attrs_missing = set(all_attrs) - attrs_found |
|||
if len(attrs_found) > 0: |
|||
_logger.debug("Fields '%s' not found in http headers\n %s", attrs_missing, headers) |
|||
|
|||
missings = set(self._REQUIRED_ATTRIBUTES) - attrs_found |
|||
if len(missings) > 0: |
|||
_logger.error("Required fields '%s' not found in http headers\n %s", missings, headers) |
|||
return attrs |
|||
|
|||
def _bind_http_remote_user(self, req, db_name): |
|||
db_name = self._get_db(db_name) |
|||
try: |
|||
registry = RegistryManager.get(db_name) |
|||
with registry.cursor() as cr: |
|||
modules = registry.get('ir.module.module') |
|||
installed = modules.search_count(cr, SUPERUSER_ID, ['&', |
|||
('name', '=', 'auth_from_http_remote_user'), |
|||
('state', '=', 'installed')]) == 1 |
|||
if not installed: |
|||
return |
|||
config = registry.get('auth_from_http_remote_user.config.settings') |
|||
# get parameters for SSO |
|||
default_login_page_disabled = config.is_default_login_page_disabled(cr, SUPERUSER_ID, None) |
|||
|
|||
# get the user |
|||
res_users = registry.get('res.users') |
|||
attrs = self._get_attributes_form_header(req) |
|||
user_id = self._get_user_id_from_attributes(res_users, cr, attrs) |
|||
|
|||
if user_id is None: |
|||
if default_login_page_disabled: |
|||
raise http.AuthenticationError() |
|||
return |
|||
|
|||
# generate a specific key for authentication |
|||
key = randomString(utils.KEY_LENGTH, '0123456789abcdef') |
|||
res_users.write(cr, SUPERUSER_ID, [user_id], {'sso_key': key}) |
|||
login = res_users.browse(cr, SUPERUSER_ID, user_id).login |
|||
req.session.bind(db_name, user_id, login, key) |
|||
except http.AuthenticationError, e: |
|||
raise e |
|||
except Exception, e: |
|||
_logger.error("Error binding Http Remote User session", exc_info=True) |
|||
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 |
|||
|
|||
|
|||
def randomString(length, chrs): |
|||
"""Produce a string of length random bytes, chosen from chrs.""" |
|||
n = len(chrs) |
|||
return ''.join([chrs[randrange(n)] for _ in xrange(length)]) |
@ -0,0 +1,60 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Author: Laurent Mignon |
|||
# Copyright 2014 'ACSONE SA/NV' |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
|
|||
from openerp.osv import orm, fields |
|||
from openerp.tools.safe_eval import safe_eval |
|||
import types |
|||
|
|||
|
|||
class auth_from_http_remote_user_configuration(orm.TransientModel): |
|||
_name = 'auth_from_http_remote_user.config.settings' |
|||
_inherit = 'res.config.settings' |
|||
|
|||
_columns = { |
|||
'default_login_page_disabled': fields.boolean("Disable login page", |
|||
help=""" |
|||
Disable the default login page. |
|||
If the HTTP_REMOTE_HEADER field is not found or no user matches the given one, |
|||
the system will display a login error page if the login page is disabled. |
|||
Otherwise the normal login page will be displayed. |
|||
"""), |
|||
} |
|||
|
|||
def is_default_login_page_disabled(self, cr, uid, fields, context=None): |
|||
ir_config_obj = self.pool['ir.config_parameter'] |
|||
default_login_page_disabled = ir_config_obj.get_param(cr, |
|||
uid, |
|||
'auth_from_http_remote_user.default_login_page_disabled') |
|||
if isinstance(default_login_page_disabled, types.BooleanType): |
|||
return default_login_page_disabled |
|||
return safe_eval(default_login_page_disabled) |
|||
|
|||
def get_default_default_login_page_disabled(self, cr, uid, fields, context=None): |
|||
default_login_page_disabled = self.is_default_login_page_disabled(cr, uid, fields, context) |
|||
return {'default_login_page_disabled': default_login_page_disabled} |
|||
|
|||
def set_default_default_login_page_disabled(self, cr, uid, ids, context=None): |
|||
config = self.browse(cr, uid, ids[0], context) |
|||
ir_config_parameter_obj = self.pool['ir.config_parameter'] |
|||
ir_config_parameter_obj.set_param(cr, |
|||
uid, |
|||
'auth_from_http_remote_user.default_login_page_disabled', |
|||
repr(config.default_login_page_disabled)) |
@ -0,0 +1,9 @@ |
|||
<?xml version="1.0"?> |
|||
<openerp> |
|||
<data noupdate="1"> |
|||
<record model="ir.config_parameter" id="auth_from_http_remote_user.default_login_page_disabled"> |
|||
<field name="key">auth_from_http_remote_user.default_login_page_disabled</field> |
|||
<field name="value">False</field> |
|||
</record> |
|||
</data> |
|||
</openerp> |
@ -0,0 +1,39 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<data> |
|||
<record model="ir.ui.view" id="help_view_config_settings"> |
|||
<field name="name">Auth HTTP_REMOTE_USER settings</field> |
|||
<field name="model">auth_from_http_remote_user.config.settings</field> |
|||
<field name="priority" eval="20" /> |
|||
<field name="arch" type="xml"> |
|||
<form string="Configure Auth HTTP_REMOTE_USER" version="7.0" |
|||
class="oe_form_configuration"> |
|||
<header> |
|||
<header> |
|||
<button string="Apply" type="object" name="execute" class="oe_highlight"/> |
|||
or |
|||
<button string="Cancel" type="object" name="cancel" class="oe_link"/> |
|||
</header> |
|||
</header> |
|||
<separator string="Auth HTTP_REMOTE_USER" /> |
|||
<group> |
|||
<field name="default_login_page_disabled" /> |
|||
</group> |
|||
</form> |
|||
</field> |
|||
</record> |
|||
|
|||
<record model="ir.actions.act_window" id="auth_from_http_remote_user_action_config_settings"> |
|||
<field name="name">Configure Auth HTTP_REMOTE_USER</field> |
|||
<field name="type">ir.actions.act_window</field> |
|||
<field name="res_model">auth_from_http_remote_user.config.settings</field> |
|||
<field name="view_mode">form</field> |
|||
<field name="target">inline</field> |
|||
</record> |
|||
|
|||
<menuitem id="base.menu_auth_from_http_remote_user_config" name="Auth HTTP_REMOTE_USER" |
|||
parent="base.menu_config" sequence="10" |
|||
action="auth_from_http_remote_user_action_config_settings" /> |
|||
|
|||
</data> |
|||
</openerp> |
@ -0,0 +1,64 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Author: Laurent Mignon |
|||
# Copyright 2014 'ACSONE SA/NV' |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
|
|||
from openerp.modules.registry import RegistryManager |
|||
from openerp.osv import orm, fields |
|||
from openerp import SUPERUSER_ID |
|||
import openerp.exceptions |
|||
from openerp.addons.auth_from_http_remote_user import utils |
|||
|
|||
|
|||
class res_users(orm.Model): |
|||
_inherit = 'res.users' |
|||
|
|||
_columns = { |
|||
'sso_key': fields.char('SSO Key', size=utils.KEY_LENGTH, |
|||
readonly=True), |
|||
} |
|||
|
|||
def copy(self, cr, uid, rid, defaults=None, context=None): |
|||
defaults = defaults or {} |
|||
defaults['sso_key'] = False |
|||
return super(res_users, self).copy(cr, uid, rid, defaults, context) |
|||
|
|||
def check_credentials(self, cr, uid, password): |
|||
try: |
|||
return super(res_users, self).check_credentials(cr, uid, password) |
|||
except openerp.exceptions.AccessDenied: |
|||
res = self.search(cr, SUPERUSER_ID, [('id', '=', uid), ('sso_key', '=', password)]) |
|||
if not res: |
|||
raise openerp.exceptions.AccessDenied() |
|||
|
|||
def check(self, db, uid, passwd): |
|||
try: |
|||
return super(res_users, self).check(db, uid, passwd) |
|||
except openerp.exceptions.AccessDenied: |
|||
if not passwd: |
|||
raise |
|||
with RegistryManager.get(db).cursor() as cr: |
|||
cr.execute('''SELECT COUNT(1) |
|||
FROM res_users |
|||
WHERE id=%s |
|||
AND sso_key=%s |
|||
AND active=%s''', (int(uid), passwd, True)) |
|||
if not cr.fetchone()[0]: |
|||
raise |
|||
self._uid_cache.setdefault(db, {})[uid] = passwd |
@ -0,0 +1,36 @@ |
|||
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>"); |
|||
}); |
|||
} |
|||
}); |
|||
|
|||
}; |
@ -0,0 +1,28 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Author: Laurent Mignon |
|||
# Copyright 2014 'ACSONE SA/NV' |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
|
|||
from . import test_res_users |
|||
fast_suite = [ |
|||
] |
|||
|
|||
checks = [ |
|||
test_res_users, |
|||
] |
@ -0,0 +1,83 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Author: Laurent Mignon |
|||
# Copyright 2014 'ACSONE SA/NV' |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
|
|||
from openerp.tests import common |
|||
import mock |
|||
import os |
|||
from contextlib import contextmanager |
|||
import unittest |
|||
|
|||
|
|||
@contextmanager |
|||
def mock_cursor(cr): |
|||
with mock.patch('openerp.sql_db.Connection.cursor') as mocked_cursor_call: |
|||
org_close = cr.close |
|||
org_autocommit = cr.autocommit |
|||
try: |
|||
cr.close = mock.Mock() |
|||
cr.autocommit = mock.Mock() |
|||
mocked_cursor_call.return_value = cr |
|||
yield |
|||
finally: |
|||
cr.close = org_close |
|||
cr.autocommit = org_autocommit |
|||
|
|||
|
|||
class test_res_users(common.TransactionCase): |
|||
|
|||
def test_login(self): |
|||
res_users_obj = self.registry('res.users') |
|||
uid = res = res_users_obj.login(common.DB, 'admin', 'admin') |
|||
self.assertTrue(res, "Basic login must works as expected") |
|||
token = "123456" |
|||
res = res_users_obj.login(common.DB, 'admin', token) |
|||
self.assertFalse(res) |
|||
# mimic what the new controller do when it find a value in |
|||
# the http header (HTTP_REMODE_USER) |
|||
res_users_obj.write(self.cr, self.uid, uid, {'sso_key': token}) |
|||
|
|||
# Here we need to mock the cursor since the login is natively done inside |
|||
# its own connection |
|||
with mock_cursor(self.cr): |
|||
# We can verifies that the given (uid, token) is authorized for the database |
|||
res_users_obj.check(common.DB, uid, token) |
|||
|
|||
# we are able to login with the new token |
|||
res = res_users_obj.login(common.DB, 'admin', token) |
|||
self.assertTrue(res) |
|||
|
|||
@unittest.skipIf(os.environ.get('TRAVIS'), |
|||
'When run by travis, tests runs on a database with all required addons from server-tools and ' |
|||
'their dependencies installed. Even if `auth_from_http_remote_user` does not require the `mail`' |
|||
'module, The previous installation of the mail module has created the column ' |
|||
'`notification_email_send` as REQUIRED into the table res_partner. BTW, it\'s no more possible ' |
|||
'to copy a res_user without an intefirty error') |
|||
def test_copy(self): |
|||
'''Check that the sso_key is not copied on copy |
|||
''' |
|||
res_users_obj = self.registry('res.users') |
|||
vals = {'sso_key': '123'} |
|||
res_users_obj.write(self.cr, self.uid, self.uid, vals) |
|||
read_vals = res_users_obj.read(self.cr, self.uid, self.uid, ['sso_key']) |
|||
self.assertDictContainsSubset(vals, read_vals) |
|||
copy = res_users_obj.copy(self.cr, self.uid, self.uid) |
|||
read_vals = res_users_obj.read(self.cr, self.uid, copy, ['sso_key']) |
|||
self.assertFalse(read_vals.get('sso_key')) |
@ -0,0 +1,22 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################## |
|||
# |
|||
# Author: Laurent Mignon |
|||
# Copyright 2014 'ACSONE SA/NV' |
|||
# |
|||
# This program is free software: you can redistribute it and/or modify |
|||
# it under the terms of the GNU Affero General Public License as |
|||
# published by the Free Software Foundation, either version 3 of the |
|||
# License, or (at your option) any later version. |
|||
# |
|||
# This program is distributed in the hope that it will be useful, |
|||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
# GNU Affero General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU Affero General Public License |
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################## |
|||
|
|||
KEY_LENGTH = 16 |
Write
Preview
Loading…
Cancel
Save
Reference in new issue