Browse Source
auth_admin_passkey: Migrate module for odoo 10
auth_admin_passkey: Migrate module for odoo 10
Remove authenticate as check_credentials is dedicated for this purpose. Removed mail translations maybe possible in some way ? Give some space to the code Make the addon compliant to OCA guidelines Adapt readme to new template and compress header in tests Make the addon a python package NOTE: authenticate() method cannot be used in tests because a new cr is created in _login method that does not contains our user. Signed-off-by: Eugen Don <eugen.don@don-systems.de>pull/776/head
Alexandre Papin
8 years ago
15 changed files with 444 additions and 326 deletions
-
98auth_admin_passkey/README.rst
-
6auth_admin_passkey/__manifest__.py
-
22auth_admin_passkey/data/ir_config_parameter.xml
-
48auth_admin_passkey/i18n/auth_admin_passkey.pot
-
31auth_admin_passkey/models/__init__.py
-
65auth_admin_passkey/models/res_config.py
-
149auth_admin_passkey/models/res_users.py
-
26auth_admin_passkey/tests/__init__.py
-
103auth_admin_passkey/tests/test_auth_admin_passkey.py
-
171auth_admin_passkey/tests/test_ui.py
-
42auth_admin_passkey/views/res_config_view.xml
-
1setup/auth_admin_passkey/odoo/__init__.py
-
1setup/auth_admin_passkey/odoo/addons/__init__.py
-
1setup/auth_admin_passkey/odoo/addons/auth_admin_passkey
-
6setup/auth_admin_passkey/setup.py
@ -1,18 +1,80 @@ |
|||||
Admin password become a passkey for all active logins |
|
||||
===================================================== |
|
||||
|
|
||||
Functionality : |
|
||||
--------------- |
|
||||
* Administrator has now the possibility to login in with any login; |
|
||||
* By default, Odoo will send a mail to user and admin to indicate them; |
|
||||
* If a user and the admin have the same password, admin will be informed; |
|
||||
|
|
||||
Technical information : |
|
||||
----------------------- |
|
||||
* Create two ir_config_parameter to enable / disable mail sending; |
|
||||
|
|
||||
Copyright, Author and Licence : |
|
||||
------------------------------- |
|
||||
* Copyright : 2014, Groupement Régional Alimentaire de Proximité; |
|
||||
* Author : Sylvain LE GAL (https://twitter.com/legalsylvain); |
|
||||
* Licence : AGPL-3 (http://www.gnu.org/licenses/) |
|
||||
|
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg |
||||
|
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html |
||||
|
:alt: License: AGPL-3 |
||||
|
|
||||
|
==================== |
||||
|
Auth Admin - Passkey |
||||
|
==================== |
||||
|
|
||||
|
This module extends the functionality of users module to support loging in with the administrator password |
||||
|
in other user accounts. |
||||
|
|
||||
|
* Administrator has now the possibility to login in with any login; |
||||
|
* By default, Odoo will send a mail to user and admin to indicate them; |
||||
|
* If a user and the admin have the same password, admin will be informed; |
||||
|
|
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
|
||||
|
To enable notifications for login attempts, you need to: |
||||
|
|
||||
|
Go to Settings > General Settings. |
||||
|
|
||||
|
Enable the "Send email to admin user" and / or "Send email to user" checkbox |
||||
|
|
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
To login into a different user account type in the user name of the account and the password of the administrator at the login screen |
||||
|
|
||||
|
|
||||
|
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
||||
|
:alt: Try me on Runbot |
||||
|
:target: https://runbot.odoo-community.org/runbot/149/10.0 |
||||
|
|
||||
|
|
||||
|
Known issues / Roadmap |
||||
|
====================== |
||||
|
|
||||
|
None |
||||
|
|
||||
|
Bug Tracker |
||||
|
=========== |
||||
|
|
||||
|
Bugs are tracked on `GitHub Issues |
||||
|
<https://github.com/OCA/server-tools/issues>`_. In case of trouble, please |
||||
|
check there if your issue has already been reported. If you spotted it first, |
||||
|
help us smash it by providing detailed and welcomed feedback. |
||||
|
|
||||
|
Credits |
||||
|
======= |
||||
|
|
||||
|
Images |
||||
|
------ |
||||
|
|
||||
|
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_. |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
|
||||
|
* Eugen Don <eugen.don@don-systems.de> |
||||
|
* Alexandre Papin (https://twitter.com/Fenkiou) |
||||
|
* Sylvain LE GAL (https://twitter.com/legalsylvain) |
||||
|
|
||||
|
|
||||
|
Maintainer |
||||
|
---------- |
||||
|
|
||||
|
.. image:: https://odoo-community.org/logo.png |
||||
|
:alt: Odoo Community Association |
||||
|
:target: https://odoo-community.org |
||||
|
|
||||
|
This module is maintained by the OCA. |
||||
|
|
||||
|
OCA, or the Odoo Community Association, is a nonprofit organization whose |
||||
|
mission is to support the collaborative development of Odoo features and |
||||
|
promote its widespread use. |
||||
|
|
||||
|
To contribute to this module, please visit https://odoo-community.org. |
@ -1,24 +1,9 @@ |
|||||
# -*- encoding: utf-8 -*- |
|
||||
############################################################################## |
|
||||
# |
|
||||
# Admin Passkey module for Odoo |
|
||||
# Copyright (C) 2013-2014 GRAP (http://www.grap.coop) |
|
||||
# @author Sylvain LE GAL (https://twitter.com/legalsylvain) |
|
||||
# |
|
||||
# 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/>. |
|
||||
# |
|
||||
############################################################################## |
|
||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright (C) 2013-2014 GRAP (http://www.grap.coop) |
||||
|
# @author Sylvain LE GAL (https://twitter.com/legalsylvain) |
||||
|
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html |
||||
|
|
||||
from . import res_config |
|
||||
from . import res_users |
|
||||
|
from . import ( |
||||
|
res_config, |
||||
|
res_users, |
||||
|
) |
@ -1,23 +1,7 @@ |
|||||
# -*- encoding: utf-8 -*- |
|
||||
############################################################################## |
|
||||
# |
|
||||
# Admin Passkey module for Odoo |
|
||||
# Copyright (C) 2013-2014 GRAP (http://www.grap.coop) |
|
||||
# @author Sylvain LE GAL (https://twitter.com/legalsylvain) |
|
||||
# |
|
||||
# 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/>. |
|
||||
# |
|
||||
############################################################################## |
|
||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright (C) 2013-2014 GRAP (http://www.grap.coop) |
||||
|
# @author Sylvain LE GAL (https://twitter.com/legalsylvain) |
||||
|
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html |
||||
|
|
||||
from . import test_auth_admin_passkey |
from . import test_auth_admin_passkey |
||||
|
from . import test_ui |
@ -0,0 +1,171 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright (C) 2013-2014 GRAP (http://www.grap.coop) |
||||
|
# @author Sylvain LE GAL (https://twitter.com/legalsylvain) |
||||
|
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html |
||||
|
|
||||
|
from lxml import html |
||||
|
|
||||
|
from werkzeug.test import Client |
||||
|
from werkzeug.wrappers import BaseResponse |
||||
|
|
||||
|
from odoo.tests import common |
||||
|
from odoo.service import wsgi_server |
||||
|
|
||||
|
|
||||
|
@common.post_install(True) |
||||
|
class TestUI(common.HttpCase): |
||||
|
|
||||
|
def setUp(self): |
||||
|
super(TestUI, self).setUp() |
||||
|
|
||||
|
with self.registry.cursor() as test_cursor: |
||||
|
env = self.env(test_cursor) |
||||
|
|
||||
|
self.admin_password = 'AdminPa$$w0rd' |
||||
|
env.ref('base.user_root').password = self.admin_password |
||||
|
self.passkey_password = 'PasskeyPa$$w0rd' |
||||
|
self.passkey_user = env['res.users'].create({ |
||||
|
'name': 'passkey', |
||||
|
'login': 'passkey', |
||||
|
'email': 'passkey', |
||||
|
'password': self.passkey_password |
||||
|
}) |
||||
|
self.dbname = env.cr.dbname |
||||
|
|
||||
|
self.werkzeug_environ = {'REMOTE_ADDR': '127.0.0.1'} |
||||
|
self.test_client = Client(wsgi_server.application, BaseResponse) |
||||
|
self.test_client.get('/web/session/logout') |
||||
|
|
||||
|
def html_doc(self, response): |
||||
|
"""Get an HTML LXML document.""" |
||||
|
return html.fromstring(response.data) |
||||
|
|
||||
|
def csrf_token(self, response): |
||||
|
"""Get a valid CSRF token.""" |
||||
|
doc = self.html_doc(response) |
||||
|
return doc.xpath("//input[@name='csrf_token']")[0].get('value') |
||||
|
|
||||
|
def get_request(self, url, data=None): |
||||
|
return self.test_client.get( |
||||
|
url, query_string=data, follow_redirects=True) |
||||
|
|
||||
|
def post_request(self, url, data=None): |
||||
|
return self.test_client.post( |
||||
|
url, data=data, follow_redirects=True, |
||||
|
environ_base=self.werkzeug_environ) |
||||
|
|
||||
|
def test_01_normal_login_admin_succeed(self): |
||||
|
# Our admin user wants to go to backoffice part of Odoo |
||||
|
response = self.get_request('/web/', data={'db': self.dbname}) |
||||
|
|
||||
|
# He notices that his redirected to login page as not authenticated |
||||
|
self.assertIn('oe_login_form', response.data) |
||||
|
|
||||
|
# He needs to enters his credentials and submit the form |
||||
|
data = { |
||||
|
'login': 'admin', |
||||
|
'password': self.admin_password, |
||||
|
'csrf_token': self.csrf_token(response), |
||||
|
'db': self.dbname |
||||
|
} |
||||
|
response = self.post_request('/web/login/', data=data) |
||||
|
|
||||
|
# He notices that his redirected to backoffice |
||||
|
self.assertNotIn('oe_login_form', response.data) |
||||
|
|
||||
|
def test_02_normal_login_admin_fail(self): |
||||
|
# Our admin user wants to go to backoffice part of Odoo |
||||
|
response = self.get_request('/web/', data={'db': self.dbname}) |
||||
|
|
||||
|
# He notices that he's redirected to login page as not authenticated |
||||
|
self.assertIn('oe_login_form', response.data) |
||||
|
|
||||
|
# He needs to enter his credentials and submit the form |
||||
|
data = { |
||||
|
'login': 'admin', |
||||
|
'password': 'password', |
||||
|
'csrf_token': self.csrf_token(response), |
||||
|
'db': self.dbname |
||||
|
} |
||||
|
response = self.post_request('/web/login/', data=data) |
||||
|
|
||||
|
# He mistyped his password so he's redirected to login page again |
||||
|
self.assertIn('Wrong login/password', response.data) |
||||
|
|
||||
|
def test_03_normal_login_passkey_succeed(self): |
||||
|
# Our passkey user wants to go to backoffice part of Odoo |
||||
|
response = self.get_request('/web/', data={'db': self.dbname}) |
||||
|
|
||||
|
# He notices that he's redirected to login page as not authenticated |
||||
|
self.assertIn('oe_login_form', response.data) |
||||
|
|
||||
|
# He needs to enter his credentials and submit the form |
||||
|
data = { |
||||
|
'login': self.passkey_user.login, |
||||
|
'password': self.passkey_password, |
||||
|
'csrf_token': self.csrf_token(response), |
||||
|
'db': self.dbname |
||||
|
} |
||||
|
response = self.post_request('/web/login/', data=data) |
||||
|
|
||||
|
# He notices that his redirected to backoffice |
||||
|
self.assertNotIn('oe_login_form', response.data) |
||||
|
|
||||
|
def test_04_normal_login_passkey_fail(self): |
||||
|
# Our passkey user wants to go to backoffice part of Odoo |
||||
|
response = self.get_request('/web/', data={'db': self.dbname}) |
||||
|
|
||||
|
# He notices that he's redirected to login page as not authenticated |
||||
|
self.assertIn('oe_login_form', response.data) |
||||
|
|
||||
|
# He needs to enter his credentials and submit the form |
||||
|
data = { |
||||
|
'login': self.passkey_user.login, |
||||
|
'password': 'password', |
||||
|
'csrf_token': self.csrf_token(response), |
||||
|
'db': self.dbname |
||||
|
} |
||||
|
response = self.post_request('/web/login/', data=data) |
||||
|
|
||||
|
# He mistyped his password so he's redirected to login page again |
||||
|
self.assertIn('Wrong login/password', response.data) |
||||
|
|
||||
|
def test_05_passkey_login_with_admin_password_succeed(self): |
||||
|
# Our admin user wants to login as passkey user |
||||
|
response = self.get_request('/web/', data={'db': self.dbname}) |
||||
|
|
||||
|
# He notices that his redirected to login page as not authenticated |
||||
|
self.assertIn('oe_login_form', response.data) |
||||
|
|
||||
|
# He needs to enters its password with passkey user's login |
||||
|
data = { |
||||
|
'login': self.passkey_user.login, |
||||
|
'password': self.admin_password, |
||||
|
'csrf_token': self.csrf_token(response), |
||||
|
'db': self.dbname |
||||
|
} |
||||
|
response = self.post_request('/web/login/', data=data) |
||||
|
|
||||
|
# He notices that his redirected to backoffice |
||||
|
self.assertNotIn('oe_login_form', response.data) |
||||
|
|
||||
|
def test_06_passkey_login_with_same_password_as_admin(self): |
||||
|
self.passkey_user.password = self.admin_password |
||||
|
|
||||
|
# Our passkey user wants to go to backoffice part of Odoo |
||||
|
response = self.get_request('/web/', data={'db': self.dbname}) |
||||
|
|
||||
|
# He notices that his redirected to login page as not authenticated |
||||
|
self.assertIn('oe_login_form', response.data) |
||||
|
|
||||
|
# He needs to enters his credentials and submit the form |
||||
|
data = { |
||||
|
'login': self.passkey_user.login, |
||||
|
'password': self.admin_password, |
||||
|
'csrf_token': self.csrf_token(response), |
||||
|
'db': self.dbname |
||||
|
} |
||||
|
response = self.post_request('/web/login/', data=data) |
||||
|
|
||||
|
# He notices that his redirected to backoffice |
||||
|
self.assertNotIn('oe_login_form', response.data) |
@ -1,47 +1,27 @@ |
|||||
<?xml version="1.0" encoding="UTF-8"?> |
<?xml version="1.0" encoding="UTF-8"?> |
||||
<!-- ********************************************************************** --> |
|
||||
<!--Admin Passkey module for Odoo --> |
|
||||
<!--Copyright (C) 2013-2014 GRAP (http://www.grap.coop) --> |
|
||||
<!--@author Sylvain LE GAL (https://twitter.com/legalsylvain) --> |
|
||||
|
|
||||
<!--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/>. --> |
|
||||
<!-- ********************************************************************** --> |
|
||||
<openerp> |
|
||||
<data> |
|
||||
|
<odoo> |
||||
|
|
||||
<record id="view_res_config_settings" model="ir.ui.view"> |
<record id="view_res_config_settings" model="ir.ui.view"> |
||||
<field name="name">base.config.settings.view</field> |
<field name="name">base.config.settings.view</field> |
||||
<field name="model">base.config.settings</field> |
<field name="model">base.config.settings</field> |
||||
<field name="inherit_id" ref="base_setup.view_general_configuration"/> |
<field name="inherit_id" ref="base_setup.view_general_configuration"/> |
||||
<field name="arch" type="xml"> |
<field name="arch" type="xml"> |
||||
<xpath expr="//label[@string='Email']/.." position='after'> |
|
||||
|
<xpath expr="//label[@name='email_label']/.." position='after'> |
||||
<group> |
<group> |
||||
<label for="id" string="Passkey"/> |
<label for="id" string="Passkey"/> |
||||
<div> |
<div> |
||||
<div> |
|
||||
<field name="auth_admin_passkey_send_to_admin" class="oe_inline"/> |
|
||||
<label for="auth_admin_passkey_send_to_admin"/> |
|
||||
</div> |
|
||||
<div> |
|
||||
<field name="auth_admin_passkey_send_to_user" class="oe_inline"/> |
|
||||
<label for="auth_admin_passkey_send_to_user"/> |
|
||||
</div> |
|
||||
|
<div> |
||||
|
<field name="auth_admin_passkey_send_to_admin" class="oe_inline"/> |
||||
|
<label for="auth_admin_passkey_send_to_admin"/> |
||||
|
</div> |
||||
|
<div> |
||||
|
<field name="auth_admin_passkey_send_to_user" class="oe_inline"/> |
||||
|
<label for="auth_admin_passkey_send_to_user"/> |
||||
|
</div> |
||||
</div> |
</div> |
||||
</group> |
</group> |
||||
</xpath> |
</xpath> |
||||
</field> |
</field> |
||||
</record> |
</record> |
||||
|
|
||||
</data> |
|
||||
</openerp> |
|
||||
|
</odoo> |
@ -0,0 +1 @@ |
|||||
|
__import__('pkg_resources').declare_namespace(__name__) |
@ -0,0 +1 @@ |
|||||
|
__import__('pkg_resources').declare_namespace(__name__) |
@ -0,0 +1 @@ |
|||||
|
../../../../auth_admin_passkey |
@ -0,0 +1,6 @@ |
|||||
|
import setuptools |
||||
|
|
||||
|
setuptools.setup( |
||||
|
setup_requires=['setuptools-odoo'], |
||||
|
odoo_addon=True, |
||||
|
) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue