8000 Move the rest of TestingResource methods to a utils-shared helper class (2/2) by vaceksimon · Pull Request #49241 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions tests/utils-shared/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
};
}
}
Original file line number Diff line number Diff line change
@@ -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, LDAPCons 6870 tants.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");
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,34 +54,19 @@
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;
Expand Down Expand Up @@ -175,107 +160,10 @@ public Response clearAdminEventQueue() {
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Loading
Loading
0