+
Skip to content

Add generic update methods for builders #40312

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 11, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;

import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
Expand Down Expand Up @@ -142,8 +143,28 @@ public ClientConfigBuilder protocolMappers(List<ProtocolMapperRepresentation> ma
return this;
}

/**
* Best practice is to use other convenience methods when configuring a client, but while the framework is under
* active development there may not be a way to perform all updates required. In these cases this method allows
* applying any changes to the underlying representation.
*
* @param update
* @return this
* @deprecated
*/
public ClientConfigBuilder update(ClientUpdate... update) {
Arrays.stream(update).forEach(u -> u.update(rep));
return this;
}

public ClientRepresentation build() {
return rep;
}

public interface ClientUpdate {

void update(ClientRepresentation client);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,28 @@ public RealmConfigBuilder failureFactor(int count) {
return this;
}

/**
* Best practice is to use other convenience methods when configuring a realm, but while the framework is under
* active development there may not be a way to perform all updates required. In these cases this method allows
* applying any changes to the underlying representation.
*
* @param update
* @return this
* @deprecated
*/
public RealmConfigBuilder update(RealmUpdate... update) {
Arrays.stream(update).forEach(u -> u.update(rep));
return this;
}

public RealmRepresentation build() {
return rep;
}

public interface RealmUpdate {

void update(RealmRepresentation realm);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.UserRepresentation;

import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
Expand Down Expand Up @@ -87,8 +88,28 @@ public UserConfigBuilder attribute(String key, String... value) {
return this;
}

/**
* Best practice is to use other convenience methods when configuring a user, but while the framework is under
* active development there may not be a way to perform all updates required. In these cases this method allows
* applying any changes to the underlying representation.
*
* @param update
* @return this
* @deprecated
*/
public UserConfigBuilder update(UserUpdate... update) {
Arrays.stream(update).forEach(u -> u.update(rep));
return this;
}

public UserRepresentation build() {
return rep;
}

public interface UserUpdate {

void update(UserRepresentation client);

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.keycloak.test.examples;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.testframework.annotations.InjectClient;
import org.keycloak.testframework.annotations.InjectRealm;
import org.keycloak.testframework.annotations.InjectUser;
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
import org.keycloak.testframework.realm.ClientConfig;
import org.keycloak.testframework.realm.ClientConfigBuilder;
import org.keycloak.testframework.realm.ManagedClient;
import org.keycloak.testframework.realm.ManagedRealm;
import org.keycloak.testframework.realm.ManagedUser;
import org.keycloak.testframework.realm.RealmConfig;
import org.keycloak.testframework.realm.RealmConfigBuilder;
import org.keycloak.testframework.realm.UserConfig;
import org.keycloak.testframework.realm.UserConfigBuilder;

import java.util.LinkedList;

@KeycloakIntegrationTest
public class CustomConfigBuilderTest {

@InjectRealm(config = CustomRealmConfig.class)
ManagedRealm realm;

@InjectClient(config = CustomClientConfig.class)
ManagedClient client;

@InjectUser(config = CustomUserConfig.class)
ManagedUser user;

@Test
public void testRealm() {
Assertions.assertEquals(1, realm.admin().groups().query("mygroup").size());
}

@Test
public void testClient() {
Assertions.assertTrue(client.admin().toRepresentation().isBearerOnly());
}

@Test
public void testUser() {
Assertions.assertFalse(user.admin().toRepresentation().isEnabled());
}

public static class CustomRealmConfig implements RealmConfig {

@Override
public RealmConfigBuilder configure(RealmConfigBuilder realm) {
return realm.update(r -> {
if (r.getGroups() == null) {
r.setGroups(new LinkedList<>());
}
GroupRepresentation group = new GroupRepresentation();
group.setName("mygroup");
group.setPath("/mygroup");
r.getGroups().add(group);
});
}
}

public static class CustomClientConfig implements ClientConfig {

@Override
public ClientConfigBuilder configure(ClientConfigBuilder client) {
return client.update(u -> u.setBearerOnly(true));
}
}

public static class CustomUserConfig implements UserConfig {

@Override
public UserConfigBuilder configure(UserConfigBuilder user) {
return user.update(u -> u.setEnabled(false));
}
}

}
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载