summaryrefslogtreecommitdiff
path: root/addons/auth_totp_portal/tests/test_tour.py
blob: 242c9f0dcea8f0e9b6ea99f5c56249142b6988ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import time

from passlib.totp import TOTP

from odoo import http
from odoo.tests import tagged, HttpCase
from odoo.addons.auth_totp.controllers.home import Home


@tagged('post_install', '-at_install')
class TestTOTPortal(HttpCase):
    """
    Largely replicates TestTOTP
    """
    def test_totp(self):
        totp = None
        # test endpoint as doing totp on the client side is not really an option
        # (needs sha1 and hmac + BE packing of 64b integers)
        def totp_hook(self, secret=None):
            nonlocal totp
            if totp is None:
                totp = TOTP(secret)
            if secret:
                return totp.generate().token
            else:
                # on check, take advantage of window because previous token has been
                # "burned" so we can't generate the same, but tour is so fast
                # we're pretty certainly within the same 30s
                return totp.generate(time.time() + 30).token
        # because not preprocessed by ControllerType metaclass
        totp_hook.routing_type = 'json'
        # patch Home to add test endpoint
        Home.totp_hook = http.route('/totphook', type='json', auth='none')(totp_hook)
        self.env['ir.http']._clear_routing_map()
        # remove endpoint and destroy routing map
        @self.addCleanup
        def _cleanup():
            del Home.totp_hook
            self.env['ir.http']._clear_routing_map()

        self.start_tour('/my/security', 'totportal_tour_setup', login='portal')
        # also disables totp otherwise we can't re-login
        self.start_tour('/', 'totportal_login_enabled', login=None)
        self.start_tour('/', 'totportal_login_disabled', login=None)