Move the rest of TestingResource methods to a utils-shared helper class (2/2) (#49241)

* Move the rest of TestingResource methods to a utils-shared helper class (2/2)

Closes: #48942

Signed-off-by: Simon Vacek <simonvacky@email.cz>

* review fix

Signed-off-by: Simon Vacek <simonvacky@email.cz>

---------

Signed-off-by: Simon Vacek <simonvacky@email.cz>
This commit is contained in:
Šimon Vacek 2026-05-27 07:51:13 +02:00 committed by GitHub
parent 5253082605
commit c27289432e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 605 additions and 823 deletions

View file

@ -51,6 +51,14 @@
<groupId>org.keycloak</groupId>
<artifactId>keycloak-services</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-model-infinispan</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-ldap-federation</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-admin-client-tests</artifactId>

View file

@ -0,0 +1,44 @@
package org.keycloak.testsuite.util.runonserver;
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
import org.keycloak.testframework.remote.providers.runonserver.FetchOnServer;
import org.keycloak.testframework.remote.providers.runonserver.FetchOnServerWrapper;
public final class CacheHelper {
public static FetchOnServerWrapper<Boolean> contains(String cacheName, String id) {
return new FetchOnServerWrapper<>() {
@Override
public FetchOnServer getRunOnServer() {
return session -> {
InfinispanConnectionProvider provider = session.getProvider(InfinispanConnectionProvider.class);
return provider.getCache(cacheName).containsKey(id);
};
}
@Override
public Class<Boolean> getResultClass() {
return Boolean.class;
}
};
}
public static FetchOnServerWrapper<Integer> size(String cacheName) {
return new FetchOnServerWrapper<>() {
@Override
public FetchOnServer getRunOnServer() {
return session -> {
InfinispanConnectionProvider provider = session.getProvider(InfinispanConnectionProvider.class);
return provider.getCache(cacheName).size();
};
}
@Override
public Class<Integer> getResultClass() {
return Integer.class;
}
};
}
}

View file

@ -0,0 +1,139 @@
package org.keycloak.testsuite.util.runonserver;
import java.util.Map;
import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.component.ComponentModel;
import org.keycloak.models.LDAPConstants;
import org.keycloak.models.RealmModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.storage.UserStorageProvider;
import org.keycloak.storage.UserStorageProviderModel;
import org.keycloak.storage.ldap.LDAPStorageProvider;
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
import org.keycloak.storage.ldap.LDAPUtils;
import org.keycloak.storage.ldap.idm.model.LDAPObject;
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
import org.keycloak.storage.ldap.mappers.membership.MembershipType;
import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapperFactory;
import org.keycloak.testframework.remote.providers.runonserver.FetchOnServer;
import org.keycloak.testframework.remote.providers.runonserver.RunOnServer;
import org.keycloak.testsuite.util.LDAPTestUtils;
import static org.keycloak.testsuite.util.LDAPTestUtils.getGroupDescriptionLDAPAttrName;
public final class LdapHelper {
/**
* @param ldapCfg configuration of LDAP provider
* @param importEnabled specify if LDAP provider will have import enabled
* @return ID of newly created provider
*/
public static FetchOnServer createLDAPProvider(Map<String,String> ldapCfg, boolean importEnabled) {
return session -> {
MultivaluedHashMap<String, String> ldapConfig = toComponentConfig(ldapCfg);
ldapConfig.putSingle(LDAPConstants.SYNC_REGISTRATIONS, "true");
ldapConfig.putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.WRITABLE.toString());
UserStorageProviderModel model = new UserStorageProviderModel();
model.setLastSync(0);
model.setChangedSyncPeriod(-1);
model.setFullSyncPeriod(-1);
model.setName("test-ldap");
model.setPriority(0);
model.setProviderId(LDAPStorageProviderFactory.PROVIDER_NAME);
model.setConfig(ldapConfig);
model.setImportEnabled(importEnabled);
model.setCachePolicy(UserStorageProviderModel.CachePolicy.MAX_LIFESPAN);
model.setMaxLifespan(600000); // Lifetime is 10 minutes
ComponentModel ldapModel = session.getContext().getRealm().addComponentModel(model);
return ldapModel.getId();
};
}
private static MultivaluedHashMap<String, String> toComponentConfig(Map<String, String> ldapConfig) {
MultivaluedHashMap<String, String> config = new MultivaluedHashMap<>();
for (Map.Entry<String, String> entry : ldapConfig.entrySet()) {
config.add(entry.getKey(), entry.getValue());
}
return config;
}
/**
* Prepare groups LDAP tests. Creates some LDAP mappers as well as some built-in GRoups and users in LDAP
*/
public static RunOnServer prepareGroupsLDAPTest() {
return session -> {
RealmModel realm = session.getContext().getRealm();
LDAPTestUtils.addLocalUser(session, realm, "mary", "mary@test.com", "password-app");
LDAPTestUtils.addLocalUser(session, realm, "john", "john@test.com", "password-app");
ComponentModel ldapModel = LDAPTestUtils.getLdapProviderModel(realm);
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
String descriptionAttrName = getGroupDescriptionLDAPAttrName(ldapFedProvider);
// Add group mapper
LDAPTestUtils.addOrUpdateGroupMapper(realm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY, descriptionAttrName);
// Remove all LDAP groups
LDAPTestUtils.removeAllLDAPGroups(session, realm, ldapModel, "groupsMapper");
// Add some groups for testing
LDAPObject group1 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "group1", descriptionAttrName, "group1 - description");
LDAPObject group11 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "group11");
LDAPObject group12 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "group12", descriptionAttrName, "group12 - description");
LDAPObject defaultGroup1 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "defaultGroup1", descriptionAttrName, "Default Group1 - description");
LDAPObject defaultGroup11 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "defaultGroup11");
LDAPObject defaultGroup12 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "defaultGroup12", descriptionAttrName, "Default Group12 - description");
LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "Team 2016/2017", descriptionAttrName, "A group with slashes in the name");
LDAPObject teamChild20182019 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "Team Child 2018/2019", descriptionAttrName, "A child group with slashes in the name");
LDAPObject teamSubChild20202021 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "Team SubChild 2020/2021", descriptionAttrName, "A sub child group with slashes in the name");
LDAPObject defaultGroup13 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "defaultGroup13", descriptionAttrName, "Default Group13 - description");
LDAPObject teamSubChild20222023 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "Team SubChild 2022/2023/A/B/C/D/E", descriptionAttrName, "A sub child group with slashes in the name");
LDAPObject defaultGroup14 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "defaultGroup14", descriptionAttrName, "Default Group14 - description");
LDAPObject teamRoot20242025 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "Team Root 2024/2025/A/B/C/D", descriptionAttrName, "A sub child group with slashes in the name");
LDAPObject defaultGroup15 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "defaultGroup15", descriptionAttrName, "Default Group15 - description");
LDAPObject teamSubChild20262027 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "Team SubChild 2026/2027", descriptionAttrName, "A sub child group with slashes in the name");
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group11);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group12);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", defaultGroup1, defaultGroup11);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", defaultGroup1, defaultGroup12);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", defaultGroup1, teamChild20182019);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", teamChild20182019, teamSubChild20202021);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", defaultGroup13, teamSubChild20222023);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", teamSubChild20222023, defaultGroup14);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", teamRoot20242025, defaultGroup15);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", defaultGroup15, teamSubChild20262027);
// Sync LDAP groups to Keycloak DB
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm, ldapModel, "groupsMapper");
new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
realm.addDefaultGroup(KeycloakModelUtils.findGroupByPath(session, realm, "/defaultGroup1/defaultGroup11"));
realm.addDefaultGroup(KeycloakModelUtils.findGroupByPath(session, realm, "/defaultGroup1/defaultGroup12"));
// Delete all LDAP users
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, realm);
// Add some LDAP users for testing
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
LDAPObject mary = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "marykeycloak", "Mary", "Kelly", "mary@email.org", null, "5678");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, mary, "Password1");
LDAPObject rob = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "robkeycloak", "Rob", "Brown", "rob@email.org", null, "8910");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, rob, "Password1");
LDAPObject james = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "jameskeycloak", "James", "Brown", "james@email.org", null, "8910");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, james, "Password1");
};
}
}

View file

