test_tour.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. import time
  2. from passlib.totp import TOTP
  3. from odoo import http
  4. from odoo.tests import tagged, HttpCase
  5. from odoo.addons.auth_totp.controllers.home import Home
  6. @tagged('post_install', '-at_install')
  7. class TestTOTPortal(HttpCase):
  8. """
  9. Largely replicates TestTOTP
  10. """
  11. def test_totp(self):
  12. totp = None
  13. # test endpoint as doing totp on the client side is not really an option
  14. # (needs sha1 and hmac + BE packing of 64b integers)
  15. def totp_hook(self, secret=None):
  16. nonlocal totp
  17. if totp is None:
  18. totp = TOTP(secret)
  19. if secret:
  20. return totp.generate().token
  21. else:
  22. # on check, take advantage of window because previous token has been
  23. # "burned" so we can't generate the same, but tour is so fast
  24. # we're pretty certainly within the same 30s
  25. return totp.generate(time.time() + 30).token
  26. # because not preprocessed by ControllerType metaclass
  27. totp_hook.routing_type = 'json'
  28. # patch Home to add test endpoint
  29. Home.totp_hook = http.route('/totphook', type='json', auth='none')(totp_hook)
  30. self.env['ir.http']._clear_routing_map()
  31. # remove endpoint and destroy routing map
  32. @self.addCleanup
  33. def _cleanup():
  34. del Home.totp_hook
  35. self.env['ir.http']._clear_routing_map()
  36. self.start_tour('/my/security', 'totportal_tour_setup', login='portal')
  37. # also disables totp otherwise we can't re-login
  38. self.start_tour('/', 'totportal_login_enabled', login=None)
  39. self.start_tour('/', 'totportal_login_disabled', login=None)