mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-10 15:32:05 -03:30
Move RealmTest.java to the new testsuite (#41326)
Part of: #34494 Signed-off-by: Lukas Hanusovsky <lhanusov@redhat.com>
This commit is contained in:
parent
811e153398
commit
f12ab6b189
@ -0,0 +1,30 @@
|
||||
package org.keycloak.tests.admin.realm;
|
||||
|
||||
import org.keycloak.admin.client.Keycloak;
|
||||
import org.keycloak.testframework.admin.AdminClientFactory;
|
||||
import org.keycloak.testframework.annotations.InjectAdminClient;
|
||||
import org.keycloak.testframework.annotations.InjectAdminClientFactory;
|
||||
import org.keycloak.testframework.annotations.InjectAdminEvents;
|
||||
import org.keycloak.testframework.annotations.InjectRealm;
|
||||
import org.keycloak.testframework.events.AdminEvents;
|
||||
import org.keycloak.testframework.realm.ManagedRealm;
|
||||
import org.keycloak.testframework.remote.runonserver.InjectRunOnServer;
|
||||
import org.keycloak.testframework.remote.runonserver.RunOnServerClient;
|
||||
|
||||
public class AbstractRealmTest {
|
||||
|
||||
@InjectRealm(ref = "managedRealm")
|
||||
ManagedRealm managedRealm;
|
||||
|
||||
@InjectAdminClient(ref = "managed", realmRef = "managedRealm")
|
||||
Keycloak adminClient;
|
||||
|
||||
@InjectAdminClientFactory
|
||||
AdminClientFactory adminClientFactory;
|
||||
|
||||
@InjectRunOnServer(ref = "managed", realmRef = "managedRealm")
|
||||
RunOnServerClient runOnServer;
|
||||
|
||||
@InjectAdminEvents(ref = "managedEvents", realmRef = "managedRealm")
|
||||
AdminEvents adminEvents;
|
||||
}
|
||||
@ -0,0 +1,270 @@
|
||||
package org.keycloak.tests.admin.realm;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.events.admin.ResourceType;
|
||||
import org.keycloak.models.BrowserSecurityHeaders;
|
||||
import org.keycloak.models.CibaConfig;
|
||||
import org.keycloak.models.OAuth2DeviceConfig;
|
||||
import org.keycloak.models.OTPPolicy;
|
||||
import org.keycloak.models.ParConfig;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RealmProvider;
|
||||
import org.keycloak.models.cache.CacheRealmProvider;
|
||||
import org.keycloak.models.cache.infinispan.RealmAdapter;
|
||||
import org.keycloak.models.jpa.entities.RealmAttributes;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
|
||||
import org.keycloak.testframework.events.AdminEventAssertion;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@KeycloakIntegrationTest
|
||||
public class RealmAttributesTest extends AbstractRealmTest {
|
||||
|
||||
/**
|
||||
* Checks attributes exposed as fields are not also included as attributes
|
||||
*/
|
||||
@Test
|
||||
public void excludesFieldsFromAttributes() {
|
||||
RealmRepresentation rep = new RealmRepresentation();
|
||||
rep.setRealm("attributes");
|
||||
|
||||
adminClient.realms().create(rep);
|
||||
|
||||
RealmRepresentation rep2 = adminClient.realm("attributes").toRepresentation();
|
||||
if (rep2.getAttributes() != null) {
|
||||
Stream.of(CibaConfig.CIBA_BACKCHANNEL_TOKEN_DELIVERY_MODE,
|
||||
CibaConfig.CIBA_EXPIRES_IN,
|
||||
CibaConfig.CIBA_INTERVAL,
|
||||
CibaConfig.CIBA_AUTH_REQUESTED_USER_HINT).forEach(i -> rep2.getAttributes().remove(i));
|
||||
}
|
||||
|
||||
Set<String> attributesKeys = rep2.getAttributes().keySet();
|
||||
|
||||
int expectedAttributesCount = 3;
|
||||
final Set<String> expectedAttributes = Sets.newHashSet(
|
||||
OAuth2DeviceConfig.OAUTH2_DEVICE_CODE_LIFESPAN,
|
||||
OAuth2DeviceConfig.OAUTH2_DEVICE_POLLING_INTERVAL,
|
||||
ParConfig.PAR_REQUEST_URI_LIFESPAN
|
||||
);
|
||||
|
||||
// This attribute is represented in Legacy store as attribute and for Map store as a field
|
||||
expectedAttributes.add(OTPPolicy.REALM_REUSABLE_CODE_ATTRIBUTE);
|
||||
expectedAttributesCount++;
|
||||
|
||||
assertThat(attributesKeys.size(), CoreMatchers.is(expectedAttributesCount));
|
||||
assertThat(attributesKeys, CoreMatchers.is(expectedAttributes));
|
||||
|
||||
adminClient.realms().realm("attributes").remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks attributes exposed as fields are not deleted on update realm
|
||||
*/
|
||||
@Test
|
||||
public void testFieldNotErased() {
|
||||
Long dummyLong = 999L;
|
||||
Integer dummyInt = 999;
|
||||
Map<String, String> browserSecurityHeaders = new HashMap<>(Arrays.stream(
|
||||
BrowserSecurityHeaders.values()).collect(Collectors.toMap(
|
||||
BrowserSecurityHeaders::getKey,
|
||||
headerValue -> headerValue.getDefaultValue().isBlank()
|
||||
? "non-null-to-test"
|
||||
: headerValue.getDefaultValue()
|
||||
)));
|
||||
|
||||
RealmRepresentation rep = new RealmRepresentation();
|
||||
rep.setRealm("attributes");
|
||||
rep.setDisplayName("DISPLAY_NAME");
|
||||
rep.setDisplayNameHtml("DISPLAY_NAME_HTML");
|
||||
rep.setDefaultSignatureAlgorithm("RS256");
|
||||
rep.setBruteForceProtected(true);
|
||||
rep.setPermanentLockout(true);
|
||||
rep.setMaxFailureWaitSeconds(dummyInt);
|
||||
rep.setWaitIncrementSeconds(dummyInt);
|
||||
rep.setQuickLoginCheckMilliSeconds(dummyLong);
|
||||
rep.setMinimumQuickLoginWaitSeconds(dummyInt);
|
||||
rep.setMaxDeltaTimeSeconds(dummyInt);
|
||||
rep.setFailureFactor(dummyInt);
|
||||
rep.setActionTokenGeneratedByAdminLifespan(dummyInt);
|
||||
rep.setActionTokenGeneratedByUserLifespan(dummyInt);
|
||||
rep.setOfflineSessionMaxLifespanEnabled(true);
|
||||
rep.setOfflineSessionMaxLifespan(dummyInt);
|
||||
rep.setBrowserSecurityHeaders(browserSecurityHeaders);
|
||||
|
||||
rep.setWebAuthnPolicyRpEntityName("RP_ENTITY_NAME");
|
||||
rep.setWebAuthnPolicySignatureAlgorithms(Collections.singletonList("RS256"));
|
||||
rep.setWebAuthnPolicyRpId("localhost");
|
||||
rep.setWebAuthnPolicyAttestationConveyancePreference("Direct");
|
||||
rep.setWebAuthnPolicyAuthenticatorAttachment("Platform");
|
||||
rep.setWebAuthnPolicyRequireResidentKey("Yes");
|
||||
rep.setWebAuthnPolicyUserVerificationRequirement("Required");
|
||||
rep.setWebAuthnPolicyCreateTimeout(dummyInt);
|
||||
rep.setWebAuthnPolicyAvoidSameAuthenticatorRegister(true);
|
||||
rep.setWebAuthnPolicyAcceptableAaguids(Collections.singletonList("00000000-0000-0000-0000-000000000000"));
|
||||
|
||||
rep.setWebAuthnPolicyPasswordlessRpEntityName("RP_ENTITY_NAME");
|
||||
rep.setWebAuthnPolicyPasswordlessSignatureAlgorithms(Collections.singletonList("RS256"));
|
||||
rep.setWebAuthnPolicyPasswordlessRpId("localhost");
|
||||
rep.setWebAuthnPolicyPasswordlessAttestationConveyancePreference("Direct");
|
||||
rep.setWebAuthnPolicyPasswordlessAuthenticatorAttachment("Platform");
|
||||
rep.setWebAuthnPolicyPasswordlessRequireResidentKey("Yes");
|
||||
rep.setWebAuthnPolicyPasswordlessUserVerificationRequirement("Required");
|
||||
rep.setWebAuthnPolicyPasswordlessCreateTimeout(dummyInt);
|
||||
rep.setWebAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister(true);
|
||||
rep.setWebAuthnPolicyPasswordlessAcceptableAaguids(Collections.singletonList("00000000-0000-0000-0000-000000000000"));
|
||||
|
||||
adminClient.realms().create(rep);
|
||||
|
||||
RealmRepresentation rep2 = new RealmRepresentation();
|
||||
rep2.setAttributes(Collections.singletonMap("frontendUrl", "http://localhost/frontEnd"));
|
||||
adminClient.realm("attributes").update(rep2);
|
||||
|
||||
rep = adminClient.realm("attributes").toRepresentation();
|
||||
assertEquals("DISPLAY_NAME", rep.getDisplayName());
|
||||
assertEquals("DISPLAY_NAME_HTML", rep.getDisplayNameHtml());
|
||||
assertEquals("RS256", rep.getDefaultSignatureAlgorithm());
|
||||
assertTrue(rep.isBruteForceProtected());
|
||||
assertTrue(rep.isPermanentLockout());
|
||||
assertEquals(dummyInt, rep.getMaxFailureWaitSeconds());
|
||||
assertEquals(dummyInt, rep.getWaitIncrementSeconds());
|
||||
assertEquals(dummyLong, rep.getQuickLoginCheckMilliSeconds());
|
||||
assertEquals(dummyInt, rep.getMinimumQuickLoginWaitSeconds());
|
||||
assertEquals(dummyInt, rep.getMaxDeltaTimeSeconds());
|
||||
assertEquals(dummyInt, rep.getFailureFactor());
|
||||
assertEquals(dummyInt, rep.getActionTokenGeneratedByAdminLifespan());
|
||||
assertEquals(dummyInt, rep.getActionTokenGeneratedByUserLifespan());
|
||||
assertTrue(rep.getOfflineSessionMaxLifespanEnabled());
|
||||
assertEquals(dummyInt, rep.getOfflineSessionMaxLifespan());
|
||||
|
||||
assertEquals("RP_ENTITY_NAME", rep.getWebAuthnPolicyRpEntityName());
|
||||
assertEquals(Collections.singletonList("RS256"), rep.getWebAuthnPolicySignatureAlgorithms());
|
||||
assertEquals("localhost", rep.getWebAuthnPolicyRpId());
|
||||
assertEquals("Direct", rep.getWebAuthnPolicyAttestationConveyancePreference());
|
||||
assertEquals("Platform", rep.getWebAuthnPolicyAuthenticatorAttachment());
|
||||
assertEquals("Yes", rep.getWebAuthnPolicyRequireResidentKey());
|
||||
assertEquals("Required", rep.getWebAuthnPolicyUserVerificationRequirement());
|
||||
assertEquals(dummyInt, rep.getWebAuthnPolicyCreateTimeout());
|
||||
assertTrue(rep.isWebAuthnPolicyAvoidSameAuthenticatorRegister());
|
||||
assertEquals(Collections.singletonList("00000000-0000-0000-0000-000000000000"), rep.getWebAuthnPolicyAcceptableAaguids());
|
||||
|
||||
assertEquals("RP_ENTITY_NAME", rep.getWebAuthnPolicyPasswordlessRpEntityName());
|
||||
assertEquals(Collections.singletonList("RS256"), rep.getWebAuthnPolicyPasswordlessSignatureAlgorithms());
|
||||
assertEquals("localhost", rep.getWebAuthnPolicyPasswordlessRpId());
|
||||
assertEquals("Direct", rep.getWebAuthnPolicyPasswordlessAttestationConveyancePreference());
|
||||
assertEquals("Platform", rep.getWebAuthnPolicyPasswordlessAuthenticatorAttachment());
|
||||
assertEquals("Yes", rep.getWebAuthnPolicyPasswordlessRequireResidentKey());
|
||||
assertEquals("Required", rep.getWebAuthnPolicyPasswordlessUserVerificationRequirement());
|
||||
assertEquals(dummyInt, rep.getWebAuthnPolicyPasswordlessCreateTimeout());
|
||||
assertTrue(rep.isWebAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister());
|
||||
assertEquals(Collections.singletonList("00000000-0000-0000-0000-000000000000"), rep.getWebAuthnPolicyPasswordlessAcceptableAaguids());
|
||||
|
||||
assertEquals(browserSecurityHeaders, rep.getBrowserSecurityHeaders());
|
||||
|
||||
adminClient.realms().realm("attributes").remove();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateRealmAttributes() {
|
||||
// first change
|
||||
RealmRepresentation rep = new RealmRepresentation();
|
||||
List<String> webAuthnPolicyAcceptableAaguids = new ArrayList<>();
|
||||
webAuthnPolicyAcceptableAaguids.add("aaguid1");
|
||||
webAuthnPolicyAcceptableAaguids.add("aaguid2");
|
||||
|
||||
rep.setAttributes(new HashMap<>());
|
||||
rep.getAttributes().put("foo1", "bar1");
|
||||
rep.getAttributes().put("foo2", "bar2");
|
||||
|
||||
rep.setWebAuthnPolicyRpEntityName("keycloak");
|
||||
rep.setWebAuthnPolicyAcceptableAaguids(webAuthnPolicyAcceptableAaguids);
|
||||
rep.setBruteForceProtected(true);
|
||||
rep.setDisplayName("dn1");
|
||||
|
||||
managedRealm.admin().update(rep);
|
||||
AdminEventAssertion.assertSuccess(adminEvents.poll()).operationType(OperationType.UPDATE).resourceType(ResourceType.REALM);
|
||||
|
||||
rep = managedRealm.admin().toRepresentation();
|
||||
assertEquals("bar1", rep.getAttributes().get("foo1"));
|
||||
assertEquals("bar2", rep.getAttributes().get("foo2"));
|
||||
assertTrue(rep.isBruteForceProtected());
|
||||
assertEquals("dn1", rep.getDisplayName());
|
||||
assertEquals(webAuthnPolicyAcceptableAaguids, rep.getWebAuthnPolicyAcceptableAaguids());
|
||||
|
||||
// second change
|
||||
webAuthnPolicyAcceptableAaguids.clear();
|
||||
rep.setBruteForceProtected(false);
|
||||
rep.setDisplayName("dn2");
|
||||
rep.getAttributes().put("foo1", "bar11");
|
||||
rep.getAttributes().remove("foo2");
|
||||
rep.setWebAuthnPolicyAcceptableAaguids(webAuthnPolicyAcceptableAaguids);
|
||||
|
||||
managedRealm.admin().update(rep);
|
||||
AdminEventAssertion.assertSuccess(adminEvents.poll()).operationType(OperationType.UPDATE).resourceType(ResourceType.REALM);
|
||||
|
||||
rep = managedRealm.admin().toRepresentation();
|
||||
|
||||
assertFalse(rep.isBruteForceProtected());
|
||||
assertEquals("dn2", rep.getDisplayName());
|
||||
|
||||
assertEquals("bar11", rep.getAttributes().get("foo1"));
|
||||
assertFalse(rep.getAttributes().containsKey("foo2"));
|
||||
assertTrue(rep.getWebAuthnPolicyAcceptableAaguids().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetEmptyAttributeValues() {
|
||||
String realmName = "testSetEmptyAttributeValues";
|
||||
RealmRepresentation rep = new RealmRepresentation();
|
||||
rep.setRealm(realmName);
|
||||
rep.setAttributes(new HashMap<>());
|
||||
rep.getAttributes().put("myboolean", "");
|
||||
rep.getAttributes().put("mylong", "");
|
||||
rep.getAttributes().put("myint", "");
|
||||
rep.getAttributes().put(RealmAttributes.ACTION_TOKEN_GENERATED_BY_USER_LIFESPAN + ".something", "");
|
||||
|
||||
adminClient.realms().create(rep);
|
||||
|
||||
try {
|
||||
adminClient.realm(realmName);
|
||||
|
||||
runOnServer.run(session -> {
|
||||
RealmModel realm = session.realms().getRealmByName(realmName);
|
||||
Assertions.assertInstanceOf(RealmAdapter.class, realm);
|
||||
|
||||
Assertions.assertNull(realm.getUserActionTokenLifespans().get("something"));
|
||||
Assertions.assertEquals(true, realm.getAttribute("myboolean", true));
|
||||
Assertions.assertEquals(realm.getAttribute("mylong", (long) 123), Long.valueOf(123));
|
||||
Assertions.assertEquals(realm.getAttribute("myint", 1234), Integer.valueOf(1234));
|
||||
|
||||
RealmProvider delegate = session.getProvider(CacheRealmProvider.class).getRealmDelegate();
|
||||
RealmModel realm2 = delegate.getRealm(realm.getId());
|
||||
Assertions.assertInstanceOf(org.keycloak.models.jpa.RealmAdapter.class, realm2);
|
||||
|
||||
Assertions.assertNull(realm2.getUserActionTokenLifespans().get("something"));
|
||||
Assertions.assertEquals(true, realm2.getAttribute("myboolean", true));
|
||||
Assertions.assertEquals(realm2.getAttribute("mylong", (long) 123), Long.valueOf(123));
|
||||
Assertions.assertEquals(realm2.getAttribute("myint", 1234), Integer.valueOf(1234));
|
||||
});
|
||||
} finally {
|
||||
adminClient.realm(realmName).remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
package org.keycloak.tests.admin.realm;
|
||||
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import org.infinispan.Cache;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.keycloak.connections.infinispan.InfinispanConnectionProvider;
|
||||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.events.admin.ResourceType;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.testframework.annotations.InjectRealm;
|
||||
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
|
||||
import org.keycloak.testframework.events.AdminEventAssertion;
|
||||
import org.keycloak.testframework.realm.ManagedRealm;
|
||||
import org.keycloak.testframework.remote.runonserver.InjectRunOnServer;
|
||||
import org.keycloak.testframework.remote.runonserver.RunOnServerClient;
|
||||
import org.keycloak.tests.utils.admin.ApiUtil;
|
||||
import org.keycloak.tests.utils.admin.AdminEventPaths;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@KeycloakIntegrationTest
|
||||
public class RealmCacheTest extends AbstractRealmTest {
|
||||
|
||||
@InjectRealm(ref = "master", attachTo = "master")
|
||||
ManagedRealm masterRealm;
|
||||
|
||||
@InjectRunOnServer(ref = "master", realmRef = "master")
|
||||
RunOnServerClient masterRunOnServer;
|
||||
|
||||
@Test
|
||||
public void clearRealmCache() {
|
||||
String realmId = managedRealm.getId();
|
||||
assertTrue(runOnServer.fetch(s -> {
|
||||
InfinispanConnectionProvider provider = s.getProvider(InfinispanConnectionProvider.class);
|
||||
Cache<Object, Object> cache = provider.getCache("realms");
|
||||
return cache.containsKey(realmId);
|
||||
}, Boolean.class));
|
||||
|
||||
managedRealm.admin().clearRealmCache();
|
||||
|
||||
// Using master realm to verify that managedRealm cache is empty.
|
||||
assertFalse(masterRunOnServer.fetch(s -> {
|
||||
InfinispanConnectionProvider provider = s.getProvider(InfinispanConnectionProvider.class);
|
||||
Cache<Object, Object> cache = provider.getCache("realms");
|
||||
return cache.containsKey(realmId);
|
||||
}, Boolean.class));
|
||||
|
||||
// The Admin event must be checked after the verification, because the event poll recreates the cache!
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.ACTION, "clear-realm-cache", ResourceType.REALM);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clearUserCache() {
|
||||
UserRepresentation user = new UserRepresentation();
|
||||
user.setUsername("clearcacheuser");
|
||||
Response response = managedRealm.admin().users().create(user);
|
||||
String userId = ApiUtil.getCreatedId(response);
|
||||
response.close();
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.CREATE, AdminEventPaths.userResourcePath(userId), user, ResourceType.USER);
|
||||
|
||||
managedRealm.admin().users().get(userId).toRepresentation();
|
||||
|
||||
assertTrue(runOnServer.fetch(s -> {
|
||||
InfinispanConnectionProvider provider = s.getProvider(InfinispanConnectionProvider.class);
|
||||
Cache<Object, Object> cache = provider.getCache("users");
|
||||
return cache.containsKey(userId);
|
||||
}, Boolean.class));
|
||||
|
||||
managedRealm.admin().clearUserCache();
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.ACTION, "clear-user-cache", ResourceType.REALM);
|
||||
|
||||
assertFalse(runOnServer.fetch(s -> {
|
||||
InfinispanConnectionProvider provider = s.getProvider(InfinispanConnectionProvider.class);
|
||||
Cache<Object, Object> cache = provider.getCache("users");
|
||||
return cache.containsKey(userId);
|
||||
}, Boolean.class));
|
||||
}
|
||||
|
||||
// NOTE: clearKeysCache tested in KcOIDCBrokerWithSignatureTest
|
||||
}
|
||||
@ -0,0 +1,262 @@
|
||||
package org.keycloak.tests.admin.realm;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import jakarta.ws.rs.BadRequestException;
|
||||
import jakarta.ws.rs.NotFoundException;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.keycloak.admin.client.Keycloak;
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.models.AdminRoles;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
|
||||
import org.keycloak.testframework.realm.UserConfigBuilder;
|
||||
import org.keycloak.tests.utils.Assert;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.everyItem;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@KeycloakIntegrationTest
|
||||
public class RealmCreateTest extends AbstractRealmTest {
|
||||
|
||||
@Test
|
||||
public void getRealms() {
|
||||
List<RealmRepresentation> realms = adminClient.realms().findAll();
|
||||
Assert.assertNames(realms, "master", managedRealm.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRealmRepresentation() {
|
||||
RealmRepresentation rep = managedRealm.admin().toRepresentation();
|
||||
Assertions.assertEquals(managedRealm.getName(), rep.getRealm());
|
||||
assertTrue(rep.isEnabled());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createRealmEmpty() {
|
||||
RealmRepresentation rep = new RealmRepresentation();
|
||||
rep.setRealm("new-realm");
|
||||
|
||||
adminClient.realms().create(rep);
|
||||
|
||||
Assert.assertNames(adminClient.realms().findAll(), "master", managedRealm.getName(), "new-realm");
|
||||
|
||||
List<String> clients = adminClient.realms().realm("new-realm").clients().findAll().stream().map(ClientRepresentation::getClientId).collect(Collectors.toList());
|
||||
assertThat(clients, containsInAnyOrder("account", "account-console", "admin-cli", "broker", "realm-management", "security-admin-console"));
|
||||
|
||||
adminClient.realms().realm("new-realm").remove();
|
||||
|
||||
Assert.assertNames(adminClient.realms().findAll(), "master", managedRealm.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createRealmWithValidConsoleUris() throws Exception {
|
||||
var realmNameWithSpaces = "new realm";
|
||||
|
||||
RealmRepresentation rep = new RealmRepresentation();
|
||||
rep.setRealm(realmNameWithSpaces);
|
||||
rep.setEnabled(Boolean.TRUE);
|
||||
rep.setUsers(Collections.singletonList(UserConfigBuilder.create()
|
||||
.username("new-realm-admin")
|
||||
.name("new-realm-admin", "new-realm-admin")
|
||||
.email("new-realm-admin@keycloak.org")
|
||||
.emailVerified()
|
||||
.password("password")
|
||||
.clientRoles(Constants.REALM_MANAGEMENT_CLIENT_ID, AdminRoles.REALM_ADMIN)
|
||||
.build()));
|
||||
|
||||
adminClient.realms().create(rep);
|
||||
|
||||
Assert.assertNames(adminClient.realms().findAll(), "master", managedRealm.getName(), realmNameWithSpaces);
|
||||
|
||||
final var urlPlaceHolders = ImmutableSet.of("${authBaseUrl}", "${authAdminUrl}");
|
||||
|
||||
RealmResource newRealm = adminClient.realms().realm(realmNameWithSpaces);
|
||||
List<String> clientUris = newRealm.clients()
|
||||
.findAll()
|
||||
.stream()
|
||||
.flatMap(client -> Stream.concat(Stream.concat(Stream.concat(
|
||||
client.getRedirectUris().stream(),
|
||||
Stream.of(client.getBaseUrl())),
|
||||
Stream.of(client.getRootUrl())),
|
||||
Stream.of(client.getAdminUrl())))
|
||||
.filter(Objects::nonNull)
|
||||
.filter(uri -> !urlPlaceHolders.contains(uri))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(clientUris, not(empty()));
|
||||
assertThat(clientUris, everyItem(containsString("/new%20realm/")));
|
||||
|
||||
try (Keycloak client = adminClientFactory.create().realm(realmNameWithSpaces)
|
||||
.username("new-realm-admin").password("password").clientId(Constants.ADMIN_CLI_CLIENT_ID).build()) {
|
||||
Assertions.assertNotNull(client.serverInfo().getInfo());
|
||||
}
|
||||
|
||||
adminClient.realms().realm(realmNameWithSpaces).remove();
|
||||
|
||||
Assert.assertNames(adminClient.realms().findAll(), "master", managedRealm.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createRealmRejectReservedCharOrEmptyName() {
|
||||
RealmRepresentation rep = new RealmRepresentation();
|
||||
rep.setRealm("new-re;alm");
|
||||
assertThrows(BadRequestException.class, () -> adminClient.realms().create(rep));
|
||||
rep.setRealm("");
|
||||
assertThrows(BadRequestException.class, () -> adminClient.realms().create(rep));
|
||||
rep.setRealm("new-realm");
|
||||
rep.setId("invalid;id");
|
||||
assertThrows(BadRequestException.class, () -> adminClient.realms().create(rep));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createRealmCheckDefaultPasswordPolicy() {
|
||||
RealmRepresentation rep = new RealmRepresentation();
|
||||
rep.setRealm("new-realm");
|
||||
|
||||
adminClient.realms().create(rep);
|
||||
|
||||
assertNull(adminClient.realm("new-realm").toRepresentation().getPasswordPolicy());
|
||||
|
||||
adminClient.realms().realm("new-realm").remove();
|
||||
|
||||
rep.setPasswordPolicy("length(8)");
|
||||
|
||||
adminClient.realms().create(rep);
|
||||
|
||||
assertEquals("length(8)", adminClient.realm("new-realm").toRepresentation().getPasswordPolicy());
|
||||
|
||||
adminClient.realms().realm("new-realm").remove();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createRealmFromJson() throws IOException {
|
||||
RealmRepresentation rep = JsonSerialization.readValue(getClass().getResourceAsStream("testrealm.json"), RealmRepresentation.class);
|
||||
adminClient.realms().create(rep);
|
||||
|
||||
RealmRepresentation created = adminClient.realms().realm("admin-test-1").toRepresentation();
|
||||
assertRealm(rep, created);
|
||||
|
||||
adminClient.realms().realm("admin-test-1").remove();
|
||||
}
|
||||
|
||||
//KEYCLOAK-6146
|
||||
@Test
|
||||
public void createRealmWithPasswordPolicyFromJsonWithInvalidPasswords() throws IOException {
|
||||
RealmRepresentation rep = JsonSerialization.readValue(getClass().getResourceAsStream("testrealm-keycloak-6146-error.json"), RealmRepresentation.class);
|
||||
//try to create realm with password policies and users with plain-text passwords what doesn't met the policies
|
||||
try {
|
||||
adminClient.realms().create(rep);
|
||||
} catch (BadRequestException ex) {
|
||||
//ensure the realm was not created
|
||||
Assertions.assertThrows(NotFoundException.class, () -> {
|
||||
adminClient.realms().realm("secure-app").toRepresentation();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//KEYCLOAK-6146
|
||||
@Test
|
||||
public void createRealmWithPasswordPolicyFromJsonWithValidPasswords() throws IOException {
|
||||
RealmRepresentation rep = JsonSerialization.readValue(RealmCreateTest.class.getResourceAsStream("testrealm-keycloak-6146.json"), RealmRepresentation.class);
|
||||
adminClient.realms().create(rep);
|
||||
assertRealm(rep, adminClient.realm(rep.getRealm()).toRepresentation());
|
||||
adminClient.realms().realm(rep.getRealm()).remove();
|
||||
}
|
||||
|
||||
private void assertRealm(RealmRepresentation realm, RealmRepresentation storedRealm) {
|
||||
if (realm.getRealm() != null) {
|
||||
assertEquals(realm.getRealm(), storedRealm.getRealm());
|
||||
}
|
||||
if (realm.isEnabled() != null) assertEquals(realm.isEnabled(), storedRealm.isEnabled());
|
||||
if (realm.isBruteForceProtected() != null) assertEquals(realm.isBruteForceProtected(), storedRealm.isBruteForceProtected());
|
||||
if (realm.getMaxFailureWaitSeconds() != null) assertEquals(realm.getMaxFailureWaitSeconds(), storedRealm.getMaxFailureWaitSeconds());
|
||||
if (realm.getMinimumQuickLoginWaitSeconds() != null) assertEquals(realm.getMinimumQuickLoginWaitSeconds(), storedRealm.getMinimumQuickLoginWaitSeconds());
|
||||
if (realm.getWaitIncrementSeconds() != null) assertEquals(realm.getWaitIncrementSeconds(), storedRealm.getWaitIncrementSeconds());
|
||||
if (realm.getQuickLoginCheckMilliSeconds() != null) assertEquals(realm.getQuickLoginCheckMilliSeconds(), storedRealm.getQuickLoginCheckMilliSeconds());
|
||||
if (realm.getMaxDeltaTimeSeconds() != null) assertEquals(realm.getMaxDeltaTimeSeconds(), storedRealm.getMaxDeltaTimeSeconds());
|
||||
if (realm.getFailureFactor() != null) assertEquals(realm.getFailureFactor(), storedRealm.getFailureFactor());
|
||||
if (realm.isRegistrationAllowed() != null) assertEquals(realm.isRegistrationAllowed(), storedRealm.isRegistrationAllowed());
|
||||
if (realm.isRegistrationEmailAsUsername() != null) assertEquals(realm.isRegistrationEmailAsUsername(), storedRealm.isRegistrationEmailAsUsername());
|
||||
if (realm.isRememberMe() != null) assertEquals(realm.isRememberMe(), storedRealm.isRememberMe());
|
||||
if (realm.isVerifyEmail() != null) assertEquals(realm.isVerifyEmail(), storedRealm.isVerifyEmail());
|
||||
if (realm.isLoginWithEmailAllowed() != null) assertEquals(realm.isLoginWithEmailAllowed(), storedRealm.isLoginWithEmailAllowed());
|
||||
if (realm.isDuplicateEmailsAllowed() != null) assertEquals(realm.isDuplicateEmailsAllowed(), storedRealm.isDuplicateEmailsAllowed());
|
||||
if (realm.isResetPasswordAllowed() != null) assertEquals(realm.isResetPasswordAllowed(), storedRealm.isResetPasswordAllowed());
|
||||
if (realm.isEditUsernameAllowed() != null) assertEquals(realm.isEditUsernameAllowed(), storedRealm.isEditUsernameAllowed());
|
||||
if (realm.getSslRequired() != null) assertEquals(realm.getSslRequired(), storedRealm.getSslRequired());
|
||||
if (realm.getAccessCodeLifespan() != null) assertEquals(realm.getAccessCodeLifespan(), storedRealm.getAccessCodeLifespan());
|
||||
if (realm.getAccessCodeLifespanUserAction() != null)
|
||||
assertEquals(realm.getAccessCodeLifespanUserAction(), storedRealm.getAccessCodeLifespanUserAction());
|
||||
if (realm.getActionTokenGeneratedByAdminLifespan() != null)
|
||||
assertEquals(realm.getActionTokenGeneratedByAdminLifespan(), storedRealm.getActionTokenGeneratedByAdminLifespan());
|
||||
if (realm.getActionTokenGeneratedByUserLifespan() != null)
|
||||
assertEquals(realm.getActionTokenGeneratedByUserLifespan(), storedRealm.getActionTokenGeneratedByUserLifespan());
|
||||
else
|
||||
assertEquals(realm.getAccessCodeLifespanUserAction(), storedRealm.getActionTokenGeneratedByUserLifespan());
|
||||
if (realm.getNotBefore() != null) assertEquals(realm.getNotBefore(), storedRealm.getNotBefore());
|
||||
if (realm.getAccessTokenLifespan() != null) assertEquals(realm.getAccessTokenLifespan(), storedRealm.getAccessTokenLifespan());
|
||||
if (realm.getAccessTokenLifespanForImplicitFlow() != null) assertEquals(realm.getAccessTokenLifespanForImplicitFlow(), storedRealm.getAccessTokenLifespanForImplicitFlow());
|
||||
if (realm.getSsoSessionIdleTimeout() != null) assertEquals(realm.getSsoSessionIdleTimeout(), storedRealm.getSsoSessionIdleTimeout());
|
||||
if (realm.getSsoSessionMaxLifespan() != null) assertEquals(realm.getSsoSessionMaxLifespan(), storedRealm.getSsoSessionMaxLifespan());
|
||||
if (realm.getSsoSessionIdleTimeoutRememberMe() != null) Assert.assertEquals(realm.getSsoSessionIdleTimeoutRememberMe(), storedRealm.getSsoSessionIdleTimeoutRememberMe());
|
||||
if (realm.getSsoSessionMaxLifespanRememberMe() != null) Assert.assertEquals(realm.getSsoSessionMaxLifespanRememberMe(), storedRealm.getSsoSessionMaxLifespanRememberMe());
|
||||
if (realm.getClientSessionIdleTimeout() != null)
|
||||
Assertions.assertEquals(realm.getClientSessionIdleTimeout(), storedRealm.getClientSessionIdleTimeout());
|
||||
if (realm.getClientSessionMaxLifespan() != null)
|
||||
Assertions.assertEquals(realm.getClientSessionMaxLifespan(), storedRealm.getClientSessionMaxLifespan());
|
||||
if (realm.getClientOfflineSessionIdleTimeout() != null)
|
||||
Assertions.assertEquals(realm.getClientOfflineSessionIdleTimeout(), storedRealm.getClientOfflineSessionIdleTimeout());
|
||||
if (realm.getClientOfflineSessionMaxLifespan() != null)
|
||||
Assertions.assertEquals(realm.getClientOfflineSessionMaxLifespan(), storedRealm.getClientOfflineSessionMaxLifespan());
|
||||
if (realm.getRequiredCredentials() != null) {
|
||||
assertNotNull(storedRealm.getRequiredCredentials());
|
||||
for (String cred : realm.getRequiredCredentials()) {
|
||||
assertTrue(storedRealm.getRequiredCredentials().contains(cred));
|
||||
}
|
||||
}
|
||||
if (realm.getLoginTheme() != null) assertEquals(realm.getLoginTheme(), storedRealm.getLoginTheme());
|
||||
if (realm.getAccountTheme() != null) assertEquals(realm.getAccountTheme(), storedRealm.getAccountTheme());
|
||||
if (realm.getAdminTheme() != null) assertEquals(realm.getAdminTheme(), storedRealm.getAdminTheme());
|
||||
if (realm.getEmailTheme() != null) assertEquals(realm.getEmailTheme(), storedRealm.getEmailTheme());
|
||||
|
||||
if (realm.getPasswordPolicy() != null) assertEquals(realm.getPasswordPolicy(), storedRealm.getPasswordPolicy());
|
||||
|
||||
if (realm.getSmtpServer() != null) {
|
||||
assertEquals(realm.getSmtpServer(), storedRealm.getSmtpServer());
|
||||
}
|
||||
|
||||
if (realm.getBrowserSecurityHeaders() != null) {
|
||||
assertEquals(realm.getBrowserSecurityHeaders(), storedRealm.getBrowserSecurityHeaders());
|
||||
}
|
||||
|
||||
if (realm.getAttributes() != null) {
|
||||
HashMap<String, String> attributes = new HashMap<>();
|
||||
attributes.putAll(storedRealm.getAttributes());
|
||||
attributes.entrySet().retainAll(realm.getAttributes().entrySet());
|
||||
assertEquals(realm.getAttributes(), attributes);
|
||||
}
|
||||
|
||||
if (realm.isUserManagedAccessAllowed() != null) assertEquals(realm.isUserManagedAccessAllowed(), storedRealm.isUserManagedAccessAllowed());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,224 @@
|
||||
/*
|
||||
* 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.tests.admin.realm;
|
||||
|
||||
import jakarta.ws.rs.NotFoundException;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.bouncycastle.util.Strings;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.events.admin.ResourceType;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.representations.idm.AdminEventRepresentation;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.ComponentRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import org.keycloak.testframework.annotations.InjectAdminEvents;
|
||||
import org.keycloak.testframework.annotations.InjectRealm;
|
||||
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
|
||||
import org.keycloak.testframework.events.AdminEventAssertion;
|
||||
import org.keycloak.testframework.events.AdminEvents;
|
||||
import org.keycloak.testframework.realm.ManagedRealm;
|
||||
import org.keycloak.testframework.remote.runonserver.InjectRunOnServer;
|
||||
import org.keycloak.testframework.remote.runonserver.RunOnServerClient;
|
||||
import org.keycloak.tests.utils.admin.AdminEventPaths;
|
||||
import org.keycloak.tests.utils.runonserver.RunHelpers;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
@KeycloakIntegrationTest
|
||||
public class RealmDefaultConfigTest extends AbstractRealmTest {
|
||||
|
||||
@InjectRealm(ref = "realm-with-smtp")
|
||||
ManagedRealm smtpRealm;
|
||||
|
||||
@InjectRunOnServer(ref = "smtp", realmRef = "realm-with-smtp")
|
||||
RunOnServerClient smtpRealmRunOnServer;
|
||||
|
||||
@InjectAdminEvents(ref = "smtpEvents", realmRef = "realm-with-smtp")
|
||||
AdminEvents smtpRealmAdminEvents;
|
||||
|
||||
@Test
|
||||
public void smtpPasswordSecret() {
|
||||
smtpRealm.updateWithCleanup(r -> r.smtp("localhost",3025, "smtp_realm@local"));
|
||||
|
||||
RealmRepresentation rep = smtpRealm.admin().toRepresentation();
|
||||
rep.getSmtpServer().put("auth", "true");
|
||||
rep.getSmtpServer().put("user", "user");
|
||||
rep.getSmtpServer().put("password", "secret");
|
||||
|
||||
smtpRealm.admin().update(rep);
|
||||
smtpRealmAdminEvents.clear();
|
||||
|
||||
RealmRepresentation returned = smtpRealm.admin().toRepresentation();
|
||||
assertEquals(ComponentRepresentation.SECRET_VALUE, returned.getSmtpServer().get("password"));
|
||||
|
||||
RealmRepresentation internalRep = smtpRealmRunOnServer.fetch(RunHelpers.internalRealm());
|
||||
assertEquals("secret", internalRep.getSmtpServer().get("password"));
|
||||
|
||||
smtpRealm.admin().update(rep);
|
||||
|
||||
AdminEventRepresentation event = smtpRealmAdminEvents.poll();
|
||||
assertFalse(event.getRepresentation().contains("some secret value!!"));
|
||||
assertTrue(event.getRepresentation().contains(ComponentRepresentation.SECRET_VALUE));
|
||||
|
||||
internalRep = smtpRealmRunOnServer.fetch(RunHelpers.internalRealm());
|
||||
assertEquals("secret", internalRep.getSmtpServer().get("password"));
|
||||
|
||||
RealmRepresentation realm = adminClient.realms().findAll().stream()
|
||||
.filter(r -> r.getRealm().equals("realm-with-smtp")).findFirst().get();
|
||||
assertEquals(ComponentRepresentation.SECRET_VALUE, realm.getSmtpServer().get("password"));
|
||||
|
||||
// updating setting the secret value with asterisks
|
||||
rep.getSmtpServer().put("password", ComponentRepresentation.SECRET_VALUE);
|
||||
smtpRealm.admin().update(rep);
|
||||
|
||||
event = smtpRealmAdminEvents.poll();
|
||||
assertTrue(event.getRepresentation().contains(ComponentRepresentation.SECRET_VALUE));
|
||||
|
||||
internalRep = smtpRealmRunOnServer.fetch(RunHelpers.internalRealm());
|
||||
assertEquals("secret", internalRep.getSmtpServer().get("password"));
|
||||
|
||||
realm = smtpRealm.admin().toRepresentation();
|
||||
assertEquals(ComponentRepresentation.SECRET_VALUE, realm.getSmtpServer().get("password"));
|
||||
}
|
||||
|
||||
@Test
|
||||
// KEYCLOAK-1110
|
||||
public void deleteDefaultRole() {
|
||||
RoleRepresentation role = new RoleRepresentation("test", "test", false);
|
||||
managedRealm.admin().roles().create(role);
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.CREATE, AdminEventPaths.roleResourcePath("test"), role, ResourceType.REALM_ROLE);
|
||||
|
||||
role = managedRealm.admin().roles().get("test").toRepresentation();
|
||||
assertNotNull(role);
|
||||
|
||||
managedRealm.admin().roles().get(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + Strings.toLowerCase(managedRealm.getName())).addComposites(Collections.singletonList(role));
|
||||
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.CREATE, AdminEventPaths.roleResourceCompositesPath(Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + Strings.toLowerCase(managedRealm.getName())), Collections.singletonList(role), ResourceType.REALM_ROLE);
|
||||
|
||||
managedRealm.admin().roles().deleteRole("test");
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.DELETE, AdminEventPaths.roleResourcePath("test"), ResourceType.REALM_ROLE);
|
||||
|
||||
try {
|
||||
managedRealm.admin().roles().get("testsadfsadf").toRepresentation();
|
||||
fail("Expected NotFoundException");
|
||||
} catch (NotFoundException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertKeycloakClientDescription() throws IOException {
|
||||
ClientRepresentation description = new ClientRepresentation();
|
||||
description.setClientId("client-id");
|
||||
description.setRedirectUris(Collections.singletonList("http://localhost"));
|
||||
|
||||
ClientRepresentation converted = managedRealm.admin().convertClientDescription(JsonSerialization.writeValueAsString(description));
|
||||
assertEquals("client-id", converted.getClientId());
|
||||
assertEquals("http://localhost", converted.getRedirectUris().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertOIDCClientDescription() throws IOException {
|
||||
String description = IOUtils.toString(RealmDefaultConfigTest.class.getResourceAsStream("client-oidc.json"), Charset.defaultCharset());
|
||||
|
||||
ClientRepresentation converted = managedRealm.admin().convertClientDescription(description);
|
||||
assertEquals(1, converted.getRedirectUris().size());
|
||||
assertEquals("http://localhost", converted.getRedirectUris().get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void convertSAMLClientDescription() throws IOException {
|
||||
String description = IOUtils.toString(RealmDefaultConfigTest.class.getResourceAsStream("saml-entity-descriptor.xml"), Charset.defaultCharset());
|
||||
|
||||
ClientRepresentation converted = managedRealm.admin().convertClientDescription(description);
|
||||
assertEquals("loadbalancer-9.siroe.com", converted.getClientId());
|
||||
assertEquals(2, converted.getRedirectUris().size());
|
||||
assertEquals("https://LoadBalancer-9.siroe.com:3443/federation/Consumer/metaAlias/sp", converted.getRedirectUris().get(0));
|
||||
assertEquals("https://LoadBalancer-9.siroe.com:3443/federation/Consumer/metaAlias/sp", converted.getRedirectUris().get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
// KEYCLOAK-17342
|
||||
public void testDefaultSignatureAlgorithm() {
|
||||
RealmRepresentation rep = new RealmRepresentation();
|
||||
rep.setRealm("new-realm");
|
||||
|
||||
adminClient.realms().create(rep);
|
||||
|
||||
assertEquals(Constants.DEFAULT_SIGNATURE_ALGORITHM, adminClient.realm("master").toRepresentation().getDefaultSignatureAlgorithm());
|
||||
assertEquals(Constants.DEFAULT_SIGNATURE_ALGORITHM, adminClient.realm("new-realm").toRepresentation().getDefaultSignatureAlgorithm());
|
||||
|
||||
adminClient.realms().realm("new-realm").remove();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSupportedOTPApplications() {
|
||||
RealmRepresentation rep = new RealmRepresentation();
|
||||
rep.setRealm("new-realm");
|
||||
|
||||
adminClient.realms().create(rep);
|
||||
|
||||
RealmResource realm = adminClient.realms().realm("new-realm");
|
||||
|
||||
rep = realm.toRepresentation();
|
||||
|
||||
List<String> supportedApplications = rep.getOtpSupportedApplications();
|
||||
assertThat(supportedApplications, hasSize(3));
|
||||
assertThat(supportedApplications, containsInAnyOrder("totpAppGoogleName", "totpAppFreeOTPName", "totpAppMicrosoftAuthenticatorName"));
|
||||
|
||||
rep.setOtpPolicyDigits(8);
|
||||
realm.update(rep);
|
||||
|
||||
rep = realm.toRepresentation();
|
||||
|
||||
supportedApplications = rep.getOtpSupportedApplications();
|
||||
assertThat(supportedApplications, hasSize(2));
|
||||
assertThat(supportedApplications, containsInAnyOrder("totpAppFreeOTPName", "totpAppGoogleName"));
|
||||
|
||||
rep.setOtpPolicyType("hotp");
|
||||
realm.update(rep);
|
||||
|
||||
rep = realm.toRepresentation();
|
||||
|
||||
supportedApplications = rep.getOtpSupportedApplications();
|
||||
assertThat(supportedApplications, hasSize(2));
|
||||
assertThat(supportedApplications, containsInAnyOrder("totpAppFreeOTPName", "totpAppGoogleName"));
|
||||
|
||||
adminClient.realms().realm("new-realm").remove();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,250 @@
|
||||
package org.keycloak.tests.admin.realm;
|
||||
|
||||
import jakarta.ws.rs.NotFoundException;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.events.admin.ResourceType;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
import org.keycloak.protocol.saml.SamlProtocol;
|
||||
import org.keycloak.representations.adapters.action.GlobalRequestResult;
|
||||
import org.keycloak.representations.adapters.action.PushNotBeforeAction;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.representations.idm.EventRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.testframework.annotations.InjectEvents;
|
||||
import org.keycloak.testframework.annotations.InjectKeycloakUrls;
|
||||
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
|
||||
import org.keycloak.testframework.events.AdminEventAssertion;
|
||||
import org.keycloak.testframework.events.Events;
|
||||
import org.keycloak.testframework.oauth.OAuthClient;
|
||||
import org.keycloak.testframework.oauth.TestApp;
|
||||
import org.keycloak.testframework.oauth.annotations.InjectOAuthClient;
|
||||
import org.keycloak.testframework.oauth.annotations.InjectTestApp;
|
||||
import org.keycloak.testframework.realm.ClientConfigBuilder;
|
||||
import org.keycloak.testframework.realm.UserConfigBuilder;
|
||||
import org.keycloak.testframework.server.KeycloakUrls;
|
||||
import org.keycloak.tests.utils.admin.ApiUtil;
|
||||
import org.keycloak.tests.utils.admin.AdminEventPaths;
|
||||
import org.keycloak.testsuite.util.oauth.AccessTokenResponse;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
@KeycloakIntegrationTest
|
||||
public class RealmOAuthActionsTest extends AbstractRealmTest {
|
||||
|
||||
@InjectOAuthClient(ref = "managedOAuth", realmRef = "managedRealm")
|
||||
OAuthClient oauth;
|
||||
|
||||
@InjectTestApp
|
||||
TestApp testApp;
|
||||
|
||||
@InjectEvents(ref = "managedEvents", realmRef = "managedRealm")
|
||||
Events events;
|
||||
|
||||
@InjectKeycloakUrls
|
||||
KeycloakUrls keycloakUrls;
|
||||
|
||||
@Test
|
||||
public void pushNotBefore() throws InterruptedException {
|
||||
setupTestAppAndUser();
|
||||
|
||||
int time = Time.currentTime() - 60;
|
||||
|
||||
RealmRepresentation rep = managedRealm.admin().toRepresentation();
|
||||
rep.setNotBefore(time);
|
||||
managedRealm.admin().update(rep);
|
||||
AdminEventAssertion.assertSuccess(adminEvents.poll()).operationType(OperationType.UPDATE).representation(rep).resourceType(ResourceType.REALM);
|
||||
|
||||
GlobalRequestResult globalRequestResult = managedRealm.admin().pushRevocation();
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.ACTION, "push-revocation", globalRequestResult, ResourceType.REALM);
|
||||
|
||||
assertThat(globalRequestResult.getSuccessRequests(), containsInAnyOrder(testApp.getAdminUri()));
|
||||
assertNull(globalRequestResult.getFailedRequests());
|
||||
|
||||
PushNotBeforeAction adminPushNotBefore = testApp.kcAdmin().getAdminPushNotBefore();
|
||||
assertEquals(time, adminPushNotBefore.getNotBefore());
|
||||
|
||||
managedRealm.admin().clients().get("test-app-new").remove();
|
||||
managedRealm.admin().users().get(ApiUtil.findUserByUsername(managedRealm.admin(), "testuser").getId()).remove();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pushNotBeforeWithSamlApp() throws InterruptedException {
|
||||
setupTestAppAndUser();
|
||||
setupTestSamlApp();
|
||||
|
||||
int time = Time.currentTime() - 60;
|
||||
|
||||
RealmRepresentation rep = managedRealm.admin().toRepresentation();
|
||||
rep.setNotBefore(time);
|
||||
managedRealm.admin().update(rep);
|
||||
AdminEventAssertion.assertSuccess(adminEvents.poll()).operationType(OperationType.UPDATE).representation(rep).resourceType(ResourceType.REALM);
|
||||
|
||||
GlobalRequestResult globalRequestResult = managedRealm.admin().pushRevocation();
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.ACTION, "push-revocation", globalRequestResult, ResourceType.REALM);
|
||||
|
||||
assertThat(globalRequestResult.getSuccessRequests(), containsInAnyOrder(testApp.getAdminUri()));
|
||||
assertThat(globalRequestResult.getFailedRequests(), containsInAnyOrder(keycloakUrls.getBase() + "/realms/" + managedRealm.getName() + "/saml-app/saml"));
|
||||
|
||||
PushNotBeforeAction adminPushNotBefore = testApp.kcAdmin().getAdminPushNotBefore();
|
||||
assertEquals(time, adminPushNotBefore.getNotBefore());
|
||||
|
||||
managedRealm.admin().clients().get("test-saml-app").remove();
|
||||
managedRealm.admin().clients().get("test-app-new").remove();
|
||||
managedRealm.admin().users().get(ApiUtil.findUserByUsername(managedRealm.admin(), "testuser").getId()).remove();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logoutAll() throws InterruptedException {
|
||||
setupTestAppAndUser();
|
||||
|
||||
Response response = managedRealm.admin().users().create(UserConfigBuilder.create().username("user").name("User", "Name").email("user@name").emailVerified().build());
|
||||
String userId = ApiUtil.getCreatedId(response);
|
||||
response.close();
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.CREATE, AdminEventPaths.userResourcePath(userId), ResourceType.USER);
|
||||
|
||||
CredentialRepresentation credential = new CredentialRepresentation();
|
||||
credential.setType(CredentialRepresentation.PASSWORD);
|
||||
credential.setValue("password");
|
||||
|
||||
managedRealm.admin().users().get(userId).resetPassword(credential);
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.ACTION, AdminEventPaths.userResetPasswordPath(userId), ResourceType.USER);
|
||||
|
||||
oauth.doPasswordGrantRequest("user", "password");
|
||||
|
||||
GlobalRequestResult globalRequestResult = managedRealm.admin().logoutAll();
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.ACTION, "logout-all", globalRequestResult, ResourceType.REALM);
|
||||
|
||||
assertEquals(1, globalRequestResult.getSuccessRequests().size());
|
||||
assertEquals(testApp.getAdminUri(), globalRequestResult.getSuccessRequests().get(0));
|
||||
assertNull(globalRequestResult.getFailedRequests());
|
||||
|
||||
assertNotNull(testApp.kcAdmin().getAdminLogoutAction());
|
||||
|
||||
managedRealm.admin().clients().get("test-app-new").remove();
|
||||
managedRealm.admin().users().get(ApiUtil.findUserByUsername(managedRealm.admin(), "testuser").getId()).remove();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteSession() {
|
||||
setupTestAppAndUser();
|
||||
|
||||
oauth.doLogin("testuser", "password");
|
||||
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(oauth.parseLoginResponse().getCode());
|
||||
assertEquals(200, tokenResponse.getStatusCode());
|
||||
|
||||
EventRepresentation event = events.poll();
|
||||
assertNotNull(event);
|
||||
|
||||
managedRealm.admin().deleteSession(event.getSessionId(), false);
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.DELETE, AdminEventPaths.deleteSessionPath(event.getSessionId()), ResourceType.USER_SESSION);
|
||||
try {
|
||||
managedRealm.admin().deleteSession(event.getSessionId(), false);
|
||||
fail("Expected 404");
|
||||
} catch (NotFoundException e) {
|
||||
// Expected
|
||||
Assertions.assertNull(adminEvents.poll());
|
||||
}
|
||||
|
||||
tokenResponse = oauth.doRefreshTokenRequest(tokenResponse.getRefreshToken());
|
||||
assertEquals(400, tokenResponse.getStatusCode());
|
||||
assertEquals("Session not active", tokenResponse.getErrorDescription());
|
||||
|
||||
managedRealm.admin().clients().get("test-app-new").remove();
|
||||
managedRealm.admin().users().get(ApiUtil.findUserByUsername(managedRealm.admin(), "testuser").getId()).remove();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clientSessionStats() {
|
||||
setupTestAppAndUser();
|
||||
|
||||
List<Map<String, String>> sessionStats = managedRealm.admin().getClientSessionStats();
|
||||
assertTrue(sessionStats.isEmpty());
|
||||
|
||||
oauth.doLogin("testuser", "password");
|
||||
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(oauth.parseLoginResponse().getCode());
|
||||
assertEquals(200, tokenResponse.getStatusCode());
|
||||
|
||||
sessionStats = managedRealm.admin().getClientSessionStats();
|
||||
|
||||
assertEquals(1, sessionStats.size());
|
||||
assertEquals("test-app-new", sessionStats.get(0).get("clientId"));
|
||||
assertEquals("1", sessionStats.get(0).get("active"));
|
||||
|
||||
String clientUuid = sessionStats.get(0).get("id");
|
||||
managedRealm.admin().clients().get(clientUuid).remove();
|
||||
|
||||
sessionStats = managedRealm.admin().getClientSessionStats();
|
||||
|
||||
assertEquals(0, sessionStats.size());
|
||||
|
||||
managedRealm.admin().users().get(ApiUtil.findUserByUsername(managedRealm.admin(), "testuser").getId()).remove();
|
||||
}
|
||||
|
||||
private void setupTestAppAndUser() {
|
||||
testApp.kcAdmin().clear();
|
||||
|
||||
ClientRepresentation client = ClientConfigBuilder.create()
|
||||
.id("test-app-new")
|
||||
.clientId("test-app-new")
|
||||
.protocol(OIDCLoginProtocol.LOGIN_PROTOCOL)
|
||||
.adminUrl(testApp.getAdminUri())
|
||||
.redirectUris(testApp.getRedirectionUri())
|
||||
.secret("secret")
|
||||
.build();
|
||||
Response resp = managedRealm.admin().clients().create(client);
|
||||
String clientDbId = ApiUtil.getCreatedId(resp);
|
||||
resp.close();
|
||||
|
||||
client.setSecret("**********"); // secrets are masked in events
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.CREATE, AdminEventPaths.clientResourcePath(clientDbId), client, ResourceType.CLIENT);
|
||||
|
||||
oauth.client("test-app-new", "secret");
|
||||
|
||||
UserRepresentation userRep = UserConfigBuilder.create().username("testuser").name("Test", "User").email("test@user").emailVerified().build();
|
||||
Response response = managedRealm.admin().users().create(userRep);
|
||||
String userId = ApiUtil.getCreatedId(response);
|
||||
response.close();
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.CREATE, AdminEventPaths.userResourcePath(userId), userRep, ResourceType.USER);
|
||||
|
||||
CredentialRepresentation credential = new CredentialRepresentation();
|
||||
credential.setType(CredentialRepresentation.PASSWORD);
|
||||
credential.setValue("password");
|
||||
|
||||
managedRealm.admin().users().get(userId).resetPassword(credential);
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.ACTION, AdminEventPaths.userResetPasswordPath(userId), ResourceType.USER);
|
||||
|
||||
testApp.kcAdmin().clear();
|
||||
}
|
||||
|
||||
private void setupTestSamlApp() {
|
||||
ClientRepresentation client = ClientConfigBuilder.create()
|
||||
.id("test-saml-app")
|
||||
.clientId("test-saml-app")
|
||||
.protocol(SamlProtocol.LOGIN_PROTOCOL)
|
||||
.adminUrl(keycloakUrls.getBase() + "/realms/" + managedRealm.getName() + "/saml-app/saml")
|
||||
.redirectUris(oauth.getRedirectUri())
|
||||
.secret("secret")
|
||||
.build();
|
||||
Response resp = managedRealm.admin().clients().create(client);
|
||||
String clientDbId = ApiUtil.getCreatedId(resp);
|
||||
resp.close();
|
||||
|
||||
client.setSecret("**********"); // secrets are masked in events
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.CREATE, AdminEventPaths.clientResourcePath(clientDbId), client, ResourceType.CLIENT);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package org.keycloak.tests.admin.realm;
|
||||
|
||||
import jakarta.ws.rs.BadRequestException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.keycloak.admin.client.Keycloak;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
|
||||
import org.keycloak.tests.utils.Assert;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
@KeycloakIntegrationTest
|
||||
public class RealmRemoveTest extends AbstractRealmTest {
|
||||
|
||||
@Test
|
||||
public void removeRealm() {
|
||||
RealmRepresentation realmRep = managedRealm.admin().toRepresentation();
|
||||
adminClient.realm(managedRealm.getName()).remove();
|
||||
|
||||
Assert.assertNames(adminClient.realms().findAll(), "master");
|
||||
|
||||
adminClient.realms().create(realmRep);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeMasterRealm() {
|
||||
// any attempt to remove the master realm should fail.
|
||||
try {
|
||||
adminClient.realm("master").remove();
|
||||
fail("It should not be possible to remove the master realm");
|
||||
} catch(BadRequestException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginAfterRemoveRealm() {
|
||||
RealmRepresentation realmRep = managedRealm.admin().toRepresentation();
|
||||
adminClient.realm(managedRealm.getName()).remove();
|
||||
|
||||
try (Keycloak client = adminClientFactory.create().realm("master")
|
||||
.username("admin").password("admin").clientId(Constants.ADMIN_CLI_CLIENT_ID).build()) {
|
||||
client.serverInfo().getInfo();
|
||||
}
|
||||
|
||||
adminClient.realms().create(realmRep);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,289 @@
|
||||
package org.keycloak.tests.admin.realm;
|
||||
|
||||
import jakarta.ws.rs.BadRequestException;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.keycloak.events.EventType;
|
||||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.events.admin.ResourceType;
|
||||
import org.keycloak.events.log.JBossLoggingEventListenerProviderFactory;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.RealmEventsConfigRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
|
||||
import org.keycloak.testframework.events.AdminEventAssertion;
|
||||
import org.keycloak.userprofile.UserProfileProvider;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.hasItems;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@KeycloakIntegrationTest
|
||||
public class RealmUpdateTest extends AbstractRealmTest {
|
||||
|
||||
/**
|
||||
* KEYCLOAK-1990 1991
|
||||
*/
|
||||
@Test
|
||||
public void renameRealmTest() {
|
||||
RealmRepresentation realm1 = new RealmRepresentation();
|
||||
realm1.setRealm("test-immutable");
|
||||
adminClient.realms().create(realm1);
|
||||
realm1 = adminClient.realms().realm("test-immutable").toRepresentation();
|
||||
realm1.setRealm("test-immutable-old");
|
||||
adminClient.realms().realm("test-immutable").update(realm1);
|
||||
assertThat(adminClient.realms().realm("test-immutable-old").toRepresentation(), notNullValue());
|
||||
|
||||
RealmRepresentation realm2 = new RealmRepresentation();
|
||||
realm2.setRealm("test-immutable");
|
||||
adminClient.realms().create(realm2);
|
||||
assertThat(adminClient.realms().realm("test-immutable").toRepresentation(), notNullValue());
|
||||
|
||||
adminClient.realms().realm("test-immutable").remove();
|
||||
adminClient.realms().realm("test-immutable-old").remove();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renameRealm() {
|
||||
String OLD = "old";
|
||||
String NEW = "new";
|
||||
|
||||
RealmRepresentation rep = new RealmRepresentation();
|
||||
rep.setId(OLD);
|
||||
rep.setRealm(OLD);
|
||||
|
||||
adminClient.realms().create(rep);
|
||||
|
||||
Map<String, String> newBaseUrls = new HashMap<>();
|
||||
Map<String, List<String>> newRedirectUris = new HashMap<>();
|
||||
|
||||
// memorize all existing clients with their soon-to-be URIs
|
||||
adminClient.realm(OLD).clients().findAll().forEach(client -> {
|
||||
if (client.getBaseUrl() != null && client.getBaseUrl().contains("/" + OLD + "/")) {
|
||||
newBaseUrls.put(client.getClientId(), client.getBaseUrl().replace("/" + OLD + "/", "/" + NEW + "/"));
|
||||
}
|
||||
if (client.getRedirectUris() != null) {
|
||||
newRedirectUris.put(
|
||||
client.getClientId(),
|
||||
client.getRedirectUris()
|
||||
.stream()
|
||||
.map(redirectUri -> redirectUri.replace("/" + OLD + "/", "/" + NEW + "/"))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// at least those three default clients should be in the list of things to be tested
|
||||
assertThat(newBaseUrls.keySet(), hasItems(Constants.ADMIN_CONSOLE_CLIENT_ID, Constants.ACCOUNT_MANAGEMENT_CLIENT_ID, Constants.ACCOUNT_CONSOLE_CLIENT_ID));
|
||||
assertThat(newRedirectUris.keySet(), hasItems(Constants.ADMIN_CONSOLE_CLIENT_ID, Constants.ACCOUNT_MANAGEMENT_CLIENT_ID, Constants.ACCOUNT_CONSOLE_CLIENT_ID));
|
||||
|
||||
rep.setRealm(NEW);
|
||||
adminClient.realm(OLD).update(rep);
|
||||
|
||||
// Check client in master realm renamed
|
||||
Assertions.assertEquals(0, adminClient.realm("master").clients().findByClientId("old-realm").size());
|
||||
Assertions.assertEquals(1, adminClient.realm("master").clients().findByClientId("new-realm").size());
|
||||
|
||||
ClientRepresentation adminConsoleClient = adminClient.realm(NEW).clients().findByClientId(Constants.ADMIN_CONSOLE_CLIENT_ID).get(0);
|
||||
assertEquals(Constants.AUTH_ADMIN_URL_PROP, adminConsoleClient.getRootUrl());
|
||||
|
||||
ClientRepresentation accountClient = adminClient.realm(NEW).clients().findByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).get(0);
|
||||
assertEquals(Constants.AUTH_BASE_URL_PROP, accountClient.getRootUrl());
|
||||
|
||||
ClientRepresentation accountConsoleClient = adminClient.realm(NEW).clients().findByClientId(Constants.ACCOUNT_CONSOLE_CLIENT_ID).get(0);
|
||||
assertEquals(Constants.AUTH_BASE_URL_PROP, accountConsoleClient.getRootUrl());
|
||||
|
||||
newBaseUrls.forEach((clientId, baseUrl) -> {
|
||||
assertEquals(baseUrl, adminClient.realm(NEW).clients().findByClientId(clientId).get(0).getBaseUrl());
|
||||
});
|
||||
newRedirectUris.forEach((clientId, redirectUris) -> {
|
||||
assertEquals(redirectUris, adminClient.realm(NEW).clients().findByClientId(clientId).get(0).getRedirectUris());
|
||||
});
|
||||
|
||||
adminClient.realms().realm(NEW).remove();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateRealmEventsConfig() {
|
||||
RealmEventsConfigRepresentation rep = managedRealm.admin().getRealmEventsConfig();
|
||||
RealmEventsConfigRepresentation repOrig = copyRealmEventsConfigRepresentation(rep);
|
||||
|
||||
// the "jboss-logging" listener should be enabled by default
|
||||
assertTrue(rep.getEventsListeners().contains(JBossLoggingEventListenerProviderFactory.ID), "jboss-logging should be enabled initially");
|
||||
|
||||
// first modification => remove "event-queue", should be sent to the queue
|
||||
rep.setEnabledEventTypes(List.of(EventType.LOGIN.name(), EventType.LOGIN_ERROR.name()));
|
||||
rep.setEventsListeners(List.of(JBossLoggingEventListenerProviderFactory.ID));
|
||||
rep.setEventsExpiration(36000L);
|
||||
rep.setEventsEnabled(false);
|
||||
rep.setAdminEventsEnabled(false);
|
||||
rep.setAdminEventsDetailsEnabled(true);
|
||||
managedRealm.admin().updateRealmEventsConfig(rep);
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.UPDATE, "events/config", rep, ResourceType.REALM);
|
||||
RealmEventsConfigRepresentation actual = managedRealm.admin().getRealmEventsConfig();
|
||||
checkRealmEventsConfigRepresentation(rep, actual);
|
||||
|
||||
// second modification => should not be sent cos event-queue was removed in the first mod
|
||||
rep.setEnabledEventTypes(Arrays.asList(EventType.LOGIN.name(),
|
||||
EventType.LOGIN_ERROR.name(), EventType.CLIENT_LOGIN.name()));
|
||||
managedRealm.admin().updateRealmEventsConfig(rep);
|
||||
Assertions.assertNull(adminEvents.poll());
|
||||
actual = managedRealm.admin().getRealmEventsConfig();
|
||||
checkRealmEventsConfigRepresentation(rep, actual);
|
||||
|
||||
// third modification => restore queue => should be sent and recovered
|
||||
managedRealm.admin().updateRealmEventsConfig(repOrig);
|
||||
AdminEventAssertion.assertEvent(adminEvents.poll(), OperationType.UPDATE, "events/config", repOrig, ResourceType.REALM);
|
||||
actual = managedRealm.admin().getRealmEventsConfig();
|
||||
checkRealmEventsConfigRepresentation(repOrig, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateRealmWithReservedCharInNameOrEmptyName() {
|
||||
RealmRepresentation rep = managedRealm.admin().toRepresentation();
|
||||
rep.setRealm("fo#o");
|
||||
assertThrows(BadRequestException.class, () -> managedRealm.admin().update(rep));
|
||||
rep.setRealm("");
|
||||
assertThrows(BadRequestException.class, () -> managedRealm.admin().update(rep));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateRealm() {
|
||||
// first change
|
||||
RealmRepresentation rep = managedRealm.admin().toRepresentation();
|
||||
rep.setSsoSessionIdleTimeout(123);
|
||||
rep.setSsoSessionMaxLifespan(12);
|
||||
rep.setSsoSessionIdleTimeoutRememberMe(33);
|
||||
rep.setSsoSessionMaxLifespanRememberMe(34);
|
||||
rep.setAccessCodeLifespanLogin(1234);
|
||||
rep.setActionTokenGeneratedByAdminLifespan(2345);
|
||||
rep.setActionTokenGeneratedByUserLifespan(3456);
|
||||
rep.setRegistrationAllowed(true);
|
||||
rep.setRegistrationEmailAsUsername(true);
|
||||
rep.setEditUsernameAllowed(true);
|
||||
rep.setUserManagedAccessAllowed(true);
|
||||
|
||||
managedRealm.admin().update(rep);
|
||||
AdminEventAssertion.assertSuccess(adminEvents.poll()).operationType(OperationType.UPDATE).representation(rep).resourceType(ResourceType.REALM);
|
||||
|
||||
rep = managedRealm.admin().toRepresentation();
|
||||
|
||||
assertEquals(123, rep.getSsoSessionIdleTimeout().intValue());
|
||||
assertEquals(12, rep.getSsoSessionMaxLifespan().intValue());
|
||||
assertEquals(33, rep.getSsoSessionIdleTimeoutRememberMe().intValue());
|
||||
assertEquals(34, rep.getSsoSessionMaxLifespanRememberMe().intValue());
|
||||
assertEquals(1234, rep.getAccessCodeLifespanLogin().intValue());
|
||||
assertEquals(2345, rep.getActionTokenGeneratedByAdminLifespan().intValue());
|
||||
assertEquals(3456, rep.getActionTokenGeneratedByUserLifespan().intValue());
|
||||
assertEquals(Boolean.TRUE, rep.isRegistrationAllowed());
|
||||
assertEquals(Boolean.TRUE, rep.isRegistrationEmailAsUsername());
|
||||
assertEquals(Boolean.TRUE, rep.isEditUsernameAllowed());
|
||||
assertEquals(Boolean.TRUE, rep.isUserManagedAccessAllowed());
|
||||
|
||||
// second change
|
||||
rep.setRegistrationAllowed(false);
|
||||
rep.setRegistrationEmailAsUsername(false);
|
||||
rep.setEditUsernameAllowed(false);
|
||||
rep.setUserManagedAccessAllowed(false);
|
||||
|
||||
managedRealm.admin().update(rep);
|
||||
AdminEventAssertion.assertSuccess(adminEvents.poll()).operationType(OperationType.UPDATE).resourceType(ResourceType.REALM);
|
||||
|
||||
rep = managedRealm.admin().toRepresentation();
|
||||
assertEquals(Boolean.FALSE, rep.isRegistrationAllowed());
|
||||
assertEquals(Boolean.FALSE, rep.isRegistrationEmailAsUsername());
|
||||
assertEquals(Boolean.FALSE, rep.isEditUsernameAllowed());
|
||||
assertEquals(Boolean.FALSE, rep.isUserManagedAccessAllowed());
|
||||
|
||||
rep.setAccessCodeLifespanLogin(0);
|
||||
rep.setAccessCodeLifespanUserAction(0);
|
||||
try {
|
||||
managedRealm.admin().update(rep);
|
||||
Assertions.fail("Not expected to successfully update the realm");
|
||||
} catch (Exception expected) {
|
||||
// Expected exception
|
||||
assertEquals("HTTP 400 Bad Request", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateRealmWithNewRepresentation() {
|
||||
// first change
|
||||
RealmRepresentation rep = new RealmRepresentation();
|
||||
rep.setEditUsernameAllowed(true);
|
||||
rep.setSupportedLocales(new HashSet<>(Arrays.asList("en", "de")));
|
||||
|
||||
managedRealm.admin().update(rep);
|
||||
AdminEventAssertion.assertSuccess(adminEvents.poll()).operationType(OperationType.UPDATE).resourceType(ResourceType.REALM);
|
||||
|
||||
rep = managedRealm.admin().toRepresentation();
|
||||
|
||||
assertEquals(Boolean.TRUE, rep.isEditUsernameAllowed());
|
||||
assertEquals(2, rep.getSupportedLocales().size());
|
||||
|
||||
// second change
|
||||
rep = new RealmRepresentation();
|
||||
rep.setEditUsernameAllowed(false);
|
||||
|
||||
managedRealm.admin().update(rep);
|
||||
AdminEventAssertion.assertSuccess(adminEvents.poll()).operationType(OperationType.UPDATE).resourceType(ResourceType.REALM);
|
||||
|
||||
rep = managedRealm.admin().toRepresentation();
|
||||
assertEquals(Boolean.FALSE, rep.isEditUsernameAllowed());
|
||||
assertEquals(2, rep.getSupportedLocales().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoUserProfileProviderComponentUponRealmChange() {
|
||||
String realmName = "new-realm";
|
||||
RealmRepresentation rep = new RealmRepresentation();
|
||||
rep.setRealm(realmName);
|
||||
|
||||
adminClient.realms().create(rep);
|
||||
|
||||
assertThat(adminClient.realm(realmName).components().query(null, UserProfileProvider.class.getName()), empty());
|
||||
|
||||
rep.setDisplayName("displayName");
|
||||
adminClient.realm(realmName).update(rep);
|
||||
|
||||
// this used to return non-empty collection
|
||||
assertThat(adminClient.realm(realmName).components().query(null, UserProfileProvider.class.getName()), empty());
|
||||
|
||||
adminClient.realms().realm(realmName).remove();
|
||||
}
|
||||
|
||||
private RealmEventsConfigRepresentation copyRealmEventsConfigRepresentation(RealmEventsConfigRepresentation rep) {
|
||||
RealmEventsConfigRepresentation recr = new RealmEventsConfigRepresentation();
|
||||
recr.setEnabledEventTypes(rep.getEnabledEventTypes());
|
||||
recr.setEventsListeners(rep.getEventsListeners());
|
||||
recr.setEventsExpiration(rep.getEventsExpiration());
|
||||
recr.setEventsEnabled(rep.isEventsEnabled());
|
||||
recr.setAdminEventsEnabled(rep.isAdminEventsEnabled());
|
||||
recr.setAdminEventsDetailsEnabled(rep.isAdminEventsDetailsEnabled());
|
||||
return recr;
|
||||
}
|
||||
|
||||
private void checkRealmEventsConfigRepresentation(RealmEventsConfigRepresentation expected,
|
||||
RealmEventsConfigRepresentation actual) {
|
||||
assertEquals(expected.getEnabledEventTypes().size(), actual.getEnabledEventTypes().size());
|
||||
assertTrue(actual.getEnabledEventTypes().containsAll(expected.getEnabledEventTypes()));
|
||||
assertEquals(expected.getEventsListeners().size(), actual.getEventsListeners().size());
|
||||
assertTrue(actual.getEventsListeners().containsAll(expected.getEventsListeners()));
|
||||
assertEquals(expected.getEventsExpiration(), actual.getEventsExpiration());
|
||||
assertEquals(expected.isEventsEnabled(), actual.isEventsEnabled());
|
||||
assertEquals(expected.isAdminEventsEnabled(), actual.isAdminEventsEnabled());
|
||||
assertEquals(expected.isAdminEventsDetailsEnabled(), actual.isAdminEventsDetailsEnabled());
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user