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.

56 lines
1.8 KiB

  1. # Copyright 2018 Creu Blanca
  2. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
  3. from threading import current_thread
  4. from odoo import api, models, SUPERUSER_ID
  5. from odoo.exceptions import AccessDenied
  6. from odoo.service import wsgi_server
  7. from odoo.tools import config
  8. class ResUsers(models.Model):
  9. _inherit = "res.users"
  10. # HACK https://github.com/odoo/odoo/issues/24183
  11. # TODO Remove in v12, and use normal odoo.http.request to get details
  12. @api.model_cr
  13. def _register_hook(self):
  14. """🐒-patch XML-RPC controller to know remote address."""
  15. super()._register_hook()
  16. original_fn = wsgi_server.application_unproxied
  17. def _patch(environ, start_response):
  18. current_thread().environ = environ
  19. return original_fn(environ, start_response)
  20. wsgi_server.application_unproxied = _patch
  21. @classmethod
  22. def _auth_check_remote(cls, login, method):
  23. """Force a method to raise an AccessDenied on falsey return."""
  24. with cls.pool.cursor() as cr:
  25. env = api.Environment(cr, SUPERUSER_ID, {})
  26. remote = env["res.users"].remote
  27. if not config['test_enable']:
  28. remote.ensure_one()
  29. result = method()
  30. if not result:
  31. # Force exception to record auth failure
  32. raise AccessDenied()
  33. return result
  34. # Override all auth-related core methods
  35. @classmethod
  36. def _login(cls, db, login, password):
  37. return cls._auth_check_remote(
  38. login,
  39. lambda: super(ResUsers, cls)._login(db, login, password),
  40. )
  41. @classmethod
  42. def authenticate(cls, db, login, password, user_agent_env):
  43. return cls._auth_check_remote(
  44. login,
  45. lambda: super(ResUsers, cls).authenticate(
  46. db, login, password, user_agent_env),
  47. )