summaryrefslogtreecommitdiff
path: root/distixapi/authn_tests.py
blob: 2d3720a5885eefa1c04d3401c378046e69fc2143 (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
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
import base64
import unittest

import distixapi


class GetCredentialsTests(unittest.TestCase):

    def test_raises_error_if_no_Authentication_header(self):
        request = DummyRequest()
        with self.assertRaises(distixapi.AuthenticationError):
            distixapi.get_credentials(request)

    def test_raises_error_if_empty_Authentication_header(self):
        request = DummyRequest()
        request.add_header('Authorization', '')
        with self.assertRaises(distixapi.AuthenticationError):
            distixapi.get_credentials(request)

    def test_raises_error_if_not_BasicAuth_header(self):
        request = DummyRequest()
        request.add_header('Authorization', 'Bearer token')
        with self.assertRaises(distixapi.AuthenticationError):
            distixapi.get_credentials(request)

    def test_raises_error_if_no_BasicAuth_value(self):
        request = DummyRequest()
        request.add_header('Authorization', 'Basic')
        with self.assertRaises(distixapi.AuthenticationError):
            distixapi.get_credentials(request)

    def test_returns_username_password(self):
        username = 'fooser'
        password = 'secret'
        request = make_request(username, password)
        u, p = distixapi.get_credentials(request)
        self.assertEqual(username, u)
        self.assertEqual(password, p)


class EncryptPasswordTests(unittest.TestCase):

    def test_returns_value_not_containing_cleartext_password(self):
        cleartext = 'secret'
        salt = 'salt'
        encrypted = distixapi.encrypt_password(salt, cleartext)
        self.assertFalse(cleartext in encrypted)

    def test_returns_different_values_with_different_salt(self):
        cleartext = 'secret'
        salt_1 = 'salt'
        salt_2 = 'salt2'
        encrypted_1 = distixapi.encrypt_password(salt_1, cleartext)
        encrypted_2 = distixapi.encrypt_password(salt_2, cleartext)
        self.assertNotEqual(encrypted_1, encrypted_2)


class PasswordCheckingTests(unittest.TestCase):

    def test_raises_exception_if_user_not_known(self):
        users = {
            'users': [],
        }
        request = make_request('unknown', 'password')
        with self.assertRaises(distixapi.AuthenticationError):
            distixapi.get_scopes(users, request)

    def test_raises_exception_if_password_is_wrong(self):
        username = 'fooser'
        salt = 'nacl'
        password = 'passwooooord'
        wrong_password = password + 'foo'
        scopes = ['get', 'put']

        users = {
            'users': {
                username: {
                    'salt': salt,
                    'password': distixapi.encrypt_password(salt, password),
                    'name': 'J. Random User',
                    'scopes': scopes,
                }
            },
        }

        request = make_request(username, wrong_password)
        with self.assertRaises(distixapi.AuthenticationError):
            distixapi.get_scopes(users, request)

    def test_returns_scopes_for_correct_creds(self):
        username = 'fooser'
        salt = 'nacl'
        password = 'passwooooord'
        scopes = ['get', 'put']

        users = {
            'users': {
                username: {
                    'salt': salt,
                    'password': distixapi.encrypt_password(salt, password),
                    'name': 'J. Random User',
                    'scopes': scopes,
                }
            },
        }

        request = make_request(username, password)
        self.assertEqual(distixapi.get_scopes(users, request), scopes)


class DummyRequest(object):

    def __init__(self):
        self._headers = {}

    def add_header(self, header, value):
        self._headers[header] = value

    def get_header(self, header):
        return self._headers.get(header)


def make_request(username, password):
    value = base64.b64encode('{}:{}'.format(username, password))
    request = DummyRequest()
    request.add_header('Authorization', 'Basic {}'.format(value))
    return request