Skip to content

Commit 710a57e

Browse files
authored
Enable setting ipaddr param in preauth and auth (#297)
Also introduces argparse to organize args better.
1 parent b357623 commit 710a57e

File tree

1 file changed

+32
-22
lines changed

1 file changed

+32
-22
lines changed

examples/Auth/basic_user_mfa.py

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,50 @@
22
Example of Duo Auth API uaer authentication with synchronous request/response
33
"""
44

5+
from argparse import ArgumentParser, Namespace
56
import duo_client
6-
import sys
77
import getpass
88

9-
from pprint import pprint
109

10+
def _get_arg(args: Namespace, name: str, prompt: str, secure=False):
11+
"""Read arg from CLI flags or stdin, using getpass when sensitive information should not be echoed to tty"""
12+
value = getattr(args, name)
13+
if value is not None:
14+
return value
1115

12-
argv_iter = iter(sys.argv[1:])
13-
14-
15-
def _get_next_arg(prompt, secure=False):
16-
"""Read information from STDIN, using getpass when sensitive information should not be echoed to tty"""
17-
try:
18-
return next(argv_iter)
19-
except StopIteration:
20-
if secure is True:
21-
return getpass.getpass(prompt)
22-
else:
23-
return input(prompt)
16+
if secure is True:
17+
return getpass.getpass(prompt)
18+
else:
19+
return input(prompt)
2420

2521

26-
def prompt_for_credentials() -> dict:
22+
def prompt_for_credentials(args: Namespace) -> dict:
2723
"""Collect required API credentials from command line prompts
2824
2925
:return: dictionary containing Duo Auth API ikey, skey and hostname strings
3026
"""
3127

32-
ikey = _get_next_arg('Duo Auth API integration key ("DI..."): ')
33-
skey = _get_next_arg('Duo Auth API integration secret key: ', secure=True)
34-
host = _get_next_arg('Duo Auth API hostname ("api-....duosecurity.com"): ')
35-
username = _get_next_arg('Duo Username: ')
28+
ikey = _get_arg(args, "ikey", 'Duo Auth API integration key ("DI..."): ')
29+
skey = _get_arg(args, "skey", 'Duo Auth API integration secret key: ', secure=True)
30+
host = _get_arg(args, "api_host", 'Duo Auth API hostname ("api-....duosecurity.com"): ')
31+
username = _get_arg(args, "username", 'Duo Username: ')
3632

3733
return {"USERNAME": username, "IKEY": ikey, "SKEY": skey, "APIHOST": host}
3834

3935

4036
def main():
4137
"""Main program entry point"""
4238

43-
inputs = prompt_for_credentials()
39+
parser = ArgumentParser()
40+
parser.add_argument("--ipaddr", type=str)
41+
parser.add_argument("--ikey", type=str)
42+
parser.add_argument("--skey", type=str)
43+
parser.add_argument("--api-host", type=str)
44+
parser.add_argument("--username", type=str)
45+
parser.add_argument("--verbose", action="store_true", default=False)
46+
args = parser.parse_args()
47+
48+
inputs = prompt_for_credentials(args)
4449

4550
auth_client = duo_client.Auth(
4651
ikey=inputs['IKEY'],
@@ -64,15 +69,20 @@ def main():
6469

6570
# Execute pre-authentication for given user
6671
print(f"\nExecuting pre-authentication for {inputs['USERNAME']}...")
67-
pre_auth = auth_client.preauth(username=inputs['USERNAME'])
72+
pre_auth = auth_client.preauth(username=inputs['USERNAME'], ipaddr=args.ipaddr)
73+
if args.verbose:
74+
print(f"{pre_auth=}")
6875

6976
if pre_auth['result'] == "auth":
7077
try:
7178
# User exists and has an MFA device enrolled
7279
print(f"Executing authentication action for {inputs['USERNAME']}...")
7380
# "auto" is selected for the factor in this example, however the pre_auth['devices'] dictionary
7481
# element contains a list of factors available for the provided user, if an alternate method is desired
75-
auth = auth_client.auth(factor="auto", username=inputs['USERNAME'], device="auto")
82+
auth = auth_client.auth(factor="auto", username=inputs['USERNAME'], device="auto", ipaddr=args.ipaddr)
83+
if args.verbose:
84+
print(f"{auth=}")
85+
7686
print(f"\n{auth['status_msg']}")
7787
except Exception as e_str:
7888
print(e_str)

0 commit comments

Comments
 (0)