You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
4.8 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright (C) 2013-2014 GRAP (http://www.grap.coop)
  3. # @author Sylvain LE GAL (https://twitter.com/legalsylvain)
  4. # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
  5. import datetime
  6. from openerp import _, api, exceptions, models, registry, SUPERUSER_ID
  7. class ResUsers(models.Model):
  8. _inherit = "res.users"
  9. def _get_translation(self, lang, text):
  10. context = {'lang': lang} # noqa: _() checks page for locals
  11. return _(text)
  12. @api.model
  13. def _send_email_passkey(self, user_agent_env):
  14. """ Send a email to the admin of the system and / or the user
  15. to inform passkey use."""
  16. mails = []
  17. mail_obj = self.env['mail.mail']
  18. icp_obj = self.env['ir.config_parameter']
  19. admin_user = self.sudo().browse(SUPERUSER_ID)
  20. login_user = self.sudo().browse(self.env.uid)
  21. send_to_admin = icp_obj.sudo().get_param(
  22. 'auth_admin_passkey.send_to_admin') == 'True' and True or False
  23. send_to_user = icp_obj.sudo().get_param(
  24. 'auth_admin_passkey.send_to_user') == 'True' and True or False
  25. if send_to_admin and admin_user.email:
  26. mails.append({'email': admin_user.email, 'lang': admin_user.lang})
  27. if send_to_user and login_user.email:
  28. mails.append({'email': login_user.email, 'lang': login_user.lang})
  29. for mail in mails:
  30. subject = self._get_translation(
  31. mail['lang'], _('Passkey used'))
  32. body = self._get_translation(
  33. mail['lang'],
  34. _("""Admin user used his passkey to login with '%s'.\n\n"""
  35. """\n\nTechnicals informations belows : \n\n"""
  36. """- Login date : %s\n\n""")) % (
  37. login_user.login,
  38. datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
  39. for k, v in user_agent_env.iteritems():
  40. body += ("- %s : %s\n\n") % (k, v)
  41. mail = mail_obj.sudo().create({
  42. 'email_to': mail['email'],
  43. 'subject': subject,
  44. 'body_html': '<pre>%s</pre>' % body})
  45. mail.send(auto_commit=True)
  46. @api.cr
  47. def _send_email_same_password(self, cr, login_user):
  48. """ Send a email to the admin user to inform that another user has the
  49. same password as him."""
  50. mail_obj = self.pool['mail.mail']
  51. admin_user = self.browse(cr, SUPERUSER_ID, SUPERUSER_ID)
  52. if admin_user.email:
  53. mail_id = mail_obj.create(cr, SUPERUSER_ID, {
  54. 'email_to': admin_user.email,
  55. 'subject': self._get_translation(
  56. admin_user.lang, _('[WARNING] Odoo Security Risk')),
  57. 'body_html': self._get_translation(
  58. admin_user.lang, _(
  59. """<pre>User with login '%s' has the same """
  60. """password as you.</pre>""")) % (login_user),
  61. })
  62. mail_obj.send(cr, SUPERUSER_ID, [mail_id], auto_commit=True)
  63. # Overload Section
  64. def authenticate(self, db, login, password, user_agent_env):
  65. """ Authenticate the user 'login' is password is ok or if
  66. is admin password. In the second case, send mail to user and admin."""
  67. user_id = super(ResUsers, self).authenticate(
  68. db, login, password, user_agent_env)
  69. if user_id and (user_id != SUPERUSER_ID):
  70. same_password = False
  71. cr = registry(db).cursor()
  72. try:
  73. # directly use parent 'check_credentials' function
  74. # to really know if credentials are ok
  75. # or if it was admin password
  76. super(ResUsers, self).check_credentials(
  77. cr, SUPERUSER_ID, password)
  78. try:
  79. # Test now if the user has the same password as admin user
  80. super(ResUsers, self).check_credentials(
  81. cr, user_id, password)
  82. same_password = True
  83. except exceptions.AccessDenied:
  84. pass
  85. if not same_password:
  86. self._send_email_passkey(cr, user_id, user_agent_env)
  87. else:
  88. self._send_email_same_password(cr, login)
  89. except exceptions.AccessDenied:
  90. pass
  91. finally:
  92. cr.close()
  93. return user_id
  94. @api.model
  95. def check_credentials(self, password):
  96. """ Return now True if credentials are good OR if password is admin
  97. password."""
  98. if self.env.uid != SUPERUSER_ID:
  99. try:
  100. super(ResUsers, self).check_credentials(password)
  101. return True
  102. except exceptions.AccessDenied:
  103. return self.sudo().check_credentials(password)
  104. else:
  105. return super(ResUsers, self).check_credentials(password)