From f2610b09b6acf978c5dea13ef33630eb33d15d00 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Mon, 17 Mar 2014 16:41:20 +0100 Subject: [PATCH] [ADD] new module 'auth_admin_passkey' that allow admin user (uid=1) to login with any login and his password. --- auth_admin_passkey/__init__.py | 6 ++ auth_admin_passkey/__openerp__.py | 63 ++++++++++++++++ .../data/ir_config_parameter.xml | 16 ++++ auth_admin_passkey/i18n/fr.po | 42 +++++++++++ auth_admin_passkey/model/__init__.py | 7 ++ auth_admin_passkey/model/res_config.py | 48 ++++++++++++ auth_admin_passkey/model/res_users.py | 71 ++++++++++++++++++ auth_admin_passkey/static/src/img/icon.png | Bin 0 -> 4113 bytes auth_admin_passkey/view/res_config_view.xml | 29 +++++++ 9 files changed, 282 insertions(+) create mode 100644 auth_admin_passkey/__init__.py create mode 100644 auth_admin_passkey/__openerp__.py create mode 100644 auth_admin_passkey/data/ir_config_parameter.xml create mode 100644 auth_admin_passkey/i18n/fr.po create mode 100644 auth_admin_passkey/model/__init__.py create mode 100644 auth_admin_passkey/model/res_config.py create mode 100644 auth_admin_passkey/model/res_users.py create mode 100644 auth_admin_passkey/static/src/img/icon.png create mode 100644 auth_admin_passkey/view/res_config_view.xml diff --git a/auth_admin_passkey/__init__.py b/auth_admin_passkey/__init__.py new file mode 100644 index 000000000..12135a333 --- /dev/null +++ b/auth_admin_passkey/__init__.py @@ -0,0 +1,6 @@ +# -*- encoding: utf-8 -*- +################################################################################ +# See __openerp__.py file for Copyright and Licence Informations. +################################################################################ + +import model diff --git a/auth_admin_passkey/__openerp__.py b/auth_admin_passkey/__openerp__.py new file mode 100644 index 000000000..dd9e30ac6 --- /dev/null +++ b/auth_admin_passkey/__openerp__.py @@ -0,0 +1,63 @@ +# -*- encoding: utf-8 -*- +################################################################################ +# See Copyright and Licence Informations undermentioned. +################################################################################ + +{ + 'name': 'Authentification - Admin Passkey', + 'version': '2.1', + 'category': 'base', + 'description': """ +Admin password become a passkey for all active logins +===================================================== + +Functionnalities : +------------------ + * Administrator has now the possibility to login in with any login; + * By default, OpenERP will send a mail to user and admin to indicate them; + +Technical informations : +------------------------ + * Create two ir_config_parameter to enable / disable mail sending; + +Limits : +-------- + * For the moment, this module doesn't manage translations for the mails; + * This module is compatible with 'auth_crypt' depending of the order of the installation: + * if 'auth_crypt' is first installed, it will work; + * if 'auth_admin_passkey' is first installed, it won't work; +If you want to install 'auth_crypt', please uninstall 'auth_admin_passkey' and +reinstall it after the installation of 'auth_crypt'. + +Otherwise, you can propose the merge of a glue module that manage this case. + +Copyright and Licence : +----------------------- + * 2014, Groupement Régional Alimentaire de Proximité + * Licence : AGPL-3 (http://www.gnu.org/licenses/) + +Contacts : +---------- + * Sylvain LE GAL (https://twitter.com/legalsylvain); + * for any help or question about this module. + """, + 'author': 'GRAP', + 'website': 'http://www.grap.coop', + 'license': 'AGPL-3', + 'depends': [ + 'mail', + ], + 'data': [ + 'data/ir_config_parameter.xml', + 'view/res_config_view.xml', + ], + 'demo': [], + 'js': [], + 'css': [], + 'qweb': [], + 'images': [], + 'post_load': '', + 'application': False, + 'installable': True, + 'auto_install': False, +} diff --git a/auth_admin_passkey/data/ir_config_parameter.xml b/auth_admin_passkey/data/ir_config_parameter.xml new file mode 100644 index 000000000..6cb75828c --- /dev/null +++ b/auth_admin_passkey/data/ir_config_parameter.xml @@ -0,0 +1,16 @@ + + + + + + auth_admin_passkey.send_to_admin + True + + + + auth_admin_passkey.send_to_user + True + + + + diff --git a/auth_admin_passkey/i18n/fr.po b/auth_admin_passkey/i18n/fr.po new file mode 100644 index 000000000..c352d40a5 --- /dev/null +++ b/auth_admin_passkey/i18n/fr.po @@ -0,0 +1,42 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * auth_admin_passkey +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 7.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-03-17 12:04+0000\n" +"PO-Revision-Date: 2014-03-17 12:04+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: auth_admin_passkey +#: view:base.config.settings:0 +msgid "Passkey" +msgstr "Mot de passe bris de glace" + +#. module: auth_admin_passkey +#: field:base.config.settings,auth_admin_passkey_send_to_admin:0 +msgid "Send email to admin user." +msgstr "Envoyer un email à l'administrateur." + +#. module: auth_admin_passkey +#: help:base.config.settings,auth_admin_passkey_send_to_user:0 +msgid "When the administrator use his password to login in with a different account, OpenERP will send an email to the account user." +msgstr "Quand l'administrateur utilise son mot de passe pour s'authentifier avec un compte différent, OpenERP lui enverra un mail." + +#. module: auth_admin_passkey +#: help:base.config.settings,auth_admin_passkey_send_to_admin:0 +msgid "When the administrator use his password to login in with a different account, OpenERP will send an email to the admin user." +msgstr "Quand l'administrateur utilise son mot de passe pour s'authentifier avec un compte différent, OpenERP enverra un mail à l'utilisateur." + +#. module: auth_admin_passkey +#: field:base.config.settings,auth_admin_passkey_send_to_user:0 +msgid "Send email to user." +msgstr "Envoyer un email à l'utilisateur." + diff --git a/auth_admin_passkey/model/__init__.py b/auth_admin_passkey/model/__init__.py new file mode 100644 index 000000000..c672ffa17 --- /dev/null +++ b/auth_admin_passkey/model/__init__.py @@ -0,0 +1,7 @@ +# -*- encoding: utf-8 -*- +################################################################################ +# See __openerp__.py file for Copyright and Licence Informations. +################################################################################ + +import res_config +import res_users diff --git a/auth_admin_passkey/model/res_config.py b/auth_admin_passkey/model/res_config.py new file mode 100644 index 000000000..53e5d99b9 --- /dev/null +++ b/auth_admin_passkey/model/res_config.py @@ -0,0 +1,48 @@ +# -*- encoding: utf-8 -*- +################################################################################ +# See __openerp__.py file for Copyright and Licence Informations. +################################################################################ + +from openerp.osv import fields +from openerp.osv.orm import TransientModel +from openerp.tools.safe_eval import safe_eval + +class base_config_settings(TransientModel): + _inherit = 'base.config.settings' + + ### Getter / Setter Section + def get_default_auth_admin_passkey_send_to_admin(self, cr, uid, ids, context=None): + icp = self.pool.get('ir.config_parameter') + return { + 'auth_admin_passkey_send_to_admin' : safe_eval(icp.get_param(cr, uid, 'auth_admin_passkey.send_to_admin', 'True')), + } + + def set_auth_admin_passkey_send_to_admin(self, cr, uid, ids, context=None): + config = self.browse(cr, uid, ids[0], context=context) + icp = self.pool.get('ir.config_parameter') + icp.set_param(cr, uid, 'auth_admin_passkey.send_to_admin', repr(config.auth_admin_passkey_send_to_admin)) + + def get_default_auth_admin_passkey_send_to_user(self, cr, uid, ids, context=None): + icp = self.pool.get('ir.config_parameter') + return { + 'auth_admin_passkey_send_to_user' : safe_eval(icp.get_param(cr, uid, 'auth_admin_passkey.send_to_user', 'True')), + } + + def set_auth_admin_passkey_send_to_user(self, cr, uid, ids, context=None): + config = self.browse(cr, uid, ids[0], context=context) + icp = self.pool.get('ir.config_parameter') + icp.set_param(cr, uid, 'auth_admin_passkey.send_to_user', repr(config.auth_admin_passkey_send_to_user)) + + ### Columns Section + _columns = { + 'auth_admin_passkey_send_to_admin': fields.boolean( + 'Send email to admin user.', + help="When the administrator use his password to login in with "\ + "a different account, OpenERP will send an email to the admin user.", + ), + 'auth_admin_passkey_send_to_user': fields.boolean( + string='Send email to user.', + help="When the administrator use his password to login in with "\ + "a different account, OpenERP will send an email to the account user.", + ), + } diff --git a/auth_admin_passkey/model/res_users.py b/auth_admin_passkey/model/res_users.py new file mode 100644 index 000000000..9cc6599dc --- /dev/null +++ b/auth_admin_passkey/model/res_users.py @@ -0,0 +1,71 @@ +# -*- encoding: utf-8 -*- +################################################################################ +# See __openerp__.py file for Copyright and Licence Informations. +################################################################################ + +import datetime +from ast import literal_eval + +from openerp import SUPERUSER_ID +from openerp import pooler +from openerp import exceptions +from openerp.osv.orm import Model + +class res_users(Model): + _inherit = "res.users" + + ### Private Function section + def _send_email_passkey(self, cr, user_id, user_agent_env): + """ Send a email to the admin of the system to inform passkey use """ + mail_obj = self.pool.get('mail.mail') + icp_obj = self.pool.get('ir.config_parameter') + admin_user = self.browse(cr, SUPERUSER_ID, SUPERUSER_ID) + login_user = self.browse(cr, SUPERUSER_ID, user_id) + send_to_admin = literal_eval(icp_obj.get_param(cr, SUPERUSER_ID, + 'auth_admin_passkey.send_to_admin', 'True')) + send_to_user = literal_eval(icp_obj.get_param(cr, SUPERUSER_ID, + 'auth_admin_passkey.send_to_user', 'True')) + emails_to = [] + if send_to_admin and admin_user.email: + emails_to.append(admin_user.email) + if send_to_user and login_user.email: + emails_to.append(login_user.email) + if emails_to: + body = "Admin user used his passkey to login with '%s'.\n\n" %(login_user.login) + body += "\n\nTechnicals informations belows : \n\n" + body += "- Login date : %s\n\n" %(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")) + for key, value in user_agent_env.iteritems(): + body +=("- %s : %s\n\n") % (key, value) + for email_to in emails_to: + mail_obj.create(cr, SUPERUSER_ID, { + 'email_to': email_to, + 'subject': "Passkey used", + 'body_html': '
%s
' % body}) + + ### Overload Section + def authenticate(self, db, login, password, user_agent_env): + """ Authenticate the user 'login' is password is ok + or if is admin password. In the second case, send mail to user and admin.""" + user_id = super(res_users, self).authenticate(db, login, password, user_agent_env) + cr = pooler.get_db(db).cursor() + try: + # directly use parent 'check_credentials' function + # to really know if credentials are ok and if it's admin password + super(res_users, self).check_credentials(cr, SUPERUSER_ID, password) + if user_id != SUPERUSER_ID: + self._send_email_passkey(cr, user_id, user_agent_env) + cr.commit() + except exceptions.AccessDenied: + pass + finally: + cr.close() + return user_id + + def check_credentials(self, cr, uid, password): + """ Return now True if credentials are good OR if password is admin password""" + try: + super(res_users, self).check_credentials(cr, SUPERUSER_ID, password) + return True + except exceptions.AccessDenied: + return super(res_users, self).check_credentials(cr, uid, password) + diff --git a/auth_admin_passkey/static/src/img/icon.png b/auth_admin_passkey/static/src/img/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..490879d9f495397f83d08b90e1cdae22725ba6d0 GIT binary patch literal 4113 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 + + + + + base.config.settings.view + base.config.settings + + + + + + + + + + +