@ -54,34 +54,19 @@ import org.keycloak.component.ComponentModel;
import org.keycloak.events.Event;
import org.keycloak.events.admin.AdminEvent;
import org.keycloak.http.HttpRequest;
import org.keycloak.models.AuthenticationFlowModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RealmProvider;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserProvider;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.representations.idm.AdminEventRepresentation;
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
import org.keycloak.representations.idm.EventRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.services.resource.RealmResourceProvider;
import org.keycloak.storage.UserStorageProvider;
import org.keycloak.testframework.remote.providers.runonserver.FetchOnServer;
import org.keycloak.testframework.remote.providers.runonserver.RunOnServer;
import org.keycloak.testframework.remote.providers.runonserver.SerializationUtil;
import org.keycloak.testsuite.components.amphibian.TestAmphibianProvider;
import org.keycloak.testsuite.events.TestEventsListenerProvider;
import org.keycloak.testsuite.federation.DummyUserFederationProviderFactory;
import org.keycloak.testsuite.forms.PassThroughAuthenticator;
import org.keycloak.testsuite.forms.PassThroughClientAuthenticator;
import org.keycloak.testsuite.model.infinispan.InfinispanTestUtil;
import org.keycloak.testsuite.rest.representation.AuthenticatorState;
import org.keycloak.testsuite.rest.resource.TestCacheResource;
import org.keycloak.testsuite.rest.resource.TestLDAPResource;
import org.keycloak.testsuite.util.FeatureDeployerUtil;
import org.keycloak.timer.TimerProvider;
import org.keycloak.truststore.FileTruststoreProvider;
@ -175,107 +160,10 @@ public class TestingResourceProvider implements RealmResourceProvider {
return Response.noContent().build();
}
@Path("/cache/{cache}")
public TestCacheResource getCacheResource(@PathParam("cache") String cacheName) {
return new TestCacheResource(session, cacheName);
}
@Path("/ldap/{realm}")
public TestLDAPResource ldap(@PathParam("realm") final String realmName) {
RealmModel realm = session.realms().getRealmByName(realmName);
return new TestLDAPResource(session, realm);
}
@Override
public void close() {
}
@POST
@Path("/update-pass-through-auth-state")
@Produces(MediaType.APPLICATION_JSON)
public AuthenticatorState updateAuthenticator(AuthenticatorState state) {
if (state.getClientId() != null) {
PassThroughClientAuthenticator.clientId = state.getClientId();
}
if (state.getUsername() != null) {
PassThroughAuthenticator.username = state.getUsername();
}
AuthenticatorState result = new AuthenticatorState();
result.setClientId(PassThroughClientAuthenticator.clientId);
result.setUsername(PassThroughAuthenticator.username);
return result;
}
@GET
@Path("/valid-credentials")
@Produces(MediaType.APPLICATION_JSON)
public boolean validCredentials(@QueryParam("realmName") String realmName, @QueryParam("userName") String userName, @QueryParam("password") String password) {
RealmModel realm = session.realms().getRealmByName(realmName);
if (realm == null) return false;
UserProvider userProvider = session.getProvider(UserProvider.class);
UserModel user = userProvider.getUserByUsername(realm, userName);
return user.credentialManager().isValid(UserCredentialModel.password(password));
}
@GET
@Path("/user-by-federated-identity")
@Produces(MediaType.APPLICATION_JSON)
public UserRepresentation getUserByFederatedIdentity(@QueryParam("realmName") String realmName,
@QueryParam("identityProvider") String identityProvider,
@QueryParam("userId") String userId,
@QueryParam("userName") String userName) {
RealmModel realm = getRealmByName(realmName);
UserModel foundFederatedUser = session.users().getUserByFederatedIdentity(realm, new FederatedIdentityModel(identityProvider, userId, userName));
if (foundFederatedUser == null) return null;
return ModelToRepresentation.toRepresentation(session, realm, foundFederatedUser);
}
@GET
@Path("/user-by-username-from-fed-factory")
@Produces(MediaType.APPLICATION_JSON)
public UserRepresentation getUserByUsernameFromFedProviderFactory(@QueryParam("realmName") String realmName,
@QueryParam("userName") String userName) {
RealmModel realm = getRealmByName(realmName);
DummyUserFederationProviderFactory factory = (DummyUserFederationProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(UserStorageProvider.class, "dummy");
UserModel user = factory.create(session, null).getUserByUsername(realm, userName);
if (user == null) return null;
return ModelToRepresentation.toRepresentation(session, realm, user);
}
@GET
@Path("/get-client-auth-flow")
@Produces(MediaType.APPLICATION_JSON)
public AuthenticationFlowRepresentation getClientAuthFlow(@QueryParam("realmName") String realmName) {
RealmModel realm = getRealmByName(realmName);
AuthenticationFlowModel flow = realm.getClientAuthenticationFlow();
if (flow == null) return null;
return ModelToRepresentation.toRepresentation(session, realm, flow);
}
@GET
@Path("/get-reset-cred-flow")
@Produces(MediaType.APPLICATION_JSON)
public AuthenticationFlowRepresentation getResetCredFlow(@QueryParam("realmName") String realmName) {
RealmModel realm = getRealmByName(realmName);
AuthenticationFlowModel flow = realm.getResetCredentialsFlow();
if (flow == null) return null;
return ModelToRepresentation.toRepresentation(session, realm, flow);
}
@GET
@Path("/get-user-by-service-account-client")
@Produces(MediaType.APPLICATION_JSON)
public UserRepresentation getUserByServiceAccountClient(@QueryParam("realmName") String realmName, @QueryParam("clientId") String clientId) {
RealmModel realm = getRealmByName(realmName);
ClientModel client = realm.getClientByClientId(clientId);
UserModel user = session.users().getServiceAccount(client);
if (user == null) return null;
return ModelToRepresentation.toRepresentation(session, realm, user);
}
@GET
@Path("/test-amphibian-component")
@Produces(MediaType.APPLICATION_JSON)

View file

@ -17,10 +17,12 @@
package org.keycloak.testsuite.rest.representation;
import java.io.Serializable;
/**
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
*/
public class AuthenticatorState {
public class AuthenticatorState implements Serializable {
private String clientId;
private String username;

View file

@ -1,107 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.rest.resource;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.utils.MediaType;
import org.infinispan.Cache;
import org.infinispan.stream.CacheCollectors;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class TestCacheResource {
private final Cache<Object, Object> cache;
public TestCacheResource(KeycloakSession session, String cacheName) {
InfinispanConnectionProvider provider = session.getProvider(InfinispanConnectionProvider.class);
cache = provider.getCache(cacheName);
}
@GET
@Path("/contains/{id}")
@Produces(MediaType.APPLICATION_JSON)
public boolean contains(@PathParam("id") String id) {
return cache.containsKey(id);
}
@GET
@Path("/contains-uuid/{id}")
@Produces(MediaType.APPLICATION_JSON)
public boolean containsUuid(@PathParam("id") String id) {
UUID uuid = UUID.fromString(id);
return cache.containsKey(uuid);
}
@GET
@Path("/enumerate-keys")
@Produces(MediaType.APPLICATION_JSON)
public Set<String> enumerateKeys() {
// Wrap cache.keySet into another set to avoid infinispan ClassNotFoundExceptions
Set<Object> keySet = new HashSet<>(cache.keySet());
return keySet.stream()
.map(Object::toString)
.collect(CacheCollectors.serializableCollector(Collectors::toSet)); // See https://issues.jboss.org/browse/ISPN-7596
}
@GET
@Path("/size")
@Produces(MediaType.APPLICATION_JSON)
public int size() {
return cache.size();
}
@GET
@Path("/clear")
@Consumes(MediaType.TEXT_PLAIN_UTF_8)
public void clear() {
cache.clear();
}
@POST
@Path("/remove-key/{id}")
@Produces(MediaType.APPLICATION_JSON)
public void removeKey(@PathParam("id") String id) {
cache.remove(id);
}
@POST
@Path("/process-expiration")
@Produces(MediaType.APPLICATION_JSON)
public void processExpiration() {
cache.getAdvancedCache().getExpirationManager().processExpiration();
}
}

View file

@ -1,310 +0,0 @@
/*
* Copyright 2017 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.rest.resource;
import java.util.Map;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.component.ComponentModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.LDAPConstants;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.storage.CacheableStorageProviderModel;
import org.keycloak.storage.UserStorageProvider;
import org.keycloak.storage.UserStorageProviderModel;
import org.keycloak.storage.ldap.LDAPStorageProvider;
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
import org.keycloak.storage.ldap.LDAPUtils;
import org.keycloak.storage.ldap.idm.model.LDAPObject;
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
import org.keycloak.storage.ldap.mappers.membership.MembershipType;
import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapperFactory;
import org.keycloak.storage.ldap.mappers.membership.role.RoleLDAPStorageMapperFactory;
import org.keycloak.testsuite.util.LDAPTestUtils;
import org.keycloak.utils.MediaType;
import static org.keycloak.testsuite.util.LDAPTestUtils.getGroupDescriptionLDAPAttrName;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class TestLDAPResource {
private final KeycloakSession session;
private final RealmModel realm;
public TestLDAPResource(KeycloakSession session, RealmModel realm) {
this.session = session;
this.realm = realm;
}
/**
* @param ldapCfg configuration of LDAP provider
* @param importEnabled specify if LDAP provider will have import enabled
* @return ID of newly created provider
*/
@POST
@Path("/create-ldap-provider")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public String createLDAPProvider(Map<String,String> ldapCfg, @QueryParam("import") boolean importEnabled) {
MultivaluedHashMap<String, String> ldapConfig = toComponentConfig(ldapCfg);
ldapConfig.putSingle(LDAPConstants.SYNC_REGISTRATIONS, "true");
ldapConfig.putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.WRITABLE.toString());
UserStorageProviderModel model = new UserStorageProviderModel();
model.setLastSync(0);
model.setChangedSyncPeriod(-1);
model.setFullSyncPeriod(-1);
model.setName("test-ldap");
model.setPriority(0);
model.setProviderId(LDAPStorageProviderFactory.PROVIDER_NAME);
model.setConfig(ldapConfig);
model.setImportEnabled(importEnabled);
model.setCachePolicy(UserStorageProviderModel.CachePolicy.MAX_LIFESPAN);
model.setMaxLifespan(600000); // Lifetime is 10 minutes
ComponentModel ldapModel = realm.addComponentModel(model);
return ldapModel.getId();
}
private static MultivaluedHashMap<String, String> toComponentConfig(Map<String, String> ldapConfig) {
MultivaluedHashMap<String, String> config = new MultivaluedHashMap<>();
for (Map.Entry<String, String> entry : ldapConfig.entrySet()) {
config.add(entry.getKey(), entry.getValue());
}
return config;
}
/**
* Prepare groups LDAP tests. Creates some LDAP mappers as well as some built-in GRoups and users in LDAP
*/
@POST
@Path("/configure-groups")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public void prepareGroupsLDAPTest() {
LDAPTestUtils.addLocalUser(session, realm, "mary", "mary@test.com", "password-app");
LDAPTestUtils.addLocalUser(session, realm, "john", "john@test.com", "password-app");
ComponentModel ldapModel = LDAPTestUtils.getLdapProviderModel(realm);
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
String descriptionAttrName = getGroupDescriptionLDAPAttrName(ldapFedProvider);
// Add group mapper
LDAPTestUtils.addOrUpdateGroupMapper(realm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY, descriptionAttrName);
// Remove all LDAP groups
LDAPTestUtils.removeAllLDAPGroups(session, realm, ldapModel, "groupsMapper");
// Add some groups for testing
LDAPObject group1 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "group1", descriptionAttrName, "group1 - description");
LDAPObject group11 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "group11");
LDAPObject group12 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "group12", descriptionAttrName, "group12 - description");
LDAPObject defaultGroup1 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "defaultGroup1", descriptionAttrName, "Default Group1 - description");
LDAPObject defaultGroup11 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "defaultGroup11");
LDAPObject defaultGroup12 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "defaultGroup12", descriptionAttrName, "Default Group12 - description");
LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "Team 2016/2017", descriptionAttrName, "A group with slashes in the name");
LDAPObject teamChild20182019 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "Team Child 2018/2019", descriptionAttrName, "A child group with slashes in the name");
LDAPObject teamSubChild20202021 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "Team SubChild 2020/2021", descriptionAttrName, "A sub child group with slashes in the name");
LDAPObject defaultGroup13 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "defaultGroup13", descriptionAttrName, "Default Group13 - description");
LDAPObject teamSubChild20222023 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "Team SubChild 2022/2023/A/B/C/D/E", descriptionAttrName, "A sub child group with slashes in the name");
LDAPObject defaultGroup14 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "defaultGroup14", descriptionAttrName, "Default Group14 - description");
LDAPObject teamRoot20242025 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "Team Root 2024/2025/A/B/C/D", descriptionAttrName, "A sub child group with slashes in the name");
LDAPObject defaultGroup15 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "defaultGroup15", descriptionAttrName, "Default Group15 - description");
LDAPObject teamSubChild20262027 = LDAPTestUtils.createLDAPGroup(session, realm, ldapModel, "Team SubChild 2026/2027", descriptionAttrName, "A sub child group with slashes in the name");
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group11);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, group12);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", defaultGroup1, defaultGroup11);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", defaultGroup1, defaultGroup12);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", defaultGroup1, teamChild20182019);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", teamChild20182019, teamSubChild20202021);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", defaultGroup13, teamSubChild20222023);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", teamSubChild20222023, defaultGroup14);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", teamRoot20242025, defaultGroup15);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", defaultGroup15, teamSubChild20262027);
// Sync LDAP groups to Keycloak DB
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm, ldapModel, "groupsMapper");
new GroupLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
realm.addDefaultGroup(KeycloakModelUtils.findGroupByPath(session, realm, "/defaultGroup1/defaultGroup11"));
realm.addDefaultGroup(KeycloakModelUtils.findGroupByPath(session, realm, "/defaultGroup1/defaultGroup12"));
// Delete all LDAP users
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, realm);
// Add some LDAP users for testing
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
LDAPObject mary = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "marykeycloak", "Mary", "Kelly", "mary@email.org", null, "5678");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, mary, "Password1");
LDAPObject rob = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "robkeycloak", "Rob", "Brown", "rob@email.org", null, "8910");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, rob, "Password1");
LDAPObject james = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "jameskeycloak", "James", "Brown", "james@email.org", null, "8910");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, james, "Password1");
}
/**
* Prepare roles LDAP tests. Creates some LDAP mappers as well as some built-in GRoups and users in LDAP
*/
@POST
@Path("/configure-roles")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public void prepareRolesLDAPTest() {
ComponentModel ldapModel = LDAPTestUtils.getLdapProviderModel(realm);
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
// Add role mapper
LDAPTestUtils.addOrUpdateRoleMapper(realm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY);
// Remove all LDAP groups and users
LDAPTestUtils.removeAllLDAPGroups(session, realm, ldapModel, "rolesMapper");
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, realm);
// Add some LDAP users for testing
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
LDAPObject mary = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "marykeycloak", "Mary", "Kelly", "mary@email.org", null, "5678");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, mary, "Password1");
LDAPObject rob = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "robkeycloak", "Rob", "Brown", "rob@email.org", null, "8910");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, rob, "Password1");
LDAPObject james = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "jameskeycloak", "James", "Brown", "james@email.org", null, "8910");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, james, "Password1");
// Add some groups for testing
LDAPObject group1 = LDAPTestUtils.createLDAPGroup("rolesMapper", session, realm, ldapModel, "group1");
LDAPObject group2 = LDAPTestUtils.createLDAPGroup("rolesMapper", session, realm, ldapModel, "group2");
LDAPObject group3 = LDAPTestUtils.createLDAPGroup("rolesMapper", session, realm, ldapModel, "group3");
// add the users to the groups
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, john);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, mary);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, rob);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group2, john);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group2, mary);
// Sync LDAP groups to Keycloak DB roles
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm, ldapModel, "rolesMapper");
new RoleLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
}
/**
* Prepare roles LDAP tests. Creates some LDAP mappers as well as some built-in GRoups and users in LDAP
*/
@POST
@Path("/configure-hardcoded-roles")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public void prepareHardcodedRolesLDAPTest() {
ComponentModel ldapCompModel = LDAPTestUtils.getLdapProviderModel(realm);
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapCompModel);
UserStorageProviderModel ldapModel = ldapFedProvider.getModel();
ldapModel.setCachePolicy(CacheableStorageProviderModel.CachePolicy.NO_CACHE);
ldapModel.setImportEnabled(false);
ldapModel.getConfig().putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.READ_ONLY.name());
realm.updateComponent(ldapModel);
// Add a hardcoded and composite role
RoleModel clientRole = realm.getClientByClientId("admin-cli").addRole("client_role");
RoleModel hardcodedRole = realm.addRole("hardcoded_role");
hardcodedRole.addCompositeRole(clientRole);
// Add role mapper
LDAPTestUtils.addOrUpdateHardcodedRoleMapper(realm, ldapModel);
// Remove all LDAP users
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, realm);
// Add some LDAP users for testing
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
}
/**
* Prepare roles LDAP tests. Creates some LDAP mappers as well as some built-in GRoups and users in LDAP
*/
@POST
@Path("/configure-hardcoded-groups")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public void prepareHardcodedGroupsLDAPTest() {
ComponentModel ldapCompModel = LDAPTestUtils.getLdapProviderModel(realm);
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapCompModel);
UserStorageProviderModel ldapModel = ldapFedProvider.getModel();
ldapModel.setCachePolicy(CacheableStorageProviderModel.CachePolicy.NO_CACHE);
ldapModel.setImportEnabled(false);
ldapModel.getConfig().putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.READ_ONLY.name());
realm.updateComponent(ldapModel);
// Add a hardcoded group hierarchy with role
RoleModel clientRole = realm.getClientByClientId("admin-cli").addRole("client_role");
GroupModel parentGroup = realm.createGroup("parent_group");
parentGroup.grantRole(clientRole);
GroupModel hardcodedGroup = realm.createGroup("hardcoded_group");
parentGroup.addChild(hardcodedGroup);
// Add group mapper
LDAPTestUtils.addOrUpdateHardcodedGroupMapper(realm, ldapModel);
// Remove all LDAP users
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, realm);
// Add some LDAP users for testing
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
}
/**
* Remove specified user directly just from the LDAP server
*/
@DELETE
@Path("/remove-ldap-user")
@Consumes(MediaType.APPLICATION_JSON)
public void removeLDAPUser(@QueryParam("username") String ldapUsername) {
ComponentModel ldapCompModel = LDAPTestUtils.getLdapProviderModel(realm);
UserStorageProviderModel ldapModel = new UserStorageProviderModel(ldapCompModel);
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
LDAPTestUtils.removeLDAPUserByUsername(ldapProvider, realm,
ldapProvider.getLdapIdentityStore().getConfig(), ldapUsername);
}
}

