KEYCLOAK-5383 Fix creating password in LDAP through admin create user endpoint
This commit is contained in:
parent
de72542151
commit
86fb18395e
4 changed files with 65 additions and 9 deletions
|
@ -77,6 +77,7 @@ import org.keycloak.models.UserConsentModel;
|
||||||
import org.keycloak.models.UserCredentialModel;
|
import org.keycloak.models.UserCredentialModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserProvider;
|
import org.keycloak.models.UserProvider;
|
||||||
|
import org.keycloak.models.credential.PasswordUserCredentialModel;
|
||||||
import org.keycloak.provider.ProviderConfigProperty;
|
import org.keycloak.provider.ProviderConfigProperty;
|
||||||
import org.keycloak.representations.idm.ApplicationRepresentation;
|
import org.keycloak.representations.idm.ApplicationRepresentation;
|
||||||
import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
|
import org.keycloak.representations.idm.AuthenticationExecutionExportRepresentation;
|
||||||
|
@ -1444,7 +1445,7 @@ public class RepresentationToModel {
|
||||||
user.addRequiredAction(UserModel.RequiredAction.valueOf(requiredAction.toUpperCase()));
|
user.addRequiredAction(UserModel.RequiredAction.valueOf(requiredAction.toUpperCase()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
createCredentials(userRep, session, newRealm, user);
|
createCredentials(userRep, session, newRealm, user, false);
|
||||||
if (userRep.getFederatedIdentities() != null) {
|
if (userRep.getFederatedIdentities() != null) {
|
||||||
for (FederatedIdentityRepresentation identity : userRep.getFederatedIdentities()) {
|
for (FederatedIdentityRepresentation identity : userRep.getFederatedIdentities()) {
|
||||||
FederatedIdentityModel mappingModel = new FederatedIdentityModel(identity.getIdentityProvider(), identity.getUserId(), identity.getUserName());
|
FederatedIdentityModel mappingModel = new FederatedIdentityModel(identity.getIdentityProvider(), identity.getUserId(), identity.getUserName());
|
||||||
|
@ -1485,18 +1486,19 @@ public class RepresentationToModel {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void createCredentials(UserRepresentation userRep, KeycloakSession session, RealmModel realm, UserModel user) {
|
public static void createCredentials(UserRepresentation userRep, KeycloakSession session, RealmModel realm, UserModel user, boolean adminRequest) {
|
||||||
if (userRep.getCredentials() != null) {
|
if (userRep.getCredentials() != null) {
|
||||||
for (CredentialRepresentation cred : userRep.getCredentials()) {
|
for (CredentialRepresentation cred : userRep.getCredentials()) {
|
||||||
updateCredential(session, realm, user, cred);
|
updateCredential(session, realm, user, cred, adminRequest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect if it is "plain-text" or "hashed" representation and update model according to it
|
// Detect if it is "plain-text" or "hashed" representation and update model according to it
|
||||||
private static void updateCredential(KeycloakSession session, RealmModel realm, UserModel user, CredentialRepresentation cred) {
|
private static void updateCredential(KeycloakSession session, RealmModel realm, UserModel user, CredentialRepresentation cred, boolean adminRequest) {
|
||||||
if (cred.getValue() != null) {
|
if (cred.getValue() != null) {
|
||||||
UserCredentialModel plainTextCred = convertCredential(cred);
|
PasswordUserCredentialModel plainTextCred = convertCredential(cred);
|
||||||
|
plainTextCred.setAdminRequest(adminRequest);
|
||||||
session.userCredentialManager().updateCredential(realm, user, plainTextCred);
|
session.userCredentialManager().updateCredential(realm, user, plainTextCred);
|
||||||
} else {
|
} else {
|
||||||
CredentialModel hashedCred = new CredentialModel();
|
CredentialModel hashedCred = new CredentialModel();
|
||||||
|
@ -1542,8 +1544,8 @@ public class RepresentationToModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UserCredentialModel convertCredential(CredentialRepresentation cred) {
|
public static PasswordUserCredentialModel convertCredential(CredentialRepresentation cred) {
|
||||||
UserCredentialModel credential = new UserCredentialModel();
|
PasswordUserCredentialModel credential = new PasswordUserCredentialModel();
|
||||||
credential.setType(cred.getType());
|
credential.setType(cred.getType());
|
||||||
credential.setValue(cred.getValue());
|
credential.setValue(cred.getValue());
|
||||||
return credential;
|
return credential;
|
||||||
|
|
|
@ -435,7 +435,7 @@ public class KeycloakApplication extends Application {
|
||||||
} else {
|
} else {
|
||||||
UserModel user = session.users().addUser(realm, userRep.getUsername());
|
UserModel user = session.users().addUser(realm, userRep.getUsername());
|
||||||
user.setEnabled(userRep.isEnabled());
|
user.setEnabled(userRep.isEnabled());
|
||||||
RepresentationToModel.createCredentials(userRep, session, realm, user);
|
RepresentationToModel.createCredentials(userRep, session, realm, user, false);
|
||||||
RepresentationToModel.createRoleMappings(userRep, user, realm);
|
RepresentationToModel.createRoleMappings(userRep, user, realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ public class UsersResource {
|
||||||
Set<String> emptySet = Collections.emptySet();
|
Set<String> emptySet = Collections.emptySet();
|
||||||
|
|
||||||
UserResource.updateUserFromRep(user, rep, emptySet, realm, session, false);
|
UserResource.updateUserFromRep(user, rep, emptySet, realm, session, false);
|
||||||
RepresentationToModel.createCredentials(rep, session, realm, user);
|
RepresentationToModel.createCredentials(rep, session, realm, user, true);
|
||||||
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, user.getId()).representation(rep).success();
|
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, user.getId()).representation(rep).success();
|
||||||
|
|
||||||
if (session.getTransactionManager().isActive()) {
|
if (session.getTransactionManager().isActive()) {
|
||||||
|
|
|
@ -27,9 +27,12 @@ import org.junit.rules.RuleChain;
|
||||||
import org.junit.rules.TestRule;
|
import org.junit.rules.TestRule;
|
||||||
import org.junit.runners.MethodSorters;
|
import org.junit.runners.MethodSorters;
|
||||||
import org.keycloak.OAuth2Constants;
|
import org.keycloak.OAuth2Constants;
|
||||||
|
import org.keycloak.admin.client.Keycloak;
|
||||||
|
import org.keycloak.admin.client.resource.RealmResource;
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
import org.keycloak.common.util.MultivaluedHashMap;
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.credential.CredentialModel;
|
import org.keycloak.credential.CredentialModel;
|
||||||
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.LDAPConstants;
|
import org.keycloak.models.LDAPConstants;
|
||||||
import org.keycloak.models.ModelException;
|
import org.keycloak.models.ModelException;
|
||||||
|
@ -39,6 +42,8 @@ import org.keycloak.models.UserCredentialModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.representations.AccessToken;
|
import org.keycloak.representations.AccessToken;
|
||||||
|
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||||
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
import org.keycloak.storage.ReadOnlyException;
|
import org.keycloak.storage.ReadOnlyException;
|
||||||
import org.keycloak.storage.StorageId;
|
import org.keycloak.storage.StorageId;
|
||||||
|
@ -54,6 +59,7 @@ import org.keycloak.storage.ldap.mappers.HardcodedLDAPRoleStorageMapper;
|
||||||
import org.keycloak.storage.ldap.mappers.HardcodedLDAPRoleStorageMapperFactory;
|
import org.keycloak.storage.ldap.mappers.HardcodedLDAPRoleStorageMapperFactory;
|
||||||
import org.keycloak.storage.ldap.mappers.LDAPStorageMapper;
|
import org.keycloak.storage.ldap.mappers.LDAPStorageMapper;
|
||||||
import org.keycloak.storage.ldap.mappers.UserAttributeLDAPStorageMapper;
|
import org.keycloak.storage.ldap.mappers.UserAttributeLDAPStorageMapper;
|
||||||
|
import org.keycloak.testsuite.ApiUtil;
|
||||||
import org.keycloak.testsuite.OAuthClient;
|
import org.keycloak.testsuite.OAuthClient;
|
||||||
import org.keycloak.testsuite.federation.storage.ldap.LDAPTestUtils;
|
import org.keycloak.testsuite.federation.storage.ldap.LDAPTestUtils;
|
||||||
import org.keycloak.testsuite.pages.AccountPasswordPage;
|
import org.keycloak.testsuite.pages.AccountPasswordPage;
|
||||||
|
@ -67,9 +73,14 @@ import org.keycloak.testsuite.rule.WebResource;
|
||||||
import org.keycloak.testsuite.rule.WebRule;
|
import org.keycloak.testsuite.rule.WebRule;
|
||||||
import org.openqa.selenium.WebDriver;
|
import org.openqa.selenium.WebDriver;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.MASTER;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.keycloak.models.AdminRoles.ADMIN;
|
||||||
|
import static org.keycloak.testsuite.Constants.AUTH_SERVER_ROOT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
@ -885,4 +896,47 @@ public class LDAPProvidersIntegrationNoImportTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// KEYCLOAK-5383
|
||||||
|
@Test
|
||||||
|
public void addUserThroughAdmin() {
|
||||||
|
Keycloak adminClient = Keycloak.getInstance(AUTH_SERVER_ROOT, MASTER, ADMIN, ADMIN, Constants.ADMIN_CLI_CLIENT_ID);
|
||||||
|
|
||||||
|
RealmResource realm = adminClient.realm("test");
|
||||||
|
|
||||||
|
UserRepresentation user = new UserRepresentation();
|
||||||
|
user.setUsername("addUserThroughAdmin");
|
||||||
|
user.setEnabled(true);
|
||||||
|
user.setCredentials(new LinkedList<>());
|
||||||
|
|
||||||
|
CredentialRepresentation cred = new CredentialRepresentation();
|
||||||
|
cred.setType(CredentialRepresentation.PASSWORD);
|
||||||
|
cred.setValue("password");
|
||||||
|
|
||||||
|
user.getCredentials().add(cred);
|
||||||
|
|
||||||
|
Response response = realm.users().create(user);
|
||||||
|
String userId = ApiUtil.getCreatedId(response);
|
||||||
|
|
||||||
|
loginPage.open();
|
||||||
|
loginPage.login("addUserThroughAdmin", "password");
|
||||||
|
|
||||||
|
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||||
|
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
||||||
|
oauth.openLogout();
|
||||||
|
|
||||||
|
cred.setValue("password2");
|
||||||
|
realm.users().get(userId).resetPassword(cred);
|
||||||
|
|
||||||
|
loginPage.open();
|
||||||
|
loginPage.login("addUserThroughAdmin", "password2");
|
||||||
|
|
||||||
|
Assert.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||||
|
Assert.assertNotNull(oauth.getCurrentQuery().get(OAuth2Constants.CODE));
|
||||||
|
oauth.openLogout();
|
||||||
|
|
||||||
|
adminClient.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue