File: test_token_async.py

package info (click to toggle)
python-flask-httpauth 4.8.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 436 kB
  • sloc: python: 2,129; makefile: 150
file content (149 lines) | stat: -rw-r--r-- 6,185 bytes parent folder | download | duplicates (2)
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import base64
import sys
import unittest
from flask import Flask
from flask_httpauth import HTTPTokenAuth
import pytest


@pytest.mark.skipif(sys.version_info < (3, 7), reason='requires python3.7')
class HTTPAuthTestCase(unittest.TestCase):
    def setUp(self):
        app = Flask(__name__)
        app.config['SECRET_KEY'] = 'my secret'

        token_auth = HTTPTokenAuth('MyToken')
        token_auth2 = HTTPTokenAuth('Token', realm='foo')
        token_auth3 = HTTPTokenAuth(header='X-API-Key')

        @token_auth.verify_token
        async def verify_token(token):
            if token == 'this-is-the-token!':
                return 'user'

        @token_auth3.verify_token
        async def verify_token3(token):
            if token == 'this-is-the-token!':
                return 'user'

        @token_auth.error_handler
        async def error_handler():
            return 'error', 401, {'WWW-Authenticate': 'MyToken realm="Foo"'}

        @app.route('/')
        async def index():
            return 'index'

        @app.route('/protected')
        @token_auth.login_required
        async def token_auth_route():
            return 'token_auth:' + token_auth.current_user()

        @app.route('/protected-optional')
        @token_auth.login_required(optional=True)
        async def token_auth_optional_route():
            return 'token_auth:' + str(token_auth.current_user())

        @app.route('/protected2')
        @token_auth2.login_required
        async def token_auth_route2():
            return 'token_auth2'

        @app.route('/protected3')
        @token_auth3.login_required
        async def token_auth_route3():
            return 'token_auth3:' + token_auth3.current_user()

        self.app = app
        self.token_auth = token_auth
        self.client = app.test_client()

    def test_token_auth_prompt(self):
        response = self.client.get('/protected')
        self.assertEqual(response.status_code, 401)
        self.assertTrue('WWW-Authenticate' in response.headers)
        self.assertEqual(response.headers['WWW-Authenticate'],
                         'MyToken realm="Foo"')

    def test_token_auth_ignore_options(self):
        response = self.client.options('/protected')
        self.assertEqual(response.status_code, 200)
        self.assertTrue('WWW-Authenticate' not in response.headers)

    def test_token_auth_login_valid(self):
        response = self.client.get(
            '/protected', headers={'Authorization':
                                   'MyToken this-is-the-token!'})
        self.assertEqual(response.data.decode('utf-8'), 'token_auth:user')

    def test_token_auth_login_valid_different_case(self):
        response = self.client.get(
            '/protected', headers={'Authorization':
                                   'mytoken this-is-the-token!'})
        self.assertEqual(response.data.decode('utf-8'), 'token_auth:user')

    def test_token_auth_login_optional(self):
        response = self.client.get('/protected-optional')
        self.assertEqual(response.data.decode('utf-8'), 'token_auth:None')

    def test_token_auth_login_invalid_token(self):
        response = self.client.get(
            '/protected', headers={'Authorization':
                                   'MyToken this-is-not-the-token!'})
        self.assertEqual(response.status_code, 401)
        self.assertTrue('WWW-Authenticate' in response.headers)
        self.assertEqual(response.headers['WWW-Authenticate'],
                         'MyToken realm="Foo"')

    def test_token_auth_login_invalid_scheme(self):
        response = self.client.get(
            '/protected', headers={'Authorization': 'Foo this-is-the-token!'})
        self.assertEqual(response.status_code, 401)
        self.assertTrue('WWW-Authenticate' in response.headers)
        self.assertEqual(response.headers['WWW-Authenticate'],
                         'MyToken realm="Foo"')

    def test_token_auth_login_invalid_header(self):
        response = self.client.get(
            '/protected', headers={'Authorization': 'this-is-a-bad-header'})
        self.assertEqual(response.status_code, 401)
        self.assertTrue('WWW-Authenticate' in response.headers)
        self.assertEqual(response.headers['WWW-Authenticate'],
                         'MyToken realm="Foo"')

    def test_token_auth_login_invalid_no_callback(self):
        response = self.client.get(
            '/protected2', headers={'Authorization':
                                    'Token this-is-the-token!'})
        self.assertEqual(response.status_code, 401)
        self.assertTrue('WWW-Authenticate' in response.headers)
        self.assertEqual(response.headers['WWW-Authenticate'],
                         'Token realm="foo"')

    def test_token_auth_custom_header_valid_token(self):
        response = self.client.get(
            '/protected3', headers={'X-API-Key': 'this-is-the-token!'})
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data.decode('utf-8'), 'token_auth3:user')

    def test_token_auth_custom_header_invalid_token(self):
        response = self.client.get(
            '/protected3', headers={'X-API-Key': 'invalid-token-should-fail'})
        self.assertEqual(response.status_code, 401)
        self.assertTrue('WWW-Authenticate' in response.headers)

    def test_token_auth_custom_header_invalid_header(self):
        response = self.client.get(
            '/protected3', headers={'API-Key': 'this-is-the-token!'})
        self.assertEqual(response.status_code, 401)
        self.assertTrue('WWW-Authenticate' in response.headers)
        self.assertEqual(response.headers['WWW-Authenticate'],
                         'Bearer realm="Authentication Required"')

    def test_token_auth_header_precedence(self):
        basic_creds = base64.b64encode(b'susan:bye').decode('utf-8')
        response = self.client.get(
            '/protected3', headers={'Authorization': 'Basic ' + basic_creds,
                                    'X-API-Key': 'this-is-the-token!'})
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data.decode('utf-8'), 'token_auth3:user')