19
19
from botocore import client
20
20
21
21
from . import authenticator , helpers , prepare , role_chooser
22
+ from . import run_command
22
23
from .consts import (
23
24
DUO_UNIVERSAL_PROMPT_FACTOR_DUO_PUSH ,
24
25
DUO_UNIVERSAL_PROMPT_FACTOR_PASSCODE ,
75
76
"--username-password-command" ,
76
77
help = 'Read username and password from the output of a shell command (expected JSON format: `{"username": "myusername", "password": "mypassword"}`)' ,
77
78
)
79
+ @click .option (
80
+ "--mfa-token-command" ,
81
+ help = 'Read MFA token from the output of a shell command (expected JSON format: `{"mfa_token": "123654"}`)' ,
82
+ )
78
83
@click .option (
79
84
'--env' ,
80
85
is_flag = True ,
81
- help = 'Read username, password from environment variables (username and password ).' ,
86
+ help = 'Read username, password and optionally an MFA token from environment variables (username, password and mfa_token ).' ,
82
87
)
83
88
@click .option (
84
89
'--stdin' ,
@@ -161,6 +166,7 @@ def login(
161
166
provider_id ,
162
167
s3_signature_version ,
163
168
username_password_command ,
169
+ mfa_token_command ,
164
170
env ,
165
171
stdin ,
166
172
authfile ,
@@ -194,6 +200,7 @@ def login(
194
200
session_duration ,
195
201
sspi ,
196
202
username_password_command ,
203
+ mfa_token_command ,
197
204
duo_factor ,
198
205
duo_device ,
199
206
aad_verification_code ,
@@ -220,11 +227,9 @@ def login(
220
227
# If we fail to get an assertion, prompt for credentials and try again
221
228
if assertion is None :
222
229
password = None
223
-
224
230
if config .username_password_command :
225
- config .adfs_user , password = _username_password_command_credentials (
226
- username_password_command
227
- )
231
+ data = run_command .run_command (username_password_command )
232
+ config .adfs_user , password = data ['username' ], data ['password' ]
228
233
if stdin :
229
234
config .adfs_user , password = _stdin_user_credentials ()
230
235
elif env :
@@ -438,40 +443,6 @@ def _emit_summary(config, session_duration):
438
443
err = True
439
444
)
440
445
441
-
442
- def _username_password_command_credentials (username_password_command ):
443
- try :
444
- logging .debug ("Executing `{}`" .format (username_password_command ))
445
- proc = subprocess .run (
446
- username_password_command ,
447
- stdout = subprocess .PIPE ,
448
- stderr = subprocess .STDOUT ,
449
- check = True ,
450
- shell = True ,
451
- )
452
- data = json .loads (proc .stdout )
453
- username = data ["username" ]
454
- password = data ["password" ]
455
- except subprocess .CalledProcessError as e :
456
- logging .error (
457
- "Failed to execute the `{}` command to retrieve username and password: \n \n {}" .format (
458
- username_password_command , e .output
459
- )
460
- )
461
- username = None
462
- password = None
463
- except json .JSONDecodeError as e :
464
- logging .error (
465
- "Failed to decode the output of the `{}` command as JSON to retrieve username and password: \n \n {}" .format (
466
- username_password_command , e
467
- )
468
- )
469
- username = None
470
- password = None
471
-
472
- return username , password
473
-
474
-
475
446
def _file_user_credentials (profile , authfile ):
476
447
config = configparser .ConfigParser ()
477
448
0 commit comments