Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[9.0] MIG auth admin passkey #678

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 5 additions & 21 deletions auth_admin_passkey/__init__.py
Original file line number Diff line number Diff line change
@@ -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 model
35 changes: 9 additions & 26 deletions auth_admin_passkey/__openerp__.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,19 @@
# -*- 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


{
'name': 'Authentification - Admin Passkey',
'version': '8.0.2.1.1',
'name': 'Authentication - Admin Passkey',
'version': '9.0.1.0.0',
'category': 'base',
'author': "GRAP,Odoo Community Association (OCA)",
'website': 'http://www.grap.coop',
'license': 'AGPL-3',
'depends': [
'mail',
],
],
'data': [
'data/ir_config_parameter.xml',
'view/res_config_view.xml',
Expand All @@ -39,8 +23,7 @@
'css': [],
'qweb': [],
'images': [],
'post_load': '',
'application': False,
'installable': False,
'installable': True,
'auto_install': False,
}
104 changes: 41 additions & 63 deletions auth_admin_passkey/model/res_config.py
Original file line number Diff line number Diff line change
@@ -1,76 +1,54 @@
# -*- 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 openerp.osv import fields
from openerp.osv.orm import TransientModel
from openerp.tools.safe_eval import safe_eval
from openerp import api, fields, models


class base_config_settings(TransientModel):
class BaseConfigSettings(models.TransientModel):
_inherit = 'base.config.settings'

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.""")

# Getter / Setter Section
def get_default_auth_admin_passkey_send_to_admin(
self, cr, uid, ids, context=None):
icp = self.pool['ir.config_parameter']
@api.model
def get_default_auth_admin_passkey_send_to_admin(self, fields):
return {
'auth_admin_passkey_send_to_admin': safe_eval(icp.get_param(
cr, uid, 'auth_admin_passkey.send_to_admin', 'True')),
'auth_admin_passkey_send_to_admin':
self.env["ir.config_parameter"].get_param(
"auth_admin_passkey.send_to_admin")
}

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))
@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 '')

def get_default_auth_admin_passkey_send_to_user(
self, cr, uid, ids, context=None):
icp = self.pool['ir.config_parameter']
@api.model
def get_default_auth_admin_passkey_send_to_user(self, fields):
return {
'auth_admin_passkey_send_to_user': safe_eval(icp.get_param(
cr, uid, 'auth_admin_passkey.send_to_user', 'True')),
'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 '')

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, Odoo 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, Odoo will send an email """
"""to the account user.""",
),
}
111 changes: 46 additions & 65 deletions auth_admin_passkey/model/res_users.py
Original file line number Diff line number Diff line change
@@ -1,113 +1,95 @@
# -*- 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

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 import _, fields, api, exceptions, models, SUPERUSER_ID
from openerp.tools.safe_eval import safe_eval


class res_users(Model):
class ResUsers(models.Model):
_inherit = "res.users"

# Private Function section
def _get_translation(self, cr, lang, text):
def _get_translation(self, lang, text):
context = {'lang': lang} # noqa: _() checks page for locals
return _(text)

def _send_email_passkey(self, cr, user_id, user_agent_env):
@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.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'))
mail_obj = self.env['mail.mail']
icp_obj = self.env['ir.config_parameter']
admin_user = self.sudo().env.user
login_user = self.env.user.sudo()
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(
cr, mail['lang'], _('Passkey used'))
mail['lang'], _('Passkey used'))
body = self._get_translation(
cr, mail['lang'],
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"))
fields.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': '<pre>%s</pre>' % body})
mail = mail_obj.sudo().create({
'email_to': mail['email'],
'subject': subject,
'body_html': '<pre>%s</pre>' % body})
mail.send(auto_commit=True)

def _send_email_same_password(self, cr, login_user):
@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.pool['mail.mail']
admin_user = self.browse(cr, SUPERUSER_ID, SUPERUSER_ID)
mail_obj = self.env['mail.mail']
admin_user = self.sudo().env.user
if admin_user.email:
mail_obj.create(cr, SUPERUSER_ID, {
mail = mail_obj.sudo().create({
'email_to': admin_user.email,
'subject': self._get_translation(
cr, admin_user.lang, _('[WARNING] Odoo Security Risk')),
admin_user.lang, _('[WARNING] OpenERP Security Risk')),

'body_html': self._get_translation(
cr, admin_user.lang, _(
admin_user.lang, _(
"""<pre>User with login '%s' has the same """
"""password as you.</pre>""")) % (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(res_users, self).authenticate(
user_id = super(ResUsers, 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()
cr = self.pool.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(
super(ResUsers, 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(
super(ResUsers, self).check_credentials(
cr, user_id, password)
same_password = True
except exceptions.AccessDenied:
Expand All @@ -116,22 +98,21 @@ def authenticate(self, db, login, password, user_agent_env):
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):
@api.model
def check_credentials(self, password):
""" Return now True if credentials are good OR if password is admin
password."""
if uid != SUPERUSER_ID:
if self.env.uid != SUPERUSER_ID:
try:
super(res_users, self).check_credentials(
cr, uid, password)
super(ResUsers, self).check_credentials(password)
return True
except exceptions.AccessDenied:
return self.check_credentials(cr, SUPERUSER_ID, password)
return self.sudo().check_credentials(password)
else:
return super(res_users, self).check_credentials(cr, uid, password)
return super(ResUsers, self).check_credentials(password)
Loading