summaryrefslogtreecommitdiffstats
path: root/tests/test_auth.py
blob: 83423efec09f6d6dd81248ef233c0c4739ce3c1a (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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
"""HTTP authentication-related tests."""
from unittest import mock
import pytest

from httpie.plugins.builtin import HTTPBasicAuth
from httpie.status import ExitStatus
from httpie.utils import ExplicitNullAuth
from .utils import http, add_auth, HTTP_OK, MockEnvironment
import httpie.cli.constants
import httpie.cli.definition


def test_basic_auth(httpbin_both):
    r = http('--auth=user:password',
             'GET', httpbin_both + '/basic-auth/user/password')
    assert HTTP_OK in r
    assert r.json == {'authenticated': True, 'user': 'user'}


@pytest.mark.parametrize('argument_name', ['--auth-type', '-A'])
def test_digest_auth(httpbin_both, argument_name):
    r = http(argument_name + '=digest', '--auth=user:password',
             'GET', httpbin_both.url + '/digest-auth/auth/user/password')
    assert HTTP_OK in r
    assert r.json == {'authenticated': True, 'user': 'user'}


@pytest.mark.parametrize('token', [
    'token_1',
    'long_token' * 5,
    'user:style',
])
def test_bearer_auth(httpbin_both, token):
    r = http('--auth-type', 'bearer', '--auth', token,
             httpbin_both + '/bearer')

    assert HTTP_OK in r
    assert r.json == {'authenticated': True, 'token': token}


@mock.patch('httpie.cli.argtypes.AuthCredentials._getpass',
            new=lambda self, prompt: 'password')
def test_password_prompt(httpbin):
    r = http('--auth', 'user',
             'GET', httpbin + '/basic-auth/user/password')
    assert HTTP_OK in r
    assert r.json == {'authenticated': True, 'user': 'user'}


def test_credentials_in_url(httpbin_both):
    url = add_auth(httpbin_both.url + '/basic-auth/user/password',
                   auth='user:password')
    r = http('GET', url)
    assert HTTP_OK in r
    assert r.json == {'authenticated': True, 'user': 'user'}


def test_credentials_in_url_auth_flag_has_priority(httpbin_both):
    """When credentials are passed in URL and via -a at the same time,
     then the ones from -a are used."""
    url = add_auth(httpbin_both.url + '/basic-auth/user/password',
                   auth='user:wrong')
    r = http('--auth=user:password', 'GET', url)
    assert HTTP_OK in r
    assert r.json == {'authenticated': True, 'user': 'user'}


@pytest.mark.parametrize('url', [
    'username@example.org',
    'username:@example.org',
])
def test_only_username_in_url(url):
    """
    https://github.com/httpie/cli/issues/242

    """
    args = httpie.cli.definition.parser.parse_args(args=[url], env=MockEnvironment())
    assert args.auth
    assert args.auth.username == 'username'
    assert args.auth.password == ''


def test_missing_auth(httpbin):
    r = http(
        '--auth-type=basic',
        'GET',
        httpbin + '/basic-auth/user/password',
        tolerate_error_exit_status=True
    )
    assert HTTP_OK not in r
    assert '--auth required' in r.stderr


def test_netrc(httpbin_both):
    # This one gets handled by requests (no --auth, --auth-type present),
    # that’s why we patch inside `requests.sessions`.
    with mock.patch('requests.sessions.get_netrc_auth') as get_netrc_auth:
        get_netrc_auth.return_value = ('httpie', 'password')
        r = http(httpbin_both + '/basic-auth/httpie/password')
        assert get_netrc_auth.call_count == 1
        assert HTTP_OK in r


def test_ignore_netrc(httpbin_both):
    with mock.patch('httpie.cli.argparser.get_netrc_auth') as get_netrc_auth:
        get_netrc_auth.return_value = ('httpie', 'password')
        r = http('--ignore-netrc', httpbin_both + '/basic-auth/httpie/password')
        assert get_netrc_auth.call_count == 0
        assert 'HTTP/1.1 401 UNAUTHORIZED' in r


def test_ignore_netrc_together_with_auth():
    args = httpie.cli.definition.parser.parse_args(
        args=['--ignore-netrc', '--auth=username:password', 'example.org'],
        env=MockEnvironment(),
    )
    assert isinstance(args.auth, HTTPBasicAuth)


def test_ignore_netrc_with_auth_type_resulting_in_missing_auth(httpbin):
    with mock.patch('httpie.cli.argparser.get_netrc_auth') as get_netrc_auth:
        get_netrc_auth.return_value = ('httpie', 'password')
        r = http(
            '--ignore-netrc',
            '--auth-type=basic',
            httpbin + '/basic-auth/httpie/password',
            tolerate_error_exit_status=True,
        )
    assert get_netrc_auth.call_count == 0
    assert r.exit_status == ExitStatus.ERROR
    assert '--auth required' in r.stderr


@pytest.mark.parametrize(
    'auth_type, endpoint',
    [
        ('basic', '/basic-auth/httpie/password'),
        ('digest', '/digest-auth/auth/httpie/password'),
    ]
)
def test_auth_plugin_netrc_parse(auth_type, endpoint, httpbin):
    # Test
    with mock.patch('httpie.cli.argparser.get_netrc_auth') as get_netrc_auth:
        get_netrc_auth.return_value = ('httpie', 'password')
        r = http('--auth-type', auth_type, httpbin + endpoint)
    assert get_netrc_auth.call_count == 1
    assert HTTP_OK in r


def test_ignore_netrc_null_auth():
    args = httpie.cli.definition.parser.parse_args(
        args=['--ignore-netrc', 'example.org'],
        env=MockEnvironment(),
    )
    assert isinstance(args.auth, ExplicitNullAuth)