View file

@ -30,7 +30,9 @@ public class TestClassProvider {
"/com/webauthn4j",
"/com/fasterxml/jackson/dataformat/cbor",
"/org/slf4j",
"/org/apache"
"/org/apache",
"/org/keycloak/util/ldap",
"/kerberos"
};
private Undertow server;

View file

@ -1,76 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.client.resources;
import java.util.Set;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import org.keycloak.utils.MediaType;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public interface TestingCacheResource {
@GET
@Path("/contains/{id}")
@Produces(MediaType.APPLICATION_JSON)
boolean contains(@PathParam("id") String id);
@GET
@Path("/contains-uuid/{id}")
@Produces(MediaType.APPLICATION_JSON)
boolean containsUuid(@PathParam("id") String id);
@GET
@Path("/enumerate-keys")
@Produces(MediaType.APPLICATION_JSON)
Set<String> enumerateKeys();
@GET
@Path("/size")
@Produces(MediaType.APPLICATION_JSON)
int size();
@GET
@Path("/clear")
@Consumes(MediaType.TEXT_PLAIN_UTF_8)
void clear();
@POST
@Path("/remove-key/{id}")
@Produces(MediaType.APPLICATION_JSON)
void removeKey(@PathParam("id") String id);
/**
* Enforce calling of the expiration on the particular infinispan cache. This will immediately expire the expired cache entries, so that they won't be available in the cache.
* Without calling this, expired entries would be removed by the infinispan expiration (probably by infinispan periodic background cleaner task)
*/
@POST
@Path("/process-expiration")
@Produces(MediaType.APPLICATION_JSON)
void processExpiration();
}

View file

@ -1,92 +0,0 @@
/*
* Copyright 2017 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.client.resources;
import java.util.Map;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import org.keycloak.utils.MediaType;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public interface TestingLDAPResource {
/**
* @param ldapCfg configuration of LDAP provider
* @param importEnabled specify if LDAP provider will have import enabled
* @return ID of newly created provider
*/
@POST
@Path("/create-ldap-provider")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
String createLDAPProvider(Map<String,String> ldapCfg, @QueryParam("import") boolean importEnabled);
/**
* Prepare groups LDAP tests. Creates some LDAP mappers as well as some built-in GRoups and users in LDAP
*/
@POST
@Path("/configure-groups")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
void prepareGroupsLDAPTest();
/**
* Prepare hardcoded groups LDAP tests. Creates some LDAP mappers as well as some built-in Groups and users in LDAP
*/
@POST
@Path("/configure-hardcoded-groups")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
void prepareHardcodedGroupsLDAPTest();
/**
* Prepare groups LDAP tests. Creates some LDAP mappers as well as some built-in Groups and users in LDAP
*/
@POST
@Path("/configure-roles")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
void prepareRolesLDAPTest();
/**
* Prepare hardcoded roles LDAP tests. Creates some LDAP mappers as well as some hardcoded roles and users in LDAP
*/
@POST
@Path("/configure-hardcoded-roles")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
void prepareHardcodedRolesLDAPTest();
/**
* Remove specified user directly just from the LDAP server
*/
@DELETE
@Path("/remove-ldap-user")
@Consumes(MediaType.APPLICATION_JSON)
void removeLDAPUser(@QueryParam("username") String ldapUsername);
}

