Pass builders to realm, client, and user configs (#35033)

Closes #35032

Signed-off-by: stianst <stianst@gmail.com>
This commit is contained in:
Stian Thorgersen
2024-11-18 10:54:11 +01:00
committed by GitHub
parent 0c1282df57
commit 4b497dd64c
17 changed files with 103 additions and 106 deletions

View File

@@ -1,18 +1,16 @@
package org.keycloak.test.framework.oauth;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.test.framework.realm.ClientConfig;
import org.keycloak.test.framework.realm.ClientConfigBuilder;
public class DefaultOAuthClientConfiguration implements ClientConfig {
@Override
public ClientRepresentation getRepresentation() {
return builder()
.clientId("test-oauth-client")
public ClientConfigBuilder configure(ClientConfigBuilder client) {
return client.clientId("test-oauth-client")
.serviceAccount()
.redirectUris("http://127.0.0.1/callback/oauth")
.secret("test-secret")
.build();
.secret("test-secret");
}
}

View File

@@ -24,6 +24,7 @@ import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
import jakarta.ws.rs.core.Response;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.test.framework.realm.ClientConfig;
import org.keycloak.test.framework.realm.ClientConfigBuilder;
import org.keycloak.test.framework.realm.ManagedClient;
import org.keycloak.test.framework.realm.ManagedRealm;
import org.keycloak.test.framework.util.ApiUtil;
@@ -47,7 +48,7 @@ public class OAuthClient {
}
private ManagedClient registerClient(ClientConfig clientConfig) {
ClientRepresentation clientRepresentation = clientConfig.getRepresentation();
ClientRepresentation clientRepresentation = clientConfig.configure(ClientConfigBuilder.create()).build();
Response response = realm.admin().clients().create(clientRepresentation);
String id = ApiUtil.handleCreatedResponse(response);
clientRepresentation.setId(id);

View File

@@ -1,13 +1,7 @@
package org.keycloak.test.framework.realm;
import org.keycloak.representations.idm.ClientRepresentation;
public interface ClientConfig {
ClientRepresentation getRepresentation();
default ClientConfigBuilder builder() {
return new ClientConfigBuilder();
}
ClientConfigBuilder configure(ClientConfigBuilder client);
}

View File

@@ -4,35 +4,44 @@ import org.keycloak.representations.idm.ClientRepresentation;
public class ClientConfigBuilder {
private final ClientRepresentation representation;
private final ClientRepresentation rep;
public ClientConfigBuilder() {
this.representation = new ClientRepresentation();
this.representation.setEnabled(true);
private ClientConfigBuilder(ClientRepresentation rep) {
this.rep = rep;
}
public static ClientConfigBuilder create() {
ClientRepresentation rep = new ClientRepresentation();
rep.setEnabled(true);
return new ClientConfigBuilder(rep);
}
public static ClientConfigBuilder update(ClientRepresentation rep) {
return new ClientConfigBuilder(rep);
}
public ClientConfigBuilder clientId(String clientId) {
representation.setClientId(clientId);
rep.setClientId(clientId);
return this;
}
public ClientConfigBuilder secret(String secret) {
representation.setSecret(secret);
rep.setSecret(secret);
return this;
}
public ClientConfigBuilder redirectUris(String... redirectUris) {
representation.setRedirectUris(Collections.combine(representation.getRedirectUris(), redirectUris));
rep.setRedirectUris(Collections.combine(rep.getRedirectUris(), redirectUris));
return this;
}
public ClientConfigBuilder serviceAccount() {
representation.setServiceAccountsEnabled(true);
rep.setServiceAccountsEnabled(true);
return this;
}
public ClientRepresentation build() {
return representation;
return rep;
}
}

View File

@@ -27,7 +27,7 @@ public class ClientSupplier implements Supplier<ManagedClient, InjectClient> {
ManagedRealm realm = instanceContext.getDependency(ManagedRealm.class, instanceContext.getAnnotation().realmRef());
ClientConfig config = SupplierHelpers.getInstance(instanceContext.getAnnotation().config());
ClientRepresentation clientRepresentation = config.getRepresentation();
ClientRepresentation clientRepresentation = config.configure(ClientConfigBuilder.create()).build();
if (clientRepresentation.getClientId() == null) {
String clientId = SupplierHelpers.createName(instanceContext);

View File

@@ -1,12 +1,10 @@
package org.keycloak.test.framework.realm;
import org.keycloak.representations.idm.ClientRepresentation;
public class DefaultClientConfig implements ClientConfig {
@Override
public ClientRepresentation getRepresentation() {
return builder().build();
public ClientConfigBuilder configure(ClientConfigBuilder client) {
return client;
}
}

View File

@@ -1,12 +1,10 @@
package org.keycloak.test.framework.realm;
import org.keycloak.representations.idm.RealmRepresentation;
public class DefaultRealmConfig implements RealmConfig {
@Override
public RealmRepresentation getRepresentation() {
return builder().build();
public RealmConfigBuilder configure(RealmConfigBuilder realm) {
return realm;
}
}

View File

@@ -1,12 +1,10 @@
package org.keycloak.test.framework.realm;
import org.keycloak.representations.idm.UserRepresentation;
public class DefaultUserConfig implements UserConfig {
@Override
public UserRepresentation getRepresentation() {
return builder().build();
public UserConfigBuilder configure(UserConfigBuilder user) {
return user;
}
}

View File

@@ -1,13 +1,7 @@
package org.keycloak.test.framework.realm;
import org.keycloak.representations.idm.RealmRepresentation;
public interface RealmConfig {
RealmRepresentation getRepresentation();
default RealmConfigBuilder builder() {
return new RealmConfigBuilder();
}
RealmConfigBuilder configure(RealmConfigBuilder realm);
}

View File

@@ -7,33 +7,42 @@ import java.util.Arrays;
public class RealmConfigBuilder {
private final RealmRepresentation representation;
private final RealmRepresentation rep;
public RealmConfigBuilder() {
this.representation = new RealmRepresentation();
this.representation.setEnabled(true);
private RealmConfigBuilder(RealmRepresentation rep) {
this.rep = rep;
}
public static RealmConfigBuilder create() {
RealmRepresentation rep = new RealmRepresentation();
rep.setEnabled(true);
return new RealmConfigBuilder(rep);
}
public static RealmConfigBuilder update(RealmRepresentation rep) {
return new RealmConfigBuilder(rep);
}
public RealmConfigBuilder name(String name) {
representation.setRealm(name);
rep.setRealm(name);
return this;
}
public RealmConfigBuilder roles(String... roleNames) {
if (representation.getRoles() == null) {
representation.setRoles(new RolesRepresentation());
if (rep.getRoles() == null) {
rep.setRoles(new RolesRepresentation());
}
representation.getRoles().setRealm(Collections.combine(representation.getRoles().getRealm(), Arrays.stream(roleNames).map(Representations::toRole)));
rep.getRoles().setRealm(Collections.combine(rep.getRoles().getRealm(), Arrays.stream(roleNames).map(Representations::toRole)));
return this;
}
public RealmConfigBuilder groups(String... groupsNames) {
representation.setGroups(Collections.combine(representation.getGroups(), Arrays.stream(groupsNames).map(Representations::toGroup)));
rep.setGroups(Collections.combine(rep.getGroups(), Arrays.stream(groupsNames).map(Representations::toGroup)));
return this;
}
public RealmRepresentation build() {
return representation;
return rep;
}
}

View File

@@ -30,7 +30,7 @@ public class RealmSupplier implements Supplier<ManagedRealm, InjectRealm> {
Keycloak adminClient = instanceContext.getDependency(Keycloak.class);
RealmConfig config = SupplierHelpers.getInstance(instanceContext.getAnnotation().config());
RealmRepresentation realmRepresentation = config.getRepresentation();
RealmRepresentation realmRepresentation = config.configure(RealmConfigBuilder.create()).build();
if (realmRepresentation.getRealm() == null) {
String realmName = SupplierHelpers.createName(instanceContext);

View File

@@ -1,13 +1,7 @@
package org.keycloak.test.framework.realm;
import org.keycloak.representations.idm.UserRepresentation;
public interface UserConfig {
UserRepresentation getRepresentation();
default UserConfigBuilder builder() {
return new UserConfigBuilder();
}
UserConfigBuilder configure(UserConfigBuilder user);
}

View File

@@ -5,46 +5,55 @@ import org.keycloak.representations.idm.UserRepresentation;
public class UserConfigBuilder {
private final UserRepresentation representation;
private final UserRepresentation rep;
public UserConfigBuilder() {
this.representation = new UserRepresentation();
this.representation.setEnabled(true);
private UserConfigBuilder(UserRepresentation rep) {
this.rep = rep;
}
public static UserConfigBuilder create() {
UserRepresentation rep = new UserRepresentation();
rep.setEnabled(true);
return new UserConfigBuilder(rep);
}
public static UserConfigBuilder update(UserRepresentation rep) {
return new UserConfigBuilder(rep);
}
public UserConfigBuilder username(String username) {
representation.setUsername(username);
rep.setUsername(username);
return this;
}
public UserConfigBuilder name(String firstName, String lastName) {
representation.setFirstName(firstName);
representation.setLastName(lastName);
rep.setFirstName(firstName);
rep.setLastName(lastName);
return this;
}
public UserConfigBuilder email(String email) {
representation.setEmail(email);
rep.setEmail(email);
return this;
}
public UserConfigBuilder password(String password) {
representation.setCredentials(Collections.combine(representation.getCredentials(), Representations.toCredential(CredentialRepresentation.PASSWORD, password)));
rep.setCredentials(Collections.combine(rep.getCredentials(), Representations.toCredential(CredentialRepresentation.PASSWORD, password)));
return this;
}
public UserConfigBuilder roles(String... roles) {
representation.setRealmRoles(Collections.combine(representation.getRealmRoles(), roles));
rep.setRealmRoles(Collections.combine(rep.getRealmRoles(), roles));
return this;
}
public UserConfigBuilder groups(String... groups) {
representation.setGroups(Collections.combine(representation.getGroups(), groups));
rep.setGroups(Collections.combine(rep.getGroups(), groups));
return this;
}
public UserRepresentation build() {
return representation;
return rep;
}
}

View File

@@ -29,7 +29,7 @@ public class UserSupplier implements Supplier<ManagedUser, InjectUser> {
ManagedRealm realm = instanceContext.getDependency(ManagedRealm.class, instanceContext.getAnnotation().realmRef());
UserConfig config = SupplierHelpers.getInstance(instanceContext.getAnnotation().config());
UserRepresentation userRepresentation = config.getRepresentation();
UserRepresentation userRepresentation = config.configure(UserConfigBuilder.create()).build();
if (userRepresentation.getUsername() == null) {
String username = SupplierHelpers.createName(instanceContext);

View File

@@ -2,20 +2,20 @@ package org.keycloak.test.examples;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.test.framework.annotations.InjectClient;
import org.keycloak.test.framework.annotations.InjectRealm;
import org.keycloak.test.framework.annotations.InjectUser;
import org.keycloak.test.framework.annotations.KeycloakIntegrationTest;
import org.keycloak.test.framework.injection.LifeCycle;
import org.keycloak.test.framework.realm.ClientConfig;
import org.keycloak.test.framework.realm.ClientConfigBuilder;
import org.keycloak.test.framework.realm.ManagedClient;
import org.keycloak.test.framework.realm.ManagedRealm;
import org.keycloak.test.framework.realm.ManagedUser;
import org.keycloak.test.framework.realm.RealmConfig;
import org.keycloak.test.framework.realm.RealmConfigBuilder;
import org.keycloak.test.framework.realm.UserConfig;
import org.keycloak.test.framework.realm.UserConfigBuilder;
@KeycloakIntegrationTest
public class FancyRealmTest {
@@ -51,37 +51,31 @@ public class FancyRealmTest {
static class MyRealm implements RealmConfig {
@Override
public RealmRepresentation getRepresentation() {
return builder()
.roles("role-1", "role-2")
.groups("group-1", "group-2")
.build();
public RealmConfigBuilder configure(RealmConfigBuilder realm) {
return realm.roles("role-1", "role-2")
.groups("group-1", "group-2");
}
}
static class MyClient implements ClientConfig {
@Override
public ClientRepresentation getRepresentation() {
return builder()
.clientId("the-client")
.redirectUris("http://127.0.0.1", "http://test")
.build();
public ClientConfigBuilder configure(ClientConfigBuilder client) {
return client.clientId("the-client")
.redirectUris("http://127.0.0.1", "http://test");
}
}
static class MyUser implements UserConfig {
@Override
public UserRepresentation getRepresentation() {
return builder()
.username("bobthemob")
public UserConfigBuilder configure(UserConfigBuilder user) {
return user.username("bobthemob")
.name("Bob", "Mob")
.email("bob@mob")
.password("password")
.roles("role-1", "role-2") // TODO Adding role mappings when creating user is not supported!
.groups("/group-1")
.build();
.groups("/group-1");
}
}

View File

@@ -3,7 +3,6 @@ package org.keycloak.test.examples;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.test.framework.annotations.InjectAdminClient;
import org.keycloak.test.framework.annotations.InjectRealm;
import org.keycloak.test.framework.annotations.InjectUser;
@@ -11,6 +10,7 @@ import org.keycloak.test.framework.annotations.KeycloakIntegrationTest;
import org.keycloak.test.framework.realm.ManagedRealm;
import org.keycloak.test.framework.realm.ManagedUser;
import org.keycloak.test.framework.realm.RealmConfig;
import org.keycloak.test.framework.realm.RealmConfigBuilder;
@KeycloakIntegrationTest
public class MultipleInstancesTest {
@@ -52,10 +52,12 @@ public class MultipleInstancesTest {
public static class CustomRealmConfig implements RealmConfig {
@Override
public RealmRepresentation getRepresentation() {
return new RealmRepresentation();
public RealmConfigBuilder configure(RealmConfigBuilder realm) {
return realm;
}
}
}

View File

@@ -7,15 +7,16 @@ import com.nimbusds.oauth2.sdk.token.AccessToken;
import jakarta.ws.rs.core.Response;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.test.framework.annotations.InjectOAuthClient;
import org.keycloak.test.framework.ui.annotations.InjectPage;
import org.keycloak.test.framework.annotations.InjectUser;
import org.keycloak.test.framework.ui.annotations.InjectWebDriver;
import org.keycloak.test.framework.annotations.KeycloakIntegrationTest;
import org.keycloak.test.framework.oauth.OAuthClient;
import org.keycloak.test.framework.ui.page.LoginPage;
import org.keycloak.test.framework.realm.ManagedUser;
import org.keycloak.test.framework.realm.UserConfig;
import org.keycloak.test.framework.realm.UserConfigBuilder;
import org.keycloak.test.framework.ui.annotations.InjectPage;
import org.keycloak.test.framework.ui.annotations.InjectWebDriver;
import org.keycloak.test.framework.ui.page.LoginPage;
import org.openqa.selenium.WebDriver;
import java.net.URI;
@@ -24,7 +25,7 @@ import java.net.URL;
@KeycloakIntegrationTest
public class OAuthClientTest {
@InjectUser(config = UserConfig.class)
@InjectUser(config = OAuthUserConfig.class)
ManagedUser user;
@InjectOAuthClient
@@ -89,15 +90,13 @@ public class OAuthClientTest {
Assertions.assertNull(introspectionResponse.toSuccessResponse().getScope());
}
public static class UserConfig implements org.keycloak.test.framework.realm.UserConfig {
public static class OAuthUserConfig implements UserConfig {
@Override
public UserRepresentation getRepresentation() {
return builder()
.name("First", "Last")
public UserConfigBuilder configure(UserConfigBuilder user) {
return user.name("First", "Last")
.email("test@local")
.password("password")
.build();
.password("password");
}
}