1from unittest import mock
2
3from httpie.cli.constants import SEPARATOR_CREDENTIALS
4from httpie.plugins import AuthPlugin
5from httpie.plugins.registry import plugin_manager
6from .utils import http, HTTP_OK
7
8
9# TODO: run all these tests in session mode as well
10
11USERNAME = 'user'
12PASSWORD = 'password'
13# Basic auth encoded `USERNAME` and `PASSWORD`
14# noinspection SpellCheckingInspection
15BASIC_AUTH_HEADER_VALUE = 'Basic dXNlcjpwYXNzd29yZA=='
16BASIC_AUTH_URL = f'/basic-auth/{USERNAME}/{PASSWORD}'
17AUTH_OK = {'authenticated': True, 'user': USERNAME}
18
19
20def basic_auth(header=BASIC_AUTH_HEADER_VALUE):
21
22    def inner(r):
23        r.headers['Authorization'] = header
24        return r
25
26    return inner
27
28
29def test_auth_plugin_parse_auth_false(httpbin):
30
31    class Plugin(AuthPlugin):
32        auth_type = 'test-parse-false'
33        auth_parse = False
34
35        def get_auth(self, username=None, password=None):
36            assert username is None
37            assert password is None
38            assert self.raw_auth == BASIC_AUTH_HEADER_VALUE
39            return basic_auth(self.raw_auth)
40
41    plugin_manager.register(Plugin)
42    try:
43        r = http(
44            httpbin + BASIC_AUTH_URL,
45            '--auth-type',
46            Plugin.auth_type,
47            '--auth',
48            BASIC_AUTH_HEADER_VALUE,
49        )
50        assert HTTP_OK in r
51        assert r.json == AUTH_OK
52    finally:
53        plugin_manager.unregister(Plugin)
54
55
56def test_auth_plugin_require_auth_false(httpbin):
57
58    class Plugin(AuthPlugin):
59        auth_type = 'test-require-false'
60        auth_require = False
61
62        def get_auth(self, username=None, password=None):
63            assert self.raw_auth is None
64            assert username is None
65            assert password is None
66            return basic_auth()
67
68    plugin_manager.register(Plugin)
69    try:
70        r = http(
71            httpbin + BASIC_AUTH_URL,
72            '--auth-type',
73            Plugin.auth_type,
74        )
75        assert HTTP_OK in r
76        assert r.json == AUTH_OK
77    finally:
78        plugin_manager.unregister(Plugin)
79
80
81def test_auth_plugin_require_auth_false_and_auth_provided(httpbin):
82
83    class Plugin(AuthPlugin):
84        auth_type = 'test-require-false-yet-provided'
85        auth_require = False
86
87        def get_auth(self, username=None, password=None):
88            assert self.raw_auth == USERNAME + SEPARATOR_CREDENTIALS + PASSWORD
89            assert username == USERNAME
90            assert password == PASSWORD
91            return basic_auth()
92
93    plugin_manager.register(Plugin)
94    try:
95        r = http(
96            httpbin + BASIC_AUTH_URL,
97            '--auth-type',
98            Plugin.auth_type,
99            '--auth',
100            USERNAME + SEPARATOR_CREDENTIALS + PASSWORD,
101        )
102        assert HTTP_OK in r
103        assert r.json == AUTH_OK
104    finally:
105        plugin_manager.unregister(Plugin)
106
107
108@mock.patch('httpie.cli.argtypes.AuthCredentials._getpass',
109            new=lambda self, prompt: 'UNEXPECTED_PROMPT_RESPONSE')
110def test_auth_plugin_prompt_password_false(httpbin):
111
112    class Plugin(AuthPlugin):
113        auth_type = 'test-prompt-false'
114        prompt_password = False
115
116        def get_auth(self, username=None, password=None):
117            assert self.raw_auth == USERNAME
118            assert username == USERNAME
119            assert password is None
120            return basic_auth()
121
122    plugin_manager.register(Plugin)
123
124    try:
125        r = http(
126            httpbin + BASIC_AUTH_URL,
127            '--auth-type',
128            Plugin.auth_type,
129            '--auth',
130            USERNAME,
131        )
132        assert HTTP_OK in r
133        assert r.json == AUTH_OK
134    finally:
135        plugin_manager.unregister(Plugin)
136