View file

@ -33,10 +33,7 @@ import jakarta.ws.rs.core.Response;
import org.keycloak.common.Profile;
import org.keycloak.common.enums.HostnameVerificationPolicy;
import org.keycloak.representations.idm.AdminEventRepresentation;
import org.keycloak.representations.idm.AuthenticationFlowRepresentation;
import org.keycloak.representations.idm.EventRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.rest.representation.AuthenticatorState;
import org.keycloak.utils.MediaType;
import org.infinispan.commons.time.TimeService;
@ -85,57 +82,11 @@ public interface TestingResource {
@Produces(MediaType.APPLICATION_JSON)
void revertTestingInfinispanTimeService();
@Path("/cache/{cache}")
TestingCacheResource cache(@PathParam("cache") String cacheName);
@Path("/ldap/{realm}")
TestingLDAPResource ldap(@PathParam("realm") final String realmName);
@POST
@Path("/update-pass-through-auth-state")
@Produces(MediaType.APPLICATION_JSON)
AuthenticatorState updateAuthenticator(AuthenticatorState state);
@GET
@Path("/valid-credentials")
@Produces(MediaType.APPLICATION_JSON)
public boolean validCredentials(@QueryParam("realmName") String realmName, @QueryParam("userName") String userName, @QueryParam("password") String password);
@GET
@Path("/user-by-federated-identity")
@Produces(MediaType.APPLICATION_JSON)
public UserRepresentation getUserByFederatedIdentity(@QueryParam("realmName") String realmName,
@QueryParam("identityProvider") String identityProvider,
@QueryParam("userId") String userId,
@QueryParam("userName") String userName);
@GET
@Path("/user-by-username-from-fed-factory")
@Produces(MediaType.APPLICATION_JSON)
public UserRepresentation getUserByUsernameFromFedProviderFactory(@QueryParam("realmName") String realmName,
@QueryParam("userName") String userName);
@GET
@Path("/get-client-auth-flow")
@Produces(MediaType.APPLICATION_JSON)
public AuthenticationFlowRepresentation getClientAuthFlow(@QueryParam("realmName") String realmName);
@GET
@Path("/get-reset-cred-flow")
@Produces(MediaType.APPLICATION_JSON)
public AuthenticationFlowRepresentation getResetCredFlow(@QueryParam("realmName") String realmName);
@GET
@Path("/get-user-by-service-account-client")
@Produces(MediaType.APPLICATION_JSON)
public UserRepresentation getUserByServiceAccountClient(@QueryParam("realmName") String realmName, @QueryParam("clientId") String clientId);
@GET
@Path("/test-amphibian-component")
@Produces(MediaType.APPLICATION_JSON)
Map<String, Map<String, Object>> getTestAmphibianComponentDetails();
@PUT
@Path("/set-krb5-conf-file")
@Consumes(MediaType.APPLICATION_JSON)

View file

@ -45,11 +45,12 @@ import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.representations.idm.KeysMetadataRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.broker.util.SimpleHttpDefault;
import org.keycloak.testsuite.client.resources.TestingCacheResource;
import org.keycloak.testsuite.client.KeycloakTestingClient;
import org.keycloak.testsuite.updaters.ClientAttributeUpdater;
import org.keycloak.testsuite.util.AccountHelper;
import org.keycloak.testsuite.util.broker.OIDCIdentityProviderConfigRep;
import org.keycloak.testsuite.util.oauth.OAuthClient;
import org.keycloak.testsuite.util.runonserver.CacheHelper;
import org.junit.Before;
import org.junit.Test;
@ -416,7 +417,7 @@ public class KcOIDCBrokerWithSignatureTest extends AbstractBaseBrokerTest {
@Test
public void testClearKeysCache() throws Exception {
public void testClearKeysCache() {
// Configure OIDC identity provider with JWKS URL
updateIdentityProviderWithJwksUrl();
@ -429,13 +430,13 @@ public class KcOIDCBrokerWithSignatureTest extends AbstractBaseBrokerTest {
// Check that key is cached
IdentityProviderRepresentation idpRep = getIdentityProvider();
String expectedCacheKey = PublicKeyStorageUtils.getIdpModelCacheKey(consumerRealm().toRepresentation().getId(), idpRep.getInternalId());
TestingCacheResource cache = testingClient.testing(bc.consumerRealmName()).cache(InfinispanConnectionProvider.KEYS_CACHE_NAME);
Assertions.assertTrue(cache.contains(expectedCacheKey));
KeycloakTestingClient.Server runOnServerConsumer = testingClient.server(bc.consumerRealmName());
Assertions.assertTrue(runOnServerConsumer.fetch(CacheHelper.contains(InfinispanConnectionProvider.KEYS_CACHE_NAME, expectedCacheKey)));
// Clear cache and check nothing cached
consumerRealm().clearKeysCache();
Assertions.assertFalse(cache.contains(expectedCacheKey));
Assertions.assertEquals(cache.size(), 0);
Assertions.assertFalse(runOnServerConsumer.fetch(CacheHelper.contains(InfinispanConnectionProvider.KEYS_CACHE_NAME, expectedCacheKey)));
Assertions.assertEquals(0, runOnServerConsumer.fetch(CacheHelper.size(InfinispanConnectionProvider.KEYS_CACHE_NAME)));
}
@ -454,8 +455,8 @@ public class KcOIDCBrokerWithSignatureTest extends AbstractBaseBrokerTest {
// Check that key is cached
IdentityProviderRepresentation idpRep = getIdentityProvider();
String expectedCacheKey = PublicKeyStorageUtils.getIdpModelCacheKey(consumerRealm().toRepresentation().getId(), idpRep.getInternalId());
TestingCacheResource cache = testingClient.testing(bc.consumerRealmName()).cache(InfinispanConnectionProvider.KEYS_CACHE_NAME);
Assertions.assertTrue(cache.contains(expectedCacheKey));
KeycloakTestingClient.Server runOnServerConsumer = testingClient.server(bc.consumerRealmName());
Assertions.assertTrue(runOnServerConsumer.fetch(CacheHelper.contains(InfinispanConnectionProvider.KEYS_CACHE_NAME, expectedCacheKey)));
// Update identityProvider to some bad JWKS_URL
OIDCIdentityProviderConfigRep cfg = new OIDCIdentityProviderConfigRep(idpRep);
@ -463,7 +464,7 @@ public class KcOIDCBrokerWithSignatureTest extends AbstractBaseBrokerTest {
updateIdentityProvider(idpRep);
// Check that key is not cached anymore
Assertions.assertFalse(cache.contains(expectedCacheKey));
Assertions.assertFalse(runOnServerConsumer.fetch(CacheHelper.contains(InfinispanConnectionProvider.KEYS_CACHE_NAME, expectedCacheKey)));
// Check that user is not able to login with IDP
timeOffSet.set(20);

View file

@ -51,6 +51,7 @@ import org.keycloak.testsuite.client.resources.TestOIDCEndpointsApplicationResou
import org.keycloak.testsuite.rest.resource.TestingOIDCEndpointsApplicationResource;
import org.keycloak.testsuite.util.oauth.AccessTokenResponse;
import org.keycloak.testsuite.util.oauth.OAuthClient;
import org.keycloak.testsuite.util.runonserver.CacheHelper;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
@ -200,7 +201,7 @@ public class OIDCJwksClientRegistrationTest extends AbstractClientRegistrationTe
// Assert item in publicKey cache for client1
String expectedCacheKey = PublicKeyStorageUtils.getClientModelCacheKey(
adminClient.realm(REALM_NAME).toRepresentation().getId(), response.getClientId());
Assertions.assertTrue(testingClient.testing().cache(InfinispanConnectionProvider.KEYS_CACHE_NAME).contains(expectedCacheKey));
Assertions.assertTrue(runOnServerMaster.fetch(CacheHelper.contains(InfinispanConnectionProvider.KEYS_CACHE_NAME, expectedCacheKey)));
// Assert it's not possible to authenticate as client2 with the same "kid" like client1
assertAuthenticateClientError(generatedKeys, clientRep2, "a1");
@ -219,7 +220,7 @@ public class OIDCJwksClientRegistrationTest extends AbstractClientRegistrationTe
// Assert item in publicKey cache for client1
String expectedCacheKey = PublicKeyStorageUtils.getClientModelCacheKey(
adminClient.realm(REALM_NAME).toRepresentation().getId(), response.getClientId());
Assertions.assertTrue(testingClient.testing().cache(InfinispanConnectionProvider.KEYS_CACHE_NAME).contains(expectedCacheKey));
Assertions.assertTrue(runOnServerMaster.fetch(CacheHelper.contains(InfinispanConnectionProvider.KEYS_CACHE_NAME, expectedCacheKey)));
@ -230,7 +231,7 @@ public class OIDCJwksClientRegistrationTest extends AbstractClientRegistrationTe
.oidc().update(response);
// Assert item not any longer for client1
Assertions.assertFalse(testingClient.testing().cache(InfinispanConnectionProvider.KEYS_CACHE_NAME).contains(expectedCacheKey));
Assertions.assertFalse(runOnServerMaster.fetch(CacheHelper.contains(InfinispanConnectionProvider.KEYS_CACHE_NAME, expectedCacheKey)));
// Assert it's not possible to authenticate as client1
assertAuthenticateClientError(generatedKeys, response, "a1");

View file

@ -40,7 +40,10 @@ import org.keycloak.exportimport.dir.DirExportProvider;
import org.keycloak.exportimport.dir.DirExportProviderFactory;
import org.keycloak.exportimport.singlefile.SingleFileExportProviderFactory;
import org.keycloak.exportimport.util.ImportUtils;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserProvider;
import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation;
import org.keycloak.representations.idm.ComponentRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
@ -52,10 +55,13 @@ import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.userprofile.config.UPConfig;
import org.keycloak.testframework.realm.UserBuilder;
import org.keycloak.testframework.remote.providers.runonserver.FetchOnServer;
import org.keycloak.testframework.remote.providers.runonserver.FetchOnServerWrapper;
import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.arquillian.annotation.UncaughtServerErrorExpected;
import org.keycloak.testsuite.client.KeycloakTestingClient;
import org.keycloak.testsuite.util.JsonTestUtils;
import org.keycloak.testsuite.util.runonserver.ExportImportHelper;
import org.keycloak.testsuite.util.runonserver.RunHelpers;
@ -67,6 +73,7 @@ import org.apache.commons.io.FileUtils;
import org.hamcrest.Matchers;
import org.jboss.arquillian.container.spi.client.container.LifecycleException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
@ -90,6 +97,12 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class ExportImportTest extends AbstractKeycloakTest {
private static final String TEST_REALM = "test-realm";
private KeycloakTestingClient.Server runOnServerTestRealm;
@Before
public void setup() {
runOnServerTestRealm = testingClient.server("test-realm");
}
@Override
public void addTestRealms(List<RealmRepresentation> testRealms) {
@ -186,7 +199,7 @@ public class ExportImportTest extends AbstractKeycloakTest {
testFullExportImport();
RealmResource testRealmRealm = adminClient.realm(TEST_REALM);
ExportImportUtil.assertDataImportedInRealm(adminClient, testingClient, testRealmRealm.toRepresentation());
ExportImportUtil.assertDataImportedInRealm(adminClient, runOnServerTestRealm, testRealmRealm.toRepresentation());
// There should be 6 files in target directory (3 realm, 3 user)
assertEquals(6, new File(targetDirPath).listFiles().length);
@ -203,7 +216,7 @@ public class ExportImportTest extends AbstractKeycloakTest {
testRealmExportImport();
RealmResource testRealmRealm = adminClient.realm(TEST_REALM);
ExportImportUtil.assertDataImportedInRealm(adminClient, testingClient, testRealmRealm.toRepresentation());
ExportImportUtil.assertDataImportedInRealm(adminClient, runOnServerTestRealm, testRealmRealm.toRepresentation());
// There should be 5 files in target directory (1 realm, 16 users, 5 users per file)
// (+ additional user service-account-test-app-authz that should not be there ???)
@ -260,7 +273,7 @@ public class ExportImportTest extends AbstractKeycloakTest {
RealmResource testRealmRealm = adminClient.realm(TEST_REALM);
ExportImportUtil.assertDataImportedInRealm(adminClient, testingClient, testRealmRealm.toRepresentation());
ExportImportUtil.assertDataImportedInRealm(adminClient, runOnServerTestRealm, testRealmRealm.toRepresentation());
}
@Test
@ -495,12 +508,12 @@ public class ExportImportTest extends AbstractKeycloakTest {
requiredActionsBeforeImport.put(action.getAlias(), action);
});
assertNotAuthenticated("test", "test-user@localhost", "password");
assertNotAuthenticated("test", "user1", "password");
assertNotAuthenticated("test", "user2", "password");
assertNotAuthenticated("test", "user3", "password");
assertNotAuthenticated("test", "user-requiredOTP", "password");
assertNotAuthenticated("test", "user-requiredWebAuthn", "password");
assertNotAuthenticated("test-user@localhost", "password");
assertNotAuthenticated("user1", "password");
assertNotAuthenticated("user2", "password");
assertNotAuthenticated("user3", "password");
assertNotAuthenticated("user-requiredOTP", "password");
assertNotAuthenticated("user-requiredWebAuthn", "password");
// Configure import
@ -511,12 +524,12 @@ public class ExportImportTest extends AbstractKeycloakTest {
// Ensure data are imported back
Assert.assertNames(adminClient.realms().findAll(), "master", "test", TEST_REALM);
assertAuthenticated("test", "test-user@localhost", "password");
assertAuthenticated("test", "user1", "password");
assertAuthenticated("test", "user2", "password");
assertAuthenticated("test", "user3", "password");
assertAuthenticated("test", "user-requiredOTP", "password");
assertAuthenticated("test", "user-requiredWebAuthn", "password");
assertAuthenticated("test-user@localhost", "password");
assertAuthenticated("user1", "password");
assertAuthenticated("user2", "password");
assertAuthenticated("user3", "password");
assertAuthenticated("user-requiredOTP", "password");
assertAuthenticated("user-requiredWebAuthn", "password");
RealmResource testRealmRealm = adminClient.realm("test");
assertTrue(testRealmRealm.users().search("user-requiredOTP").get(0)
@ -525,7 +538,7 @@ public class ExportImportTest extends AbstractKeycloakTest {
.getRequiredActions().get(0).equals(WebAuthnRegisterFactory.PROVIDER_ID));
// KEYCLOAK-6050 Check SMTP password is exported/imported
assertEquals("secret", testingClient.server("test").fetch(RunHelpers.internalRealm()).getSmtpServer().get("password"));
assertEquals("secret", runOnServer.fetch(RunHelpers.internalRealm()).getSmtpServer().get("password"));
// KEYCLOAK-8176 Check required actions are exported/imported properly
List<RequiredActionProviderRepresentation> requiredActionsAfterImport = adminClient.realm("master").flows().getRequiredActions();
@ -560,12 +573,12 @@ public class ExportImportTest extends AbstractKeycloakTest {
Assert.assertNames(adminClient.realms().findAll(), TEST_REALM, "master");
assertNotAuthenticated("test", "test-user@localhost", "password");
assertNotAuthenticated("test", "user1", "password");
assertNotAuthenticated("test", "user2", "password");
assertNotAuthenticated("test", "user3", "password");
assertNotAuthenticated("test", "user-requiredOTP", "password");
assertNotAuthenticated("test", "user-requiredWebAuthn", "password");
assertNotAuthenticated("test-user@localhost", "password");
assertNotAuthenticated("user1", "password");
assertNotAuthenticated("user2", "password");
assertNotAuthenticated("user3", "password");
assertNotAuthenticated("user-requiredOTP", "password");
assertNotAuthenticated("user-requiredWebAuthn", "password");
// Configure import
runOnServerMaster.run(ExportImportHelper.setAction(ExportImportConfig.ACTION_IMPORT));
@ -575,12 +588,12 @@ public class ExportImportTest extends AbstractKeycloakTest {
// Ensure data are imported back, but just for "test" realm
Assert.assertNames(adminClient.realms().findAll(), "master", "test", TEST_REALM);
assertAuthenticated("test", "test-user@localhost", "password");
assertAuthenticated("test", "user1", "password");
assertAuthenticated("test", "user2", "password");
assertAuthenticated("test", "user3", "password");
assertAuthenticated("test", "user-requiredOTP", "password");
assertAuthenticated("test", "user-requiredWebAuthn", "password");
assertAuthenticated("test-user@localhost", "password");
assertAuthenticated("user1", "password");
assertAuthenticated("user2", "password");
assertAuthenticated("user3", "password");
assertAuthenticated("user-requiredOTP", "password");
assertAuthenticated("user-requiredWebAuthn", "password");
RealmResource testRealmRealm = adminClient.realm("test");
assertTrue(testRealmRealm.users().search("user-requiredOTP").get(0)
@ -613,16 +626,16 @@ public class ExportImportTest extends AbstractKeycloakTest {
checkEventsConfig(adminClient.realm("test").getRealmEventsConfig());
}
private void assertAuthenticated(String realmName, String username, String password) {
assertAuth(true, realmName, username, password);
private void assertAuthenticated(String username, String password) {
assertAuth(true, username, password);
}
private void assertNotAuthenticated(String realmName, String username, String password) {
assertAuth(false, realmName, username, password);
private void assertNotAuthenticated(String username, String password) {
assertAuth(false, username, password);
}
private void assertAuth(boolean expectedResult, String realmName, String username, String password) {
assertEquals(expectedResult, testingClient.testing().validCredentials(realmName, username, password));
private void assertAuth(boolean expectedResult, String username, String password) {
assertEquals(expectedResult, runOnServerMaster.fetch(validCredentials(username, password)));
}
private void assertComponents(List<ComponentRepresentation> expected, List<ComponentRepresentation> actual) {
@ -696,4 +709,27 @@ public class ExportImportTest extends AbstractKeycloakTest {
runOnServerMaster.run(ExportImportHelper.runImport());
}
private static FetchOnServerWrapper<Boolean> validCredentials(String userName, String password) {
return new FetchOnServerWrapper<>() {
@Override
public FetchOnServer getRunOnServer() {
return session -> {
RealmModel realm = session.realms().getRealmByName("test");
if (realm == null) {
return false;
}
UserProvider userProvider = session.getProvider(UserProvider.class);
UserModel user = userProvider.getUserByUsername(realm, userName);
return user.credentialManager().isValid(UserCredentialModel.password(password));
};
}
@Override
public Class<Boolean> getResultClass() {
return Boolean.class;
}
};
}
}

View file

@ -40,11 +40,17 @@ import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.common.Profile;
import org.keycloak.common.constants.KerberosConstants;
import org.keycloak.common.constants.ServiceAccountConstants;
import org.keycloak.models.AuthenticationFlowModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.LDAPConstants;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.credential.PasswordCredentialModel;
import org.keycloak.models.credential.dto.PasswordCredentialData;
import org.keycloak.models.utils.DefaultAuthenticationFlows;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.protocol.oidc.OIDCConfigAttributes;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
@ -73,9 +79,12 @@ import org.keycloak.storage.UserStorageProvider;
import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapper;
import org.keycloak.storage.ldap.mappers.FullNameLDAPStorageMapperFactory;
import org.keycloak.storage.ldap.mappers.LDAPStorageMapper;
import org.keycloak.testframework.remote.providers.runonserver.FetchOnServer;
import org.keycloak.testframework.remote.providers.runonserver.FetchOnServerWrapper;
import org.keycloak.testsuite.ProfileAssume;
import org.keycloak.testsuite.admin.AdminApiUtil;
import org.keycloak.testsuite.client.KeycloakTestingClient;
import org.keycloak.testsuite.federation.DummyUserFederationProviderFactory;
import org.keycloak.util.JsonSerialization;
import org.hamcrest.Matcher;
@ -93,7 +102,7 @@ public class ExportImportUtil {
// In the old testsuite, this method exists as a public method of ImportTest from the model package.
// However, model package is not ready to be migrated yet.
public static void assertDataImportedInRealm(Keycloak adminClient, KeycloakTestingClient testingClient, RealmRepresentation realm) throws IOException {
public static void assertDataImportedInRealm(Keycloak adminClient, KeycloakTestingClient.Server runOnServer, RealmRepresentation realm) throws IOException {
Assertions.assertTrue(realm.isVerifyEmail());
Assertions.assertEquals((Integer)3600000, realm.getOfflineSessionIdleTimeout());
Assertions.assertEquals((Integer)1500, realm.getAccessTokenLifespanForImplicitFlow());
@ -272,9 +281,9 @@ public class ExportImportUtil {
Assertions.assertEquals(1, socialLowercaseLinks.size());
Assertions.assertEquals("lowercasesocialuser@gmail.com", socialLowercaseLinks.get(0).getUserName());
UserRepresentation foundSocialUser = testingClient.testing(realm.getRealm()).getUserByFederatedIdentity(realm.getRealm(), "facebook1", "facebook1", "fbuser1");
UserRepresentation foundSocialUser = runOnServer.fetch(getUserByFederatedIdentity("facebook1", "facebook1", "fbuser1"));
Assertions.assertEquals(foundSocialUser.getUsername(), socialUser.toRepresentation().getUsername());
Assertions.assertNull(testingClient.testing(realm.getRealm()).getUserByFederatedIdentity(realm.getRealm(), "facebook", "not-existing", "not-existing"));
Assertions.assertNull(runOnServer.fetch(getUserByFederatedIdentity("facebook", "not-existing", "not-existing")));
Assertions.assertEquals("facebook1", facebookIdentityRep.getUserId());
Assertions.assertEquals("fbuser1", facebookIdentityRep.getUserName());
@ -337,15 +346,15 @@ public class ExportImportUtil {
/////////////////
// Assert that federation link wasn't created during import
Assertions.assertNull(testingClient.testing(realm.getRealm()).getUserByUsernameFromFedProviderFactory(realm.getRealm(), "wburke"));
Assertions.assertNull(runOnServer.fetch(getUserByUsernameFromFedProviderFactory("wburke")));
// Test builtin authentication flows
AuthenticationFlowRepresentation clientFlow = testingClient.testing(realm.getRealm()).getClientAuthFlow(realm.getRealm());
AuthenticationFlowRepresentation clientFlow = runOnServer.fetch(getClientAuthFlow());
Assertions.assertEquals(DefaultAuthenticationFlows.CLIENT_AUTHENTICATION_FLOW, clientFlow.getAlias());
Assertions.assertNotNull(realmRsc.flows().getFlow(clientFlow.getId()));
Assertions.assertTrue(realmRsc.flows().getExecutions(clientFlow.getAlias()).size() > 0);
AuthenticationFlowRepresentation resetFlow = testingClient.testing(realm.getRealm()).getResetCredFlow(realm.getRealm());
AuthenticationFlowRepresentation resetFlow = runOnServer.fetch(getResetCredFlow());
Assertions.assertEquals(DefaultAuthenticationFlows.RESET_CREDENTIALS_FLOW, resetFlow.getAlias());
Assertions.assertNotNull(realmRsc.flows().getFlow(resetFlow.getId()));
Assertions.assertTrue(realmRsc.flows().getExecutions(resetFlow.getAlias()).size() > 0);
@ -424,11 +433,11 @@ public class ExportImportUtil {
if (ProfileAssume.isFeatureEnabled(Profile.Feature.AUTHORIZATION)) {
Assertions.assertTrue(testAppAuthzApp.isServiceAccountsEnabled());
Assertions.assertNull(testingClient.testing(realm.getRealm()).getUserByServiceAccountClient(realm.getRealm(), application.getClientId()));//session.users().getUserByServiceAccountClient(application));
UserRepresentation otherAppSA = testingClient.testing(realm.getRealm()).getUserByServiceAccountClient(realm.getRealm(), otherApp.getClientId());//session.users().getUserByServiceAccountClient(otherApp);
Assertions.assertNull(runOnServer.fetch(getUserByServiceAccountClient(application.getClientId())));//session.users().getUserByServiceAccountClient(application));
UserRepresentation otherAppSA = runOnServer.fetch(getUserByServiceAccountClient(otherApp.getClientId()));//session.users().getUserByServiceAccountClient(otherApp);
Assertions.assertNotNull(otherAppSA);
Assertions.assertEquals("service-account-otherapp", otherAppSA.getUsername());
UserRepresentation testAppAuthzSA = testingClient.testing(realm.getRealm()).getUserByServiceAccountClient(realm.getRealm(), testAppAuthzApp.getClientId());
UserRepresentation testAppAuthzSA = runOnServer.fetch(getUserByServiceAccountClient(testAppAuthzApp.getClientId()));
Assertions.assertNotNull(testAppAuthzSA);
Assertions.assertEquals("service-account-test-app-authz", testAppAuthzSA.getUsername());
@ -782,4 +791,109 @@ public class ExportImportUtil {
}
}
}
private static FetchOnServerWrapper<UserRepresentation> getUserByServiceAccountClient(String clientId) {
return new FetchOnServerWrapper<>() {
@Override
public FetchOnServer getRunOnServer() {
return session -> {
RealmModel realm = session.getContext().getRealm();
ClientModel client = realm.getClientByClientId(clientId);
UserModel user = session.users().getServiceAccount(client);
if (user == null) return null;
return ModelToRepresentation.toRepresentation(session, realm, user);
};
}
@Override
public Class<UserRepresentation> getResultClass() {
return UserRepresentation.class;
}
};
}
private static FetchOnServerWrapper<AuthenticationFlowRepresentation> getResetCredFlow() {
return new FetchOnServerWrapper<>() {
@Override
public FetchOnServer getRunOnServer() {
return session -> {
RealmModel realm = session.getContext().getRealm();
AuthenticationFlowModel flow = realm.getResetCredentialsFlow();
if (flow == null) return null;
return ModelToRepresentation.toRepresentation(session, realm, flow);
};
}
@Override
public Class<AuthenticationFlowRepresentation> getResultClass() {
return AuthenticationFlowRepresentation.class;
}
};
}
private static FetchOnServerWrapper<AuthenticationFlowRepresentation> getClientAuthFlow() {
return new FetchOnServerWrapper<>() {
@Override
public FetchOnServer getRunOnServer() {
return session -> {
RealmModel realm = session.getContext().getRealm();
AuthenticationFlowModel flow = realm.getClientAuthenticationFlow();
if (flow == null) return null;
return ModelToRepresentation.toRepresentation(session, realm, flow);
};
}
@Override
public Class<AuthenticationFlowRepresentation> getResultClass() {
return AuthenticationFlowRepresentation.class;
}
};
}
private static FetchOnServerWrapper<UserRepresentation> getUserByUsernameFromFedProviderFactory(String userName) {
return new FetchOnServerWrapper<>() {
@Override
public FetchOnServer getRunOnServer() {
return session -> {
RealmModel realm = session.getContext().getRealm();
DummyUserFederationProviderFactory factory = (DummyUserFederationProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(UserStorageProvider.class, "dummy");
UserModel user = factory.create(session, null).getUserByUsername(realm, userName);
if (user == null) return null;
return ModelToRepresentation.toRepresentation(session, realm, user);
};
}
@Override
public Class<UserRepresentation> getResultClass() {
return UserRepresentation.class;
}
};
}
private static FetchOnServerWrapper<UserRepresentation> getUserByFederatedIdentity(String identityProvider,
String userId,
String userName) {
return new FetchOnServerWrapper<>() {
@Override
public FetchOnServer getRunOnServer() {
return session -> {
RealmModel realm = session.getContext().getRealm();
UserModel foundFederatedUser = session.users().getUserByFederatedIdentity(realm, new FederatedIdentityModel(identityProvider, userId, userName));
if (foundFederatedUser == null) return null;
return ModelToRepresentation.toRepresentation(session, realm, foundFederatedUser);
};
}
@Override
public Class<UserRepresentation> getResultClass() {
return UserRepresentation.class;
}
};
}
}

View file

@ -20,13 +20,19 @@ package org.keycloak.testsuite.federation.kerberos;
import jakarta.ws.rs.core.Response;
import org.keycloak.common.constants.KerberosConstants;
import org.keycloak.component.ComponentModel;
import org.keycloak.federation.kerberos.CommonKerberosConfig;
import org.keycloak.models.RealmModel;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.idm.ComponentRepresentation;
import org.keycloak.storage.UserStorageProviderModel;
import org.keycloak.storage.ldap.LDAPStorageProvider;
import org.keycloak.storage.ldap.LDAPStorageProviderFactory;
import org.keycloak.storage.ldap.kerberos.LDAPProviderKerberosConfig;
import org.keycloak.testframework.remote.providers.runonserver.RunOnServer;
import org.keycloak.testsuite.KerberosEmbeddedServer;
import org.keycloak.testsuite.util.KerberosRule;
import org.keycloak.testsuite.util.LDAPTestUtils;
import org.keycloak.testsuite.util.TestAppHelper;
import org.keycloak.testsuite.util.oauth.AccessTokenResponse;
@ -155,7 +161,7 @@ public class KerberosLdapCrossRealmTrustTest extends AbstractKerberosTest {
public void test05DisableTrust() throws Exception {
// Remove the LDAP entry corresponding to the Kerberos principal krbtgt/KEYCLOAK.ORG@KC2.COM
// This will effectively disable kerberos cross-realm trust
testingClient.testing().ldap("test").removeLDAPUser("krbtgt2");
runOnServer.run(removeLDAPUser("krbtgt2"));
// There is no trust among kerberos realms anymore. SPNEGO shouldn't work. There would be failure even on Apache HTTP client side
@ -169,4 +175,19 @@ public class KerberosLdapCrossRealmTrustTest extends AbstractKerberosTest {
}
/**
* Remove specified user directly just from the LDAP server
*/
public static RunOnServer removeLDAPUser(String ldapUsername) {
return session -> {
RealmModel realm = session.getContext().getRealm();
ComponentModel ldapCompModel = LDAPTestUtils.getLdapProviderModel(realm);
UserStorageProviderModel ldapModel = new UserStorageProviderModel(ldapCompModel);
LDAPStorageProvider ldapProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
LDAPTestUtils.removeLDAPUserByUsername(ldapProvider, realm,
ldapProvider.getLdapIdentityStore().getConfig(), ldapUsername);
};
}
}

View file

@ -30,6 +30,7 @@ import org.keycloak.testsuite.pages.LoginPasswordUpdatePage;
import org.keycloak.testsuite.pages.OAuthGrantPage;
import org.keycloak.testsuite.pages.RegisterPage;
import org.keycloak.testsuite.util.LDAPRule;
import org.keycloak.testsuite.util.runonserver.LdapHelper;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Rule;
@ -79,7 +80,7 @@ public abstract class AbstractLDAPTest extends AbstractTestRealmKeycloakTest {
protected void createLDAPProvider() {
Map<String, String> cfg = getLDAPRule().getConfig();
ldapModelId = testingClient.testing().ldap(TEST_REALM_NAME).createLDAPProvider(cfg, isImportEnabled());
ldapModelId = runOnServer.fetchString(LdapHelper.createLDAPProvider(cfg, isImportEnabled())).replace("\"", "");
Assertions.assertEquals(22, ldapModelId.length(), "Short ID not used for ldap id");
log.infof("LDAP Provider created");
}

View file

@ -46,6 +46,7 @@ import org.keycloak.storage.ldap.mappers.membership.group.GroupLDAPStorageMapper
import org.keycloak.storage.ldap.mappers.membership.group.GroupMapperConfig;
import org.keycloak.testsuite.util.LDAPRule;
import org.keycloak.testsuite.util.LDAPTestUtils;
import org.keycloak.testsuite.util.runonserver.LdapHelper;
import org.junit.ClassRule;
import org.junit.FixMethodOrder;
@ -77,7 +78,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
@Override
protected void afterImportTestRealm() {
testingClient.testing().ldap(TEST_REALM_NAME).prepareGroupsLDAPTest();
runOnServer.run(LdapHelper.prepareGroupsLDAPTest());
}
@Override

View file

@ -18,11 +18,20 @@ package org.keycloak.testsuite.federation.ldap;
import java.io.Serializable;
import org.keycloak.component.ComponentModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.LDAPConstants;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.storage.CacheableStorageProviderModel;
import org.keycloak.storage.UserStorageProvider;
import org.keycloak.storage.UserStorageProviderModel;
import org.keycloak.storage.ldap.LDAPStorageProvider;
import org.keycloak.storage.ldap.idm.model.LDAPObject;
import org.keycloak.testframework.remote.providers.runonserver.RunOnServer;
import org.keycloak.testsuite.util.LDAPRule;
import org.keycloak.testsuite.util.LDAPTestUtils;
import org.junit.ClassRule;
import org.junit.Test;
@ -47,7 +56,7 @@ public class LDAPHardcodedGroupMapperTest extends AbstractLDAPTest implements Se
@Override
protected void afterImportTestRealm() {
testingClient.testing().ldap(TEST_REALM_NAME).prepareHardcodedGroupsLDAPTest();
runOnServer.run(prepareHardcodedGroupsLDAPTest());
}
/**
@ -86,4 +95,37 @@ public class LDAPHardcodedGroupMapperTest extends AbstractLDAPTest implements Se
});
}
/**
* Prepare hardcoded groups LDAP tests. Creates some LDAP mappers as well as some built-in Groups and users in LDAP
*/
public static RunOnServer prepareHardcodedGroupsLDAPTest() {
return session -> {
RealmModel realm = session.getContext().getRealm();
ComponentModel ldapCompModel = LDAPTestUtils.getLdapProviderModel(realm);
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapCompModel);
UserStorageProviderModel ldapModel = ldapFedProvider.getModel();
ldapModel.setCachePolicy(CacheableStorageProviderModel.CachePolicy.NO_CACHE);
ldapModel.setImportEnabled(false);
ldapModel.getConfig().putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.READ_ONLY.name());
realm.updateComponent(ldapModel);
// Add a hardcoded group hierarchy with role
RoleModel clientRole = realm.getClientByClientId("admin-cli").addRole("client_role");
GroupModel parentGroup = realm.createGroup("parent_group");
parentGroup.grantRole(clientRole);
GroupModel hardcodedGroup = realm.createGroup("hardcoded_group");
parentGroup.addChild(hardcodedGroup);
// Add group mapper
LDAPTestUtils.addOrUpdateHardcodedGroupMapper(realm, ldapModel);
// Remove all LDAP users
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, realm);
// Add some LDAP users for testing
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
};
}
}

View file

@ -18,10 +18,19 @@ package org.keycloak.testsuite.federation.ldap;
import java.util.stream.Collectors;
import org.keycloak.component.ComponentModel;
import org.keycloak.models.LDAPConstants;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.storage.CacheableStorageProviderModel;
import org.keycloak.storage.UserStorageProvider;
import org.keycloak.storage.UserStorageProviderModel;
import org.keycloak.storage.ldap.LDAPStorageProvider;
import org.keycloak.storage.ldap.idm.model.LDAPObject;
import org.keycloak.testframework.remote.providers.runonserver.RunOnServer;
import org.keycloak.testsuite.util.LDAPRule;
import org.keycloak.testsuite.util.LDAPTestUtils;
import org.junit.ClassRule;
import org.junit.Test;
@ -46,7 +55,7 @@ public class LDAPHardcodedRoleMapperTest extends AbstractLDAPTest {
@Override
protected void afterImportTestRealm() {
testingClient.testing().ldap(TEST_REALM_NAME).prepareHardcodedRolesLDAPTest();
runOnServer.run(prepareHardcodedRolesLDAPTest());
}
/**
@ -77,4 +86,34 @@ public class LDAPHardcodedRoleMapperTest extends AbstractLDAPTest {
});
}
/**
* Prepare hardcoded roles LDAP tests. Creates some LDAP mappers as well as some hardcoded roles and users in LDAP
*/
public static RunOnServer prepareHardcodedRolesLDAPTest() {
return session -> {
RealmModel realm = session.getContext().getRealm();
ComponentModel ldapCompModel = LDAPTestUtils.getLdapProviderModel(realm);
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapCompModel);
UserStorageProviderModel ldapModel = ldapFedProvider.getModel();
ldapModel.setCachePolicy(CacheableStorageProviderModel.CachePolicy.NO_CACHE);
ldapModel.setImportEnabled(false);
ldapModel.getConfig().putSingle(LDAPConstants.EDIT_MODE, UserStorageProvider.EditMode.READ_ONLY.name());
realm.updateComponent(ldapModel);
// Add a hardcoded and composite role
RoleModel clientRole = realm.getClientByClientId("admin-cli").addRole("client_role");
RoleModel hardcodedRole = realm.addRole("hardcoded_role");
hardcodedRole.addCompositeRole(clientRole);
// Add role mapper
LDAPTestUtils.addOrUpdateHardcodedRoleMapper(realm, ldapModel);
// Remove all LDAP users
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, realm);
// Add some LDAP users for testing
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
};
}
}

View file

@ -80,6 +80,7 @@ import org.keycloak.testsuite.util.AccountHelper;
import org.keycloak.testsuite.util.LDAPRule;
import org.keycloak.testsuite.util.LDAPTestUtils;
import org.keycloak.testsuite.util.oauth.AccessTokenResponse;
import org.keycloak.testsuite.util.runonserver.LdapHelper;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
@ -525,7 +526,7 @@ public class LDAPProvidersIntegrationTest extends AbstractLDAPTest {
// Re-add LDAP provider
Map<String, String> cfg = getLDAPRule().getConfig();
ldapModelId = testingClient.testing().ldap(TEST_REALM_NAME).createLDAPProvider(cfg, isImportEnabled());
ldapModelId = runOnServer.fetchString(LdapHelper.createLDAPProvider(cfg, isImportEnabled())).replace("\"", "");
testingClient.server().run(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);

View file

@ -20,11 +20,18 @@ import java.util.stream.Collectors;
import org.keycloak.component.ComponentModel;
import org.keycloak.models.ClientModel;
import org.keycloak.models.LDAPConstants;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.storage.ldap.LDAPStorageProvider;
import org.keycloak.storage.ldap.LDAPUtils;
import org.keycloak.storage.ldap.idm.model.LDAPObject;
import org.keycloak.storage.ldap.mappers.membership.LDAPGroupMapperMode;
import org.keycloak.storage.ldap.mappers.membership.MembershipType;
import org.keycloak.storage.ldap.mappers.membership.role.RoleLDAPStorageMapperFactory;
import org.keycloak.storage.ldap.mappers.membership.role.RoleMapperConfig;
import org.keycloak.testframework.remote.providers.runonserver.RunOnServer;
import org.keycloak.testsuite.util.LDAPRule;
import org.keycloak.testsuite.util.LDAPTestUtils;
@ -55,7 +62,7 @@ public class LDAPRoleMapperTest extends AbstractLDAPTest {
@Override
protected void afterImportTestRealm() {
testingClient.testing().ldap(TEST_REALM_NAME).prepareRolesLDAPTest();
runOnServer.run(prepareRolesLDAPTest());
}
@Test
@ -192,4 +199,49 @@ public class LDAPRoleMapperTest extends AbstractLDAPTest {
}
});
}
/**
* Prepare groups LDAP tests. Creates some LDAP mappers as well as some built-in Groups and users in LDAP
*/
public static RunOnServer prepareRolesLDAPTest() {
return session -> {
RealmModel realm = session.getContext().getRealm();
ComponentModel ldapModel = LDAPTestUtils.getLdapProviderModel(realm);
LDAPStorageProvider ldapFedProvider = LDAPTestUtils.getLdapProvider(session, ldapModel);
// Add role mapper
LDAPTestUtils.addOrUpdateRoleMapper(realm, ldapModel, LDAPGroupMapperMode.LDAP_ONLY);
// Remove all LDAP groups and users
LDAPTestUtils.removeAllLDAPGroups(session, realm, ldapModel, "rolesMapper");
LDAPTestUtils.removeAllLDAPUsers(ldapFedProvider, realm);
// Add some LDAP users for testing
LDAPObject john = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "johnkeycloak", "John", "Doe", "john@email.org", null, "1234");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, john, "Password1");
LDAPObject mary = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "marykeycloak", "Mary", "Kelly", "mary@email.org", null, "5678");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, mary, "Password1");
LDAPObject rob = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "robkeycloak", "Rob", "Brown", "rob@email.org", null, "8910");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, rob, "Password1");
LDAPObject james = LDAPTestUtils.addLDAPUser(ldapFedProvider, realm, "jameskeycloak", "James", "Brown", "james@email.org", null, "8910");
LDAPTestUtils.updateLDAPPassword(ldapFedProvider, james, "Password1");
// Add some groups for testing
LDAPObject group1 = LDAPTestUtils.createLDAPGroup("rolesMapper", session, realm, ldapModel, "group1");
LDAPObject group2 = LDAPTestUtils.createLDAPGroup("rolesMapper", session, realm, ldapModel, "group2");
LDAPObject group3 = LDAPTestUtils.createLDAPGroup("rolesMapper", session, realm, ldapModel, "group3");
// add the users to the groups
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, john);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, mary);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group1, rob);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group2, john);
LDAPUtils.addMember(ldapFedProvider, MembershipType.DN, LDAPConstants.MEMBER, "not-used", group2, mary);
// Sync LDAP groups to Keycloak DB roles
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(realm, ldapModel, "rolesMapper");
new RoleLDAPStorageMapperFactory().create(session, mapperModel).syncDataFromFederationProviderToKeycloak(realm);
};
}
}

View file

@ -37,6 +37,7 @@ import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.util.LDAPRule;
import org.keycloak.testsuite.util.LDAPTestConfiguration;
import org.keycloak.testsuite.util.LDAPTestUtils;
import org.keycloak.testsuite.util.runonserver.LdapHelper;
import org.junit.ClassRule;
import org.junit.FixMethodOrder;
@ -74,7 +75,7 @@ public class LDAPSpecialCharsTest extends AbstractLDAPTest {
@Override
protected void afterImportTestRealm() {
testingClient.testing().ldap(TEST_REALM_NAME).prepareGroupsLDAPTest();
runOnServer.run(LdapHelper.prepareGroupsLDAPTest());
testingClient.server().run(session -> {
LDAPTestContext ctx = LDAPTestContext.init(session);

View file

@ -31,9 +31,12 @@ import org.keycloak.services.managers.LDAPServerCapabilitiesManager;
import org.keycloak.storage.ldap.idm.store.ldap.extended.PasswordModifyRequest;
import org.keycloak.testsuite.AbstractAdminTest;
import org.keycloak.testsuite.arquillian.annotation.EnableVault;
import org.keycloak.testsuite.client.KeycloakTestingClient;
import org.keycloak.testsuite.util.LDAPRule;
import org.keycloak.testsuite.util.runonserver.LdapHelper;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
@ -49,6 +52,13 @@ public class UserFederationLdapConnectionTest extends AbstractAdminTest {
@ClassRule
public static LDAPRule ldapRule = new LDAPRule();
KeycloakTestingClient.Server runOnServerAdminClientTest;
@Before
public void setup() {
runOnServerAdminClientTest = testingClient.server(REALM_NAME);
}
@Test
public void testLdapConnections() {
// Unknown action
@ -64,7 +74,7 @@ public class UserFederationLdapConnectionTest extends AbstractAdminTest {
assertStatus(response, 204);
// Connection success with invalid credentials
String ldapModelId = testingClient.testing().ldap(REALM_NAME).createLDAPProvider(ldapRule.getConfig(), false);
String ldapModelId = runOnServerAdminClientTest.fetchString(LdapHelper.createLDAPProvider(ldapRule.getConfig(), false)).replace("\"", "");
getCleanup().addCleanup(() -> {
adminClient.realm(REALM_NAME).components().removeComponent(ldapModelId);;
});
@ -162,7 +172,7 @@ public class UserFederationLdapConnectionTest extends AbstractAdminTest {
Map<String, String> cfg = ldapRule.getConfig();
cfg.put(LDAPConstants.CONNECTION_URL, "ldap://invalid:10389 ldap://localhost:10389");
cfg.put(LDAPConstants.CONNECTION_TIMEOUT, "1000");
String ldapModelId = testingClient.testing().ldap(REALM_NAME).createLDAPProvider(cfg, false);
String ldapModelId = runOnServerAdminClientTest.fetchString(LdapHelper.createLDAPProvider(cfg, false)).replace("\"", "");
// Only 2nd server works with stored LDAP federation provider
response = realm.testLDAPConnection(new TestLdapConnectionRepresentation(LDAPServerCapabilitiesManager.TEST_AUTHENTICATION,
@ -179,7 +189,7 @@ public class UserFederationLdapConnectionTest extends AbstractAdminTest {
cfg.put(LDAPConstants.CONNECTION_URL, "ldaps://localhost:10636");
cfg.put(LDAPConstants.START_TLS, "false");
cfg.put(LDAPConstants.USE_TRUSTSTORE_SPI, "true");
String ldapModelId = testingClient.testing().ldap(REALM_NAME).createLDAPProvider(cfg, false);
String ldapModelId = runOnServerAdminClientTest.fetchString(LdapHelper.createLDAPProvider(cfg, false)).replace("\"", "");
try {
// test passing everything with password included
Response response = realm.testLDAPConnection(new TestLdapConnectionRepresentation(LDAPServerCapabilitiesManager.TEST_AUTHENTICATION,

View file

@ -45,6 +45,7 @@ import org.keycloak.testframework.realm.AuthenticationExecutionBuilder;
import org.keycloak.testframework.realm.AuthenticationFlowBuilder;
import org.keycloak.testframework.realm.ClientBuilder;
import org.keycloak.testframework.realm.UserBuilder;
import org.keycloak.testframework.remote.providers.runonserver.RunOnServer;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.pages.AppPage;
@ -306,7 +307,7 @@ public class CustomFlowTest extends AbstractFlowTest {
AuthenticatorState state = new AuthenticatorState();
state.setUsername("login-test");
state.setClientId("test-app");
testingClient.testing().updateAuthenticator(state);
runOnServerMaster.run(updateAuthenticator(state));
oauth.openLoginForm();
@ -321,7 +322,7 @@ public class CustomFlowTest extends AbstractFlowTest {
AuthenticatorState state = new AuthenticatorState();
state.setUsername("login-test");
state.setClientId("test-app");
testingClient.testing().updateAuthenticator(state);
runOnServerMaster.run(updateAuthenticator(state));
grantAccessToken("test-app", "login-test");
}
@ -331,15 +332,15 @@ public class CustomFlowTest extends AbstractFlowTest {
AuthenticatorState state = new AuthenticatorState();
state.setClientId("dummy-client");
state.setUsername("login-test");
testingClient.testing().updateAuthenticator(state);
runOnServerMaster.run(updateAuthenticator(state));
grantAccessToken("dummy-client", "login-test");
state.setClientId("test-app");
testingClient.testing().updateAuthenticator(state);
runOnServerMaster.run(updateAuthenticator(state));
grantAccessToken("test-app", "login-test");
state.setClientId("unknown");
testingClient.testing().updateAuthenticator(state);
runOnServerMaster.run(updateAuthenticator(state));
AccessTokenResponse response = oauth.doPasswordGrantRequest("test-user", "password");
assertEquals(401, response.getStatusCode());
@ -356,7 +357,7 @@ public class CustomFlowTest extends AbstractFlowTest {
.error(Errors.CLIENT_NOT_FOUND);
state.setClientId("test-app");
testingClient.testing().updateAuthenticator(state);
runOnServerMaster.run(updateAuthenticator(state));
// Test throwing exception from the client authenticator. No error details should be displayed
response = oauth.passwordGrantRequest("test-user", "password").param(PassThroughClientAuthenticator.TEST_ERROR_PARAM, "Some Random Error").send();
@ -408,5 +409,15 @@ public class CustomFlowTest extends AbstractFlowTest {
.details(Details.CLIENT_AUTH_METHOD, PassThroughClientAuthenticator.PROVIDER_ID);
}
public static RunOnServer updateAuthenticator(AuthenticatorState state) {
return session -> {
if (state.getClientId() != null) {
PassThroughClientAuthenticator.clientId = state.getClientId();
}
if (state.getUsername() != null) {
PassThroughAuthenticator.username = state.getUsername();
}
};
}
}

View file

@ -68,6 +68,7 @@ import org.keycloak.testsuite.util.TokenSignatureUtil;
import org.keycloak.testsuite.util.UserManager;
import org.keycloak.testsuite.util.oauth.AccessTokenResponse;
import org.keycloak.testsuite.util.oauth.LogoutResponse;
import org.keycloak.testsuite.util.runonserver.CacheHelper;
import org.keycloak.util.TokenUtil;
import org.apache.http.NameValuePair;
@ -821,6 +822,6 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT
}
private int getAuthenticationSessionsCount() {
return testingClient.testing().cache(InfinispanConnectionProvider.AUTHENTICATION_SESSIONS_CACHE_NAME).size();
return runOnServerMaster.fetch(CacheHelper.size(InfinispanConnectionProvider.AUTHENTICATION_SESSIONS_CACHE_NAME));
}
}

View file

@ -38,6 +38,7 @@ import org.keycloak.testsuite.federation.ldap.LDAPTestContext;
import org.keycloak.testsuite.organization.admin.AbstractOrganizationTest;
import org.keycloak.testsuite.util.LDAPRule;
import org.keycloak.testsuite.util.LDAPTestUtils;
import org.keycloak.testsuite.util.runonserver.LdapHelper;
import org.junit.ClassRule;
import org.junit.Test;
@ -61,8 +62,8 @@ public class OrganizationMemberWithLdapTest extends AbstractOrganizationTest {
// add an LDAP provider with a group mapper
Map<String, String> cfg = ldapRule.getConfig();
testingClient.testing().ldap(TEST_REALM_NAME).createLDAPProvider(cfg, true);
testingClient.testing().ldap(TEST_REALM_NAME).prepareGroupsLDAPTest();
runOnServer.fetchString(LdapHelper.createLDAPProvider(cfg, true));
runOnServer.run(LdapHelper.prepareGroupsLDAPTest());
}
@Test