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 . -# -############################################################################## +# -*- 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 model +from . import models diff --git a/auth_admin_passkey/__manifest__.py b/auth_admin_passkey/__manifest__.py index 69b7c8b1c..2122d131f 100644 --- a/auth_admin_passkey/__manifest__.py +++ b/auth_admin_passkey/__manifest__.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 . -# -############################################################################## +# -*- 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 { 'name': 'Authentification - Admin Passkey', @@ -32,7 +15,7 @@ ], 'data': [ 'data/ir_config_parameter.xml', - 'view/res_config_view.xml', + 'views/res_config_view.xml', ], 'demo': [], 'js': [], diff --git a/auth_admin_passkey/model/res_config.py b/auth_admin_passkey/model/res_config.py deleted file mode 100644 index 11c7fa083..000000000 --- a/auth_admin_passkey/model/res_config.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- 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 . -# -############################################################################## - -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['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['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['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['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 deleted file mode 100644 index d0a5a8aa2..000000000 --- a/auth_admin_passkey/model/res_users.py +++ /dev/null @@ -1,137 +0,0 @@ -# -*- 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 . -# -############################################################################## - -import datetime - -from openerp import SUPERUSER_ID -from openerp import pooler -from openerp import exceptions -from openerp.osv.orm import Model -from openerp.tools.translate import _ -from openerp.tools.safe_eval import safe_eval - - -class res_users(Model): - _inherit = "res.users" - - # Private Function section - def _get_translation(self, cr, lang, text): - context = {'lang': lang} # noqa: _() checks page for locals - return _(text) - - def _send_email_passkey(self, cr, user_id, user_agent_env): - """ Send a email to the admin of the system and / or the user - to inform passkey use.""" - mails = [] - mail_obj = self.pool['mail.mail'] - icp_obj = self.pool['ir.config_parameter'] - admin_user = self.browse(cr, SUPERUSER_ID, SUPERUSER_ID) - login_user = self.browse(cr, SUPERUSER_ID, user_id) - send_to_admin = safe_eval(icp_obj.get_param( - cr, SUPERUSER_ID, 'auth_admin_passkey.send_to_admin', 'True')) - send_to_user = safe_eval(icp_obj.get_param( - cr, SUPERUSER_ID, '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( - cr, mail['lang'], _('Passkey used')) - body = self._get_translation( - cr, 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_obj.create( - cr, SUPERUSER_ID, { - 'email_to': mail['email'], - 'subject': subject, - 'body_html': '
%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 . -# -############################################################################## +# -*- 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 threading diff --git a/auth_admin_passkey/view/res_config_view.xml b/auth_admin_passkey/views/res_config_view.xml similarity index 100% rename from auth_admin_passkey/view/res_config_view.xml rename to auth_admin_passkey/views/res_config_view.xml