### Question:
WebAuthnCredentialProvider implements CredentialProvider, CredentialInputValidator, CredentialInputUpdater { @Override public boolean isValid(RealmModel realm, UserModel user, CredentialInput input) { if (!WebAuthnCredentialModel.class.isInstance(input)) return false; WebAuthnCredentialModel context = WebAuthnCredentialModel.class.cast(input); List<WebAuthnCredentialModel> auths = getWebAuthnCredentialModelList(realm, user); WebAuthnAuthenticationContextValidator webAuthnAuthenticationContextValidator = new WebAuthnAuthenticationContextValidator(); try { for (WebAuthnCredentialModel auth : auths) { byte[] credentialId = auth.getAttestedCredentialData().getCredentialId(); if (Arrays.equals(credentialId, context.getAuthenticationContext().getCredentialId())) { Authenticator authenticator = new AuthenticatorImpl( auth.getAttestedCredentialData(), auth.getAttestationStatement(), auth.getCount() ); WebAuthnAuthenticationContextValidationResponse response = webAuthnAuthenticationContextValidator.validate( context.getAuthenticationContext(), authenticator); long count = auth.getCount(); auth.setCount(count + 1); CredentialModel cred = createCredentialModel(auth); session.userCredentialManager().updateCredential(realm, user, cred); dumpCredentialModel(cred); dumpWebAuthnCredentialModel(auth); return true; } } } catch (Exception e) { e.printStackTrace(); } return false; } WebAuthnCredentialProvider(KeycloakSession session); @Override boolean updateCredential(RealmModel realm, UserModel user, CredentialInput input); @Override void disableCredentialType(RealmModel realm, UserModel user, String credentialType); @Override Set<String> getDisableableCredentialTypes(RealmModel realm, UserModel user); @Override boolean supportsCredentialType(String credentialType); @Override boolean isConfiguredFor(RealmModel realm, UserModel user, String credentialType); @Override boolean isValid(RealmModel realm, UserModel user, CredentialInput input);  }### Answer:
@Test public void test_isValid() throws Exception { WebAuthnAuthenticationContext authenticationContext = getValidWebAuthnAuthenticationContext(); WebAuthnCredentialModel input = new WebAuthnCredentialModel(); input.setAuthenticationContext(authenticationContext); WebAuthnCredentialModel model = getValidWebAuthnCredentialModel(); Method method = WebAuthnCredentialProvider.class.getDeclaredMethod("createCredentialModel", CredentialInput.class); method.setAccessible(true); CredentialModel credModel = (CredentialModel)method.invoke(provider, model); when(session.userCredentialManager() .getStoredCredentialsByType(any(RealmModel.class), any(UserModel.class), anyString())) .thenReturn(Arrays.asList(credModel)); Assert.assertTrue(provider.isValid(mock(RealmModel.class), mock(UserModel.class), input)); }
@Test public void test_isValid_credential_id_unmatch() throws Exception { WebAuthnAuthenticationContext authenticationContext = getValidWebAuthnAuthenticationContext("atgcatgcatgcatgc"); WebAuthnCredentialModel input = new WebAuthnCredentialModel(); input.setAuthenticationContext(authenticationContext); WebAuthnCredentialModel model = getValidWebAuthnCredentialModel(); Method method = WebAuthnCredentialProvider.class.getDeclaredMethod("createCredentialModel", CredentialInput.class); method.setAccessible(true); CredentialModel credModel = (CredentialModel)method.invoke(provider, model); when(session.userCredentialManager() .getStoredCredentialsByType(any(RealmModel.class), any(UserModel.class), anyString())) .thenReturn(Arrays.asList(credModel)); Assert.assertFalse(provider.isValid(mock(RealmModel.class), mock(UserModel.class), input)); }