CognitoIDP: clean MFA settings capability and enable multiple MFA methods (#6853)
This commit is contained in:
		
							parent
							
								
									178f2b8c03
								
							
						
					
					
						commit
						9a84423187
					
				| @ -833,7 +833,7 @@ class CognitoIdpUser(BaseModel): | ||||
|         user_mfa_setting_list = [] | ||||
|         if self.software_token_mfa_enabled: | ||||
|             user_mfa_setting_list.append("SOFTWARE_TOKEN_MFA") | ||||
|         elif self.sms_mfa_enabled: | ||||
|         if self.sms_mfa_enabled: | ||||
|             user_mfa_setting_list.append("SMS_MFA") | ||||
|         user_json = self._base_json() | ||||
|         if extended: | ||||
| @ -1981,26 +1981,13 @@ class CognitoIdpBackend(BaseBackend): | ||||
|         for user_pool in self.user_pools.values(): | ||||
|             if access_token in user_pool.access_tokens: | ||||
|                 _, username = user_pool.access_tokens[access_token] | ||||
|                 user = self.admin_get_user(user_pool.id, username) | ||||
| 
 | ||||
|                 if software_token_mfa_settings and software_token_mfa_settings.get( | ||||
|                     "Enabled" | ||||
|                 ): | ||||
|                     if user.token_verified: | ||||
|                         user.software_token_mfa_enabled = True | ||||
|                     else: | ||||
|                         raise InvalidParameterException( | ||||
|                             "User has not verified software token mfa" | ||||
|                         ) | ||||
| 
 | ||||
|                     if software_token_mfa_settings.get("PreferredMfa"): | ||||
|                         user.preferred_mfa_setting = "SOFTWARE_TOKEN_MFA" | ||||
|                 elif sms_mfa_settings and sms_mfa_settings["Enabled"]: | ||||
|                     user.sms_mfa_enabled = True | ||||
| 
 | ||||
|                     if sms_mfa_settings.get("PreferredMfa"): | ||||
|                         user.preferred_mfa_setting = "SMS_MFA" | ||||
|                 return None | ||||
|                 return self.admin_set_user_mfa_preference( | ||||
|                     user_pool.id, | ||||
|                     username, | ||||
|                     software_token_mfa_settings, | ||||
|                     sms_mfa_settings, | ||||
|                 ) | ||||
| 
 | ||||
|         raise NotAuthorizedError(access_token) | ||||
| 
 | ||||
| @ -2013,21 +2000,33 @@ class CognitoIdpBackend(BaseBackend): | ||||
|     ) -> None: | ||||
|         user = self.admin_get_user(user_pool_id, username) | ||||
| 
 | ||||
|         if software_token_mfa_settings and software_token_mfa_settings.get("Enabled"): | ||||
|             if user.token_verified: | ||||
|                 user.software_token_mfa_enabled = True | ||||
|         if software_token_mfa_settings: | ||||
|             if software_token_mfa_settings.get("Enabled"): | ||||
|                 if user.token_verified: | ||||
|                     user.software_token_mfa_enabled = True | ||||
|                 else: | ||||
|                     raise InvalidParameterException( | ||||
|                         "User has not verified software token mfa" | ||||
|                     ) | ||||
|             else: | ||||
|                 raise InvalidParameterException( | ||||
|                     "User has not verified software token mfa" | ||||
|                 ) | ||||
|                 user.software_token_mfa_enabled = False | ||||
| 
 | ||||
|             if software_token_mfa_settings.get("PreferredMfa"): | ||||
|                 user.preferred_mfa_setting = "SOFTWARE_TOKEN_MFA" | ||||
|         elif sms_mfa_settings and sms_mfa_settings.get("Enabled"): | ||||
|             user.sms_mfa_enabled = True | ||||
|             elif user.preferred_mfa_setting != "SMS_MFA": | ||||
|                 user.preferred_mfa_setting = "" | ||||
| 
 | ||||
|         if sms_mfa_settings: | ||||
|             if sms_mfa_settings.get("Enabled"): | ||||
|                 user.sms_mfa_enabled = True | ||||
|             else: | ||||
|                 user.sms_mfa_enabled = False | ||||
| 
 | ||||
|             if sms_mfa_settings.get("PreferredMfa"): | ||||
|                 user.preferred_mfa_setting = "SMS_MFA" | ||||
|             elif user.preferred_mfa_setting != "SOFTWARE_TOKEN_MFA": | ||||
|                 user.preferred_mfa_setting = "" | ||||
| 
 | ||||
|         return None | ||||
| 
 | ||||
|     def _validate_password(self, user_pool_id: str, password: str) -> None: | ||||
|  | ||||
| @ -4235,6 +4235,8 @@ def test_setting_mfa(): | ||||
| 
 | ||||
|     for auth_flow in ["ADMIN_NO_SRP_AUTH", "ADMIN_USER_PASSWORD_AUTH"]: | ||||
|         result = authentication_flow(conn, auth_flow) | ||||
| 
 | ||||
|         # Set MFA method | ||||
|         conn.associate_software_token(AccessToken=result["access_token"]) | ||||
|         conn.verify_software_token( | ||||
|             AccessToken=result["access_token"], UserCode="123456" | ||||
| @ -4243,12 +4245,24 @@ def test_setting_mfa(): | ||||
|             AccessToken=result["access_token"], | ||||
|             SoftwareTokenMfaSettings={"Enabled": True, "PreferredMfa": True}, | ||||
|         ) | ||||
|         result = conn.admin_get_user( | ||||
|         user = conn.admin_get_user( | ||||
|             UserPoolId=result["user_pool_id"], Username=result["username"] | ||||
|         ) | ||||
| 
 | ||||
|         assert len(result["UserMFASettingList"]) == 1 | ||||
|         assert result["PreferredMfaSetting"] == "SOFTWARE_TOKEN_MFA" | ||||
|         assert len(user["UserMFASettingList"]) == 1 | ||||
|         assert user["PreferredMfaSetting"] == "SOFTWARE_TOKEN_MFA" | ||||
| 
 | ||||
|         # Unset MFA method | ||||
|         conn.set_user_mfa_preference( | ||||
|             AccessToken=result["access_token"], | ||||
|             SoftwareTokenMfaSettings={"Enabled": False, "PreferredMfa": False}, | ||||
|         ) | ||||
|         user = conn.admin_get_user( | ||||
|             UserPoolId=result["user_pool_id"], Username=result["username"] | ||||
|         ) | ||||
| 
 | ||||
|         assert len(user["UserMFASettingList"]) == 0 | ||||
|         assert user["PreferredMfaSetting"] == "" | ||||
| 
 | ||||
| 
 | ||||
| @mock_cognitoidp | ||||
| @ -4269,7 +4283,7 @@ def test_setting_mfa_when_token_not_verified(): | ||||
| 
 | ||||
| 
 | ||||
| @mock_cognitoidp | ||||
| def test_admin_setting_mfa(): | ||||
| def test_admin_setting_single_mfa(): | ||||
|     conn = boto3.client("cognito-idp", "us-west-2") | ||||
| 
 | ||||
|     user_pool_id = conn.create_user_pool( | ||||
| @ -4278,6 +4292,7 @@ def test_admin_setting_mfa(): | ||||
|     username = "test@example.com" | ||||
|     conn.admin_create_user(UserPoolId=user_pool_id, Username=username) | ||||
| 
 | ||||
|     # Set MFA SMS method | ||||
|     conn.admin_set_user_mfa_preference( | ||||
|         Username=username, | ||||
|         UserPoolId=user_pool_id, | ||||
| @ -4287,6 +4302,50 @@ def test_admin_setting_mfa(): | ||||
|     assert len(result["UserMFASettingList"]) == 1 | ||||
|     assert result["PreferredMfaSetting"] == "SMS_MFA" | ||||
| 
 | ||||
|     # Unset MFA SMS method | ||||
|     conn.admin_set_user_mfa_preference( | ||||
|         Username=username, | ||||
|         UserPoolId=user_pool_id, | ||||
|         SMSMfaSettings={"Enabled": False, "PreferredMfa": False}, | ||||
|     ) | ||||
|     result = conn.admin_get_user(UserPoolId=user_pool_id, Username=username) | ||||
|     assert len(result["UserMFASettingList"]) == 0 | ||||
|     assert result["PreferredMfaSetting"] == "" | ||||
| 
 | ||||
| 
 | ||||
| @mock_cognitoidp | ||||
| def test_admin_setting_mfa_totp_and_sms(): | ||||
|     conn = boto3.client("cognito-idp", "us-west-2") | ||||
| 
 | ||||
|     result = authentication_flow(conn, "ADMIN_NO_SRP_AUTH") | ||||
|     access_token = result["access_token"] | ||||
|     user_pool_id = result["user_pool_id"] | ||||
|     username = result["username"] | ||||
|     conn.associate_software_token(AccessToken=access_token) | ||||
|     conn.verify_software_token(AccessToken=access_token, UserCode="123456") | ||||
| 
 | ||||
|     # Set MFA TOTP and SMS methods | ||||
|     conn.admin_set_user_mfa_preference( | ||||
|         Username=username, | ||||
|         UserPoolId=user_pool_id, | ||||
|         SoftwareTokenMfaSettings={"Enabled": True, "PreferredMfa": True}, | ||||
|         SMSMfaSettings={"Enabled": True, "PreferredMfa": False}, | ||||
|     ) | ||||
|     result = conn.admin_get_user(UserPoolId=user_pool_id, Username=username) | ||||
|     assert len(result["UserMFASettingList"]) == 2 | ||||
|     assert result["PreferredMfaSetting"] == "SOFTWARE_TOKEN_MFA" | ||||
| 
 | ||||
|     # Unset MFA TOTP and SMS methods | ||||
|     conn.admin_set_user_mfa_preference( | ||||
|         Username=username, | ||||
|         UserPoolId=user_pool_id, | ||||
|         SoftwareTokenMfaSettings={"Enabled": False, "PreferredMfa": False}, | ||||
|         SMSMfaSettings={"Enabled": False, "PreferredMfa": False}, | ||||
|     ) | ||||
|     result = conn.admin_get_user(UserPoolId=user_pool_id, Username=username) | ||||
|     assert len(result["UserMFASettingList"]) == 0 | ||||
|     assert result["PreferredMfaSetting"] == "" | ||||
| 
 | ||||
| 
 | ||||
| @mock_cognitoidp | ||||
| def test_admin_setting_mfa_when_token_not_verified(): | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user