diff --git a/auth_admin_passkey/__init__.py b/auth_admin_passkey/__init__.py
index 088e71f64..6751b2be1 100644
--- a/auth_admin_passkey/__init__.py
+++ b/auth_admin_passkey/__init__.py
@@ -1,23 +1,6 @@
-# -*- encoding: utf-8 -*-
-##############################################################################
-#
-# Admin Passkey module for OpenERP
-# 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
%s' % body}) - - def _send_email_same_password(self, cr, login_user): - """ Send a email to the admin user to inform that another user has the - same password as him.""" - mail_obj = self.pool['mail.mail'] - admin_user = self.browse(cr, SUPERUSER_ID, SUPERUSER_ID) - if admin_user.email: - mail_obj.create(cr, SUPERUSER_ID, { - 'email_to': admin_user.email, - 'subject': self._get_translation( - cr, admin_user.lang, _('[WARNING] OpenERP Security Risk')), - 'body_html': self._get_translation( - cr, admin_user.lang, _( - """
User with login '%s' has the same """ - """password as you.""")) % (login_user), - }) - - # 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) - if user_id and (user_id != SUPERUSER_ID): - same_password = False - cr = pooler.get_db(db).cursor() - try: - # directly use parent 'check_credentials' function - # to really know if credentials are ok - # or if it was admin password - super(res_users, self).check_credentials( - cr, SUPERUSER_ID, password) - try: - # Test now if the user has the same password as admin user - super(res_users, self).check_credentials( - cr, user_id, password) - same_password = True - except exceptions.AccessDenied: - pass - if not same_password: - self._send_email_passkey(cr, user_id, user_agent_env) - else: - self._send_email_same_password(cr, login) - 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.""" - if uid != SUPERUSER_ID: - try: - super(res_users, self).check_credentials( - cr, uid, password) - return True - except exceptions.AccessDenied: - return self.check_credentials(cr, SUPERUSER_ID, password) - else: - return super(res_users, self).check_credentials(cr, uid, password) diff --git a/auth_admin_passkey/model/__init__.py b/auth_admin_passkey/models/__init__.py similarity index 100% rename from auth_admin_passkey/model/__init__.py rename to auth_admin_passkey/models/__init__.py diff --git a/auth_admin_passkey/models/res_config.py b/auth_admin_passkey/models/res_config.py new file mode 100644 index 000000000..62c34d287 --- /dev/null +++ b/auth_admin_passkey/models/res_config.py @@ -0,0 +1,53 @@ +# -*- 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 openerp import api, fields, models + + +class BaseConfigSettings(models.TransientModel): + _inherit = 'base.config.settings' + + # Getter / Setter Section + @api.model + def get_default_auth_admin_passkey_send_to_admin(self, fields): + return { + 'auth_admin_passkey_send_to_admin': + self.env["ir.config_parameter"].get_param( + "auth_admin_passkey.send_to_admin") + } + + @api.multi + def set_auth_admin_passkey_send_to_admin(self): + for config in self: + self.env['ir.config_parameter'].set_param( + "auth_admin_passkey.send_to_admin", + config.auth_admin_passkey_send_to_admin or '') + + @api.model + def get_default_auth_admin_passkey_send_to_user(self, fields): + return { + 'auth_admin_passkey_send_to_user': + self.env["ir.config_parameter"].get_param( + "auth_admin_passkey.send_to_user") + } + + @api.multi + def set_auth_admin_passkey_send_to_user(self): + for config in self: + self.env['ir.config_parameter'].set_param( + "auth_admin_passkey.send_to_user", + config.auth_admin_passkey_send_to_user or '') + + auth_admin_passkey_send_to_admin = fields.Boolean( + string='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/models/res_users.py b/auth_admin_passkey/models/res_users.py new file mode 100644 index 000000000..e2495143e --- /dev/null +++ b/auth_admin_passkey/models/res_users.py @@ -0,0 +1,118 @@ +# -*- 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 + +import datetime + +from openerp import _, api, exceptions, models, registry, SUPERUSER_ID +from openerp.tools.safe_eval import safe_eval + + +class ResUsers(models.Model): + _inherit = "res.users" + + def _get_translation(self, lang, text): + context = {'lang': lang} # noqa: _() checks page for locals + return _(text) + + @api.model + def _send_email_passkey(self, user_agent_env): + """ Send a email to the admin of the system and / or the user + to inform passkey use.""" + mails = [] + mail_obj = self.env['mail.mail'] + icp_obj = self.env['ir.config_parameter'] + admin_user = self.sudo().browse(SUPERUSER_ID) + login_user = self.sudo().browse(self.env.uid) + send_to_admin = safe_eval(icp_obj.sudo().get_param( + 'auth_admin_passkey.send_to_admin', + 'True')) + send_to_user = safe_eval(icp_obj.sudo().get_param( + 'auth_admin_passkey.send_to_user', + 'True')) + + if send_to_admin and admin_user.email: + mails.append({'email': admin_user.email, 'lang': admin_user.lang}) + if send_to_user and login_user.email: + mails.append({'email': login_user.email, 'lang': login_user.lang}) + for mail in mails: + subject = self._get_translation( + mail['lang'], _('Passkey used')) + body = self._get_translation( + mail['lang'], + _("""Admin user used his passkey to login with '%s'.\n\n""" + """\n\nTechnicals informations belows : \n\n""" + """- Login date : %s\n\n""")) % ( + login_user.login, + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")) + for k, v in user_agent_env.iteritems(): + body += ("- %s : %s\n\n") % (k, v) + mail = mail_obj.sudo().create({ + 'email_to': mail['email'], + 'subject': subject, + 'body_html': '
%s' % body}) + mail.send(auto_commit=True) + + @api.cr + def _send_email_same_password(self, login_user): + """ Send a email to the admin user to inform that another user has the + same password as him.""" + mail_obj = self.env['mail.mail'] + admin_user = self.sudo().browse(SUPERUSER_ID) + if admin_user.email: + mail = mail_obj.sudo().create({ + 'email_to': admin_user.email, + 'subject': self._get_translation( + admin_user.lang, _('[WARNING] OpenERP Security Risk')), + 'body_html': self._get_translation( + admin_user.lang, _( + """
User with login '%s' has the same """ + """password as you.""")) % (login_user), + }) + mail.send(auto_commit=True) + + # 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(ResUsers, self).authenticate( + db, login, password, user_agent_env) + if user_id and (user_id != SUPERUSER_ID): + same_password = False + cr = registry(db).cursor() + try: + # directly use parent 'check_credentials' function + # to really know if credentials are ok + # or if it was admin password + super(ResUsers, self).check_credentials( + cr, SUPERUSER_ID, password) + try: + # Test now if the user has the same password as admin user + super(ResUsers, self).check_credentials( + cr, user_id, password) + same_password = True + except exceptions.AccessDenied: + pass + if not same_password: + self._send_email_passkey(cr, user_id, user_agent_env) + else: + self._send_email_same_password(cr, login) + except exceptions.AccessDenied: + pass + finally: + cr.close() + return user_id + + @api.model + def check_credentials(self, password): + """ Return now True if credentials are good OR if password is admin +password.""" + if self.env.uid != SUPERUSER_ID: + try: + super(ResUsers, self).check_credentials(password) + return True + except exceptions.AccessDenied: + return self.sudo().check_credentials(password) + else: + return super(ResUsers, self).check_credentials(password) diff --git a/auth_admin_passkey/tests/test_auth_admin_passkey.py b/auth_admin_passkey/tests/test_auth_admin_passkey.py index 2ce02d26c..2f0edaf9d 100644 --- a/auth_admin_passkey/tests/test_auth_admin_passkey.py +++ b/auth_admin_passkey/tests/test_auth_admin_passkey.py @@ -1,24 +1,7 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# Admin Passkey module for OpenERP -# 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