Skip to content

Commit 1ee3e5b

Browse files
authored
Add http_proxy parameter to Client (#21)
1 parent eacb8dd commit 1ee3e5b

4 files changed

Lines changed: 35 additions & 3 deletions

File tree

demo/app.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ def parse():
114114
host=config[config_section]['api_hostname'],
115115
redirect_uri=config[config_section]['redirect_uri'],
116116
duo_certs=config[config_section].get('duo_certs', None),
117+
http_proxy=config[config_section].get('http_proxy', None),
117118
)
118119
except DuoException as e:
119120
print("*** Duo config error. Verify the values in duo.conf are correct ***")

demo/duo.conf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ client_secret =
55
api_hostname =
66
redirect_uri = http://localhost:8080/duo-callback
77
failmode = closed
8+
; Uncomment to use an HTTP proxy server
9+
; http_proxy = localhost:8081

duo_universal/client.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def _create_jwt_args(self, endpoint):
113113
return jwt_args
114114

115115
def __init__(self, client_id, client_secret, host,
116-
redirect_uri, duo_certs=DEFAULT_CA_CERT_PATH, use_duo_code_attribute=True):
116+
redirect_uri, duo_certs=DEFAULT_CA_CERT_PATH, use_duo_code_attribute=True, http_proxy=None):
117117
"""
118118
Initializes instance of Client class
119119
@@ -125,6 +125,7 @@ def __init__(self, client_id, client_secret, host,
125125
redirect_uri -- Uri to redirect to after a successful auth
126126
duo_certs -- (Optional) Provide custom CA certs
127127
use_duo_code_attribute -- (Optional: default true) Flag to use `duo_code` instead of `code` for returned authorization parameter
128+
http_proxy -- (Optional) HTTP proxy to tunnel requests through
128129
"""
129130

130131
self._validate_init_config(client_id,
@@ -148,6 +149,11 @@ def __init__(self, client_id, client_secret, host,
148149
else:
149150
self._duo_certs = DEFAULT_CA_CERT_PATH
150151

152+
if http_proxy is not None:
153+
self._http_proxy = {'https': http_proxy}
154+
else:
155+
self._http_proxy = None
156+
151157
def generate_state(self):
152158
"""
153159
Return a random string of 36 characters
@@ -181,7 +187,8 @@ def health_check(self):
181187
try:
182188
response = requests.post(health_check_endpoint,
183189
data=all_args,
184-
verify=self._duo_certs)
190+
verify=self._duo_certs,
191+
proxies=self._http_proxy)
185192
res = json.loads(response.content)
186193
if res['stat'] != 'OK':
187194
raise DuoException(res)
@@ -282,7 +289,8 @@ def exchange_authorization_code_for_2fa_result(self, duoCode, username, nonce=No
282289
params=all_args,
283290
headers={"user-agent":
284291
user_agent},
285-
verify=self._duo_certs)
292+
verify=self._duo_certs,
293+
proxies=self._http_proxy)
286294
except Exception as e:
287295
raise DuoException(e)
288296

tests/test_setup_client.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
WRONG_HOST = "api-XXXXXXX.test.duosecurity.com"
1212
REDIRECT_URI = "https://www.example.com"
1313
CA_CERT_NEW = "/path/to/cert/ca_cert_new.pem"
14+
PROXY_HOST = "http://proxy.example.com:8001"
1415
NONE = None
1516

1617

@@ -116,6 +117,26 @@ def test_disable_duo_cert(self):
116117
def test_default_duo_code_attribute(self):
117118
self.assertEqual(self.client._use_duo_code_attribute, True)
118119

120+
def test_proxy_unset(self):
121+
plain_client = client.Client(CLIENT_ID, CLIENT_SECRET, HOST, REDIRECT_URI)
122+
self.assertEqual(plain_client._http_proxy, NONE)
123+
124+
def test_proxy_set_on_args(self):
125+
client_with_proxy = client.Client(CLIENT_ID, CLIENT_SECRET, HOST, REDIRECT_URI, NONE, True, PROXY_HOST)
126+
self.assertEqual(client_with_proxy._http_proxy, {'https': PROXY_HOST})
127+
128+
def test_proxy_set_on_kwargs(self):
129+
client_with_proxy = client.Client(CLIENT_ID, CLIENT_SECRET, HOST, REDIRECT_URI, http_proxy=PROXY_HOST)
130+
self.assertEqual(client_with_proxy._http_proxy, {'https': PROXY_HOST})
131+
132+
def test_proxy_set_off_args(self):
133+
client_with_no_proxy = client.Client(CLIENT_ID, CLIENT_SECRET, HOST, REDIRECT_URI, NONE, True, NONE)
134+
self.assertEqual(client_with_no_proxy._http_proxy, NONE)
135+
136+
def test_proxy_set_off_kwargs(self):
137+
client_with_no_proxy = client.Client(CLIENT_ID, CLIENT_SECRET, HOST, REDIRECT_URI, http_proxy=NONE)
138+
self.assertEqual(client_with_no_proxy._http_proxy, NONE)
139+
119140

120141
if __name__ == '__main__':
121142
unittest.main()

0 commit comments

Comments
 (0)