mirror of
https://github.com/keycloak/keycloak.git
synced 2025-12-16 20:15:46 -06:00
Fix duplicate label when using password history (#42903)
Closes #42736 Signed-off-by: Alexander Schwartz <alexander.schwartz@gmx.net>
This commit is contained in:
committed by
GitHub
parent
ac121b4c50
commit
a8d947b1a9
@@ -66,7 +66,7 @@ public class JpaUserCredentialStore implements UserCredentialStore {
|
||||
if (!Objects.equals(cred.getUserLabel(), entity.getUserLabel())) {
|
||||
// For legacy entries in the credentials, there might be a duplicate for historical reasons.
|
||||
// Ignore them when the credential is updated, which might happen when credentials are verified.
|
||||
validateDuplicateCredential(realm, user, cred.getUserLabel(), cred.getId());
|
||||
validateDuplicateCredential(realm, user, cred.getType(), cred.getUserLabel(), cred.getId());
|
||||
}
|
||||
entity.setCreatedDate(cred.getCreatedDate());
|
||||
entity.setUserLabel(cred.getUserLabel());
|
||||
@@ -135,7 +135,7 @@ public class JpaUserCredentialStore implements UserCredentialStore {
|
||||
@Override
|
||||
public CredentialModel getStoredCredentialByNameAndType(RealmModel realm, UserModel user, String name, String type) {
|
||||
return getStoredCredentialsStream(realm, user).filter(credential ->
|
||||
Objects.equals(type, credential.getType()) && Objects.equals(name, credential.getUserLabel()))
|
||||
Objects.equals(type, credential.getType()) && Objects.equals(name, credential.getUserLabel()))
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@@ -144,12 +144,13 @@ public class JpaUserCredentialStore implements UserCredentialStore {
|
||||
|
||||
}
|
||||
|
||||
private void validateDuplicateCredential(RealmModel realm, UserModel user, String userLabel, String credentialId) {
|
||||
private void validateDuplicateCredential(RealmModel realm, UserModel user, String credType, String userLabel, String credentialId) {
|
||||
if (userLabel != null) {
|
||||
boolean exists = getStoredCredentialEntities(realm, user)
|
||||
.anyMatch(existing -> existing.getUserLabel() != null
|
||||
&& existing.getUserLabel().equalsIgnoreCase(userLabel.trim())
|
||||
&& (credentialId == null || !existing.getId().equals(credentialId))); // Exclude self in update
|
||||
&& existing.getType().equals(credType)
|
||||
&& !existing.getId().equals(credentialId)); // Exclude self in update
|
||||
|
||||
if (exists) {
|
||||
throw new ModelDuplicateException("Device already exists with the same name", CredentialModel.USER_LABEL);
|
||||
@@ -158,7 +159,7 @@ public class JpaUserCredentialStore implements UserCredentialStore {
|
||||
}
|
||||
|
||||
CredentialEntity createCredentialEntity(RealmModel realm, UserModel user, CredentialModel cred) {
|
||||
validateDuplicateCredential(realm, user, cred.getUserLabel(), null);
|
||||
validateDuplicateCredential(realm, user, cred.getType(), cred.getUserLabel(), null);
|
||||
CredentialEntity entity = new CredentialEntity();
|
||||
String id = cred.getId() == null ? KeycloakModelUtils.generateId() : cred.getId();
|
||||
entity.setId(id);
|
||||
|
||||
@@ -127,6 +127,8 @@ public class PasswordCredentialProvider implements CredentialProvider<PasswordCr
|
||||
if (expiredPasswordsPolicyValue > 1 || passwordAgeInDaysPolicy > 0) {
|
||||
oldPassword.setId(null);
|
||||
oldPassword.setType(PasswordCredentialModel.PASSWORD_HISTORY);
|
||||
// Setting the label to "nulL" avoids duplicate label errors
|
||||
oldPassword.setUserLabel(null);
|
||||
oldPassword = user.credentialManager().createStoredCredential(oldPassword);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,8 @@ public class PasswordHistoryPolicyTest extends AbstractAuthTest {
|
||||
newCredential.setValue(newPassword);
|
||||
newCredential.setTemporary(false);
|
||||
userResource.resetPassword(newCredential);
|
||||
CredentialRepresentation cr = userResource.credentials().stream().filter(credentialRepresentation -> credentialRepresentation.getType().equals(PASSWORD)).findFirst().get();
|
||||
userResource.setCredentialUserLabel(cr.getId(), "My Password");
|
||||
}
|
||||
|
||||
private void expectBadRequestException(Consumer<Void> f) {
|
||||
|
||||
@@ -95,7 +95,7 @@ public class WebAuthnSigningInTest extends AbstractWebAuthnAccountTest {
|
||||
public void createWebAuthnSameUserLabel() {
|
||||
final String SAME_LABEL = "key123";
|
||||
|
||||
SigningInPage.UserCredential webAuthn = addWebAuthnCredential(SAME_LABEL, false);
|
||||
SigningInPage.UserCredential webAuthn = addWebAuthnCredential(SAME_LABEL, true);
|
||||
assertThat(webAuthn, notNullValue());
|
||||
|
||||
SigningInPage.CredentialType credentialType = webAuthnPwdlessCredentialType;
|
||||
|
||||
Reference in New Issue
Block a user