File: web_ui.py

package info (click to toggle)
trac-accountmanager 0.6.1%2Bsvn18669-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,552 kB
  • sloc: python: 6,863; javascript: 175; makefile: 4
file content (132 lines) | stat: -rw-r--r-- 5,389 bytes parent folder | download
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# -*- coding: utf-8 -*-
#
# Copyright (C) 2024 Jun Omae <jun66j5@gmail.com>
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution.

import os
import shutil
import tempfile
import unittest

from trac.test import EnvironmentStub, MockRequest
from trac.util import create_file
from trac.web.api import RequestDone
from trac.web.auth import LoginModule as TracLoginModule
from trac.web.chrome import Chrome
from trac.web.main import RequestDispatcher
from trac.wiki.web_ui import WikiModule

from ..api import AccountManager
from ..svnserve import SvnServePasswordStore
from ..web_ui import LoginModule
from . import makeSuite


class LoginTestCase(unittest.TestCase):

    authz_content = '[users]\n' \
                    'john = pass\n'
    referer = 'http://example.org/trac.cgi/wiki/WikiStart'

    def setUp(self):
        self.tmpdir = tempfile.mkdtemp(prefix='trac-testdir-')
        self.env = EnvironmentStub(
            path=self.tmpdir,
            enable=[Chrome, WikiModule, AccountManager, SvnServePasswordStore,
                    LoginModule],
            disable=[TracLoginModule])
        self.config = self.env.config
        self.config.set('trac', 'use_chunked_encoding', 'disabled')
        authz_file = os.path.join(self.tmpdir, 'svnserve-authz.txt')
        create_file(authz_file, self.authz_content)
        self.config.set('account-manager', 'password_store',
                        'SvnServePasswordStore')
        self.config.set('account-manager', 'password_file', authz_file)
        self.mod = LoginModule(self.env)
        self.dispatcher = RequestDispatcher(self.env)

    def tearDown(self):
        self.env.shutdown()
        shutil.rmtree(self.tmpdir)

    def _create_req(self, **kwargs):
        referer = kwargs.pop('referer', None)
        req = MockRequest(self.env, **kwargs)
        req.environ.pop('REMOTE_USER', None)
        if referer:
            req.environ['HTTP_REFERER'] = referer
        req.callbacks['authname'] = self.dispatcher.authenticate
        return req

    def _create_req_login(self, username='', password='', rememberme=None,
                          referer=None, cookie=''):
        args = {'username': username, 'password': password}
        if rememberme is not None:
            args['rememberme'] = rememberme
        return self._create_req(method='POST', path_info='/login', args=args,
                                referer=referer, cookie=cookie)

    def _to_incookie(self, req):
        return '; '.join('{}={}'.format(key, c.value)
                         for key, c in req.outcookie.items())

    def test_login_success(self):
        req = self._create_req_login(username='john', password='pass',
                                     referer=self.referer)
        self.assertRaises(RequestDone, self.dispatcher.dispatch, req)
        self.assertEqual(self.referer, req.headers_sent.get('Location'))
        self.assertIn('trac_auth', req.outcookie)
        self.assertTrue(req.outcookie['trac_auth'].value)
        self.assertFalse(req.outcookie['trac_auth'].get('expires'))
        self.assertNotIn('trac_auth_session', req.outcookie)

        cookie = self._to_incookie(req)
        req = self._create_req(path_info='/wiki/WikiStart', cookie=cookie)
        self.assertRaises(RequestDone, self.dispatcher.dispatch, req)
        for item in req.chrome['nav']['metanav']:
            if item['name'] == 'login':
                self.assertIn('>john<', str(item['label']))
                break
        else:
            self.fail('Missing login item in metanav')

    def test_login_failure(self):
        req = self._create_req_login(username='john', password='????')
        self.assertRaises(RequestDone, self.dispatcher.dispatch, req)
        self.assertIn(b'Invalid username or password',
                      req.response_sent.getvalue())

    def test_login_persist(self):
        self.config.set('account-manager', 'persistent_sessions', 'enabled')
        self.config.set('account-manager', 'cookie_refresh_pct', '-100')
        req = self._create_req_login(username='john', password='pass',
                                     rememberme='1', referer=self.referer)
        self.assertRaises(RequestDone, self.dispatcher.dispatch, req)
        self.assertIn('trac_auth', req.outcookie)
        self.assertTrue(req.outcookie['trac_auth'].get('expires'))
        self.assertIn('trac_auth_session', req.outcookie)
        self.assertEqual('1', req.outcookie['trac_auth_session'].value)
        self.assertTrue(req.outcookie['trac_auth_session'].get('expires'))
        old_session_id = req.outcookie['trac_auth'].value
        cookie = self._to_incookie(req)

        self.config.set('account-manager', 'cookie_refresh_pct', '100')
        req = self._create_req(path_info='/wiki/WikiStart', cookie=cookie)
        self.assertRaises(RequestDone, self.dispatcher.dispatch, req)
        self.assertIn('trac_auth', req.outcookie)
        new_session_id = req.outcookie['trac_auth'].value
        self.assertNotEqual(old_session_id, new_session_id)
        self.assertEqual(len(old_session_id), len(new_session_id))


def test_suite():
    suite = unittest.TestSuite()
    suite.addTest(makeSuite(LoginTestCase))
    return suite


if __name__ == '__main__':
    unittest.main(defaultTest='test_suite')