@@ -76,6 +76,7 @@ def __init__(self, gac_ui, okta_org_url, verify_ssl_certs=True, device_token=Non
7676 self ._password = None
7777 self ._preferred_mfa_type = None
7878 self ._preferred_mfa_provider = None
79+ self ._preferred_mfa_factor_id = None
7980 self ._duo_universal_factor = 'Duo Push'
8081 self ._mfa_code = None
8182 self ._remember_device = None
@@ -113,6 +114,9 @@ def set_preferred_mfa_type(self, preferred_mfa_type):
113114 def set_preferred_mfa_provider (self , preferred_mfa_provider ):
114115 self ._preferred_mfa_provider = preferred_mfa_provider
115116
117+ def set_preferred_mfa_factor_id (self , preferred_mfa_factor_id ):
118+ self ._preferred_mfa_factor_id = preferred_mfa_factor_id
119+
116120 def set_mfa_code (self , mfa_code ):
117121 self ._mfa_code = mfa_code
118122
@@ -813,6 +817,17 @@ def _choose_factor(self, factors):
813817 else :
814818 preferred_factors = preferred_factors_with_preferred_provider
815819
820+ # Pin to a specific factor by its Okta factor id. Overrides the type/provider
821+ # filters above when matched, since the id uniquely identifies one factor.
822+ if self ._preferred_mfa_factor_id is not None :
823+ factor_id_matches = [item for item in factors if item .get ('id' ) == self ._preferred_mfa_factor_id ]
824+ if factor_id_matches :
825+ preferred_factors = factor_id_matches
826+ else :
827+ self .ui .notify ('Preferred factor id {!r} not found among {} enrolled factors.' .format (
828+ self ._preferred_mfa_factor_id , len (factors )
829+ ))
830+
816831 if len (preferred_factors ) == 1 :
817832 factor_name = self ._build_factor_name (preferred_factors [0 ])
818833 self .ui .info (factor_name + ' selected' )
@@ -827,7 +842,7 @@ def _choose_factor(self, factors):
827842 for i , factor in enumerate (factors ):
828843 factor_name = self ._build_factor_name (factor )
829844 if factor_name != "" :
830- self .ui .info ('[{}] {}' .format (i , factor_name ))
845+ self .ui .info ('[{}] {} (id: {}) ' .format (i , factor_name , factor . get ( 'id' ) ))
831846 selection = self ._get_user_int_factor_choice (len (factors ))
832847
833848 # make sure the choice is valid
0 commit comments