From b5311150b97c4cd1e98a7c481a303770dc9b3fc0 Mon Sep 17 00:00:00 2001 From: eva Date: Fri, 12 Aug 2022 17:11:24 +0200 Subject: [PATCH 1/3] 10227: RelayState max length not respected (fix2) --- server-spi-private/pom.xml | 10 +++ .../provider/util/IdentityBrokerState.java | 44 +++++++++- .../util/IdentityBrokerStateTest.java | 86 +++++++++++++++++++ .../oidc/AbstractOAuth2IdentityProvider.java | 3 +- .../resources/IdentityBrokerService.java | 4 +- .../twitter/TwitterIdentityProvider.java | 2 +- 6 files changed, 140 insertions(+), 9 deletions(-) create mode 100644 server-spi-private/src/test/java/org/keycloak/broker/provider/util/IdentityBrokerStateTest.java diff --git a/server-spi-private/pom.xml b/server-spi-private/pom.xml index 6e6af97184a5..ade516223dc1 100755 --- a/server-spi-private/pom.xml +++ b/server-spi-private/pom.xml @@ -30,6 +30,10 @@ Keycloak Server Private SPI + + 1.9.5 + + org.keycloak @@ -80,6 +84,12 @@ hamcrest test + + org.mockito + mockito-all + ${mockito.version} + test + diff --git a/server-spi-private/src/main/java/org/keycloak/broker/provider/util/IdentityBrokerState.java b/server-spi-private/src/main/java/org/keycloak/broker/provider/util/IdentityBrokerState.java index 1783b1a46b74..897a69064b0d 100644 --- a/server-spi-private/src/main/java/org/keycloak/broker/provider/util/IdentityBrokerState.java +++ b/server-spi-private/src/main/java/org/keycloak/broker/provider/util/IdentityBrokerState.java @@ -17,6 +17,14 @@ package org.keycloak.broker.provider.util; +import org.keycloak.authorization.policy.evaluation.Realm; +import org.keycloak.models.ClientModel; +import org.keycloak.models.RealmModel; + +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; +import java.util.Base64; +import java.util.UUID; import java.util.regex.Pattern; /** @@ -30,20 +38,48 @@ public class IdentityBrokerState { private static final Pattern DOT = Pattern.compile("\\."); - public static IdentityBrokerState decoded(String state, String clientId, String tabId) { - String encodedState = state + "." + tabId + "." + clientId; + public static IdentityBrokerState decoded(String state, String clientId, String clientClientId, String tabId) { - return new IdentityBrokerState(state, clientId, tabId, encodedState); + String clientIdEncoded = clientClientId; // Default use the client.clientId + try { + UUID clientDbUuid = UUID.fromString(clientId); + ByteBuffer bb = ByteBuffer.wrap(new byte[16]); + bb.putLong(clientDbUuid.getMostSignificantBits()); + bb.putLong(clientDbUuid.getLeastSignificantBits()); + byte[] clientUuidBytes = bb.array(); + clientIdEncoded = Base64.getEncoder().encodeToString(clientUuidBytes).replace("=", ""); + } catch (IllegalArgumentException e) { + // Ignore...the clientid in the database was not in UUID format. Just use as is. + } + String encodedState = state + "." + tabId + "." + clientIdEncoded; + + return new IdentityBrokerState(state, clientClientId, tabId, encodedState); } - public static IdentityBrokerState encoded(String encodedState) { + public static IdentityBrokerState encoded(String encodedState, RealmModel realmModel) { String[] decoded = DOT.split(encodedState, 3); String state =(decoded.length > 0) ? decoded[0] : null; String tabId = (decoded.length > 1) ? decoded[1] : null; String clientId = (decoded.length > 2) ? decoded[2] : null; + try { + byte[] decodedClientId = Base64.getDecoder().decode(clientId); + ByteBuffer bb = ByteBuffer.wrap(decodedClientId); + long first = bb.getLong(); + long second = bb.getLong(); + UUID clientDbUuid = new UUID(first, second); + String clientIdInDb = clientDbUuid.toString(); + ClientModel clientModel = realmModel.getClientById(clientIdInDb); + if (clientModel != null) { + clientId = clientModel.getClientId(); + } + } catch (IllegalArgumentException | BufferUnderflowException e) { + // Ignore...the clientid was not in encoded uuid format. Just use as it is. + } + + return new IdentityBrokerState(state, clientId, tabId, encodedState); } diff --git a/server-spi-private/src/test/java/org/keycloak/broker/provider/util/IdentityBrokerStateTest.java b/server-spi-private/src/test/java/org/keycloak/broker/provider/util/IdentityBrokerStateTest.java new file mode 100644 index 000000000000..1096768ea49c --- /dev/null +++ b/server-spi-private/src/test/java/org/keycloak/broker/provider/util/IdentityBrokerStateTest.java @@ -0,0 +1,86 @@ +package org.keycloak.broker.provider.util; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; +import org.keycloak.models.ClientModel; +import org.keycloak.models.RealmModel; +import org.mockito.Mockito; + +public class IdentityBrokerStateTest { + + + @Test + public void testDecodedWithClientIdNotUuid() { + + // Given + String state = "gNrGamIDGKpKSI9yOrcFzYTKoFGH779_WNCacAelkhk"; + String clientId = "something not a uuid"; + String clientClientId = "http://i.am.an.url"; + String tabId = "vpISZLVDAc0"; + + // When + IdentityBrokerState encodedState = IdentityBrokerState.decoded(state, clientId, clientClientId, tabId); + + // Then + Assert.assertNotNull(encodedState); + Assert.assertEquals(clientClientId, encodedState.getClientId()); + Assert.assertEquals(tabId, encodedState.getTabId()); + Assert.assertEquals("gNrGamIDGKpKSI9yOrcFzYTKoFGH779_WNCacAelkhk.vpISZLVDAc0.http://i.am.an.url", encodedState.getEncoded()); + } + + @Test + public void testDecodedWithClientIdAnActualUuid() { + + // Given + String state = "gNrGamIDGKpKSI9yOrcFzYTKoFGH779_WNCacAelkhk"; + String clientId = "ed49448c-14cf-471e-a83a-063d0dc3bc8c"; + String clientClientId = "http://i.am.an.url"; + String tabId = "vpISZLVDAc0"; + + // When + IdentityBrokerState encodedState = IdentityBrokerState.decoded(state, clientId, clientClientId, tabId); + + // Then + Assert.assertNotNull(encodedState); + Assert.assertEquals(clientClientId, encodedState.getClientId()); + Assert.assertEquals(tabId, encodedState.getTabId()); + Assert.assertEquals("gNrGamIDGKpKSI9yOrcFzYTKoFGH779_WNCacAelkhk.vpISZLVDAc0.7UlEjBTPRx6oOgY9DcO8jA", encodedState.getEncoded()); + } + + @Test + @Ignore + public void testEncodedWithClientIdUUid() { + // Given + String encoded = "gNrGamIDGKpKSI9yOrcFzYTKoFGH779_WNCacAelkhk.vpISZLVDAc0.7UlEjBTPRx6oOgY9DcO8jA"; + ClientModel clientModel = Mockito.mock(ClientModel.class); + String myClientId = "my-client-id"; + Mockito.when(clientModel.getClientId()).thenReturn(myClientId); + RealmModel realmModel = Mockito.mock(RealmModel.class); + Mockito.when(realmModel.getClientById(Mockito.eq("ed49448c-14cf-471e-a83a-063d0dc3bc8c"))).thenReturn(clientModel); + + // When + IdentityBrokerState decodedState = IdentityBrokerState.encoded(encoded, realmModel); + + // Then + Assert.assertNotNull(decodedState); + Assert.assertEquals(myClientId, decodedState.getClientId()); + } + + @Test + @Ignore + public void testEncodedWithClientIdNotUUid() { + // Given + String encoded = "gNrGamIDGKpKSI9yOrcFzYTKoFGH779_WNCacAelkhk.vpISZLVDAc0.http://i.am.an.url"; + RealmModel realmModel = Mockito.mock(RealmModel.class); + + // When + IdentityBrokerState decodedState = IdentityBrokerState.encoded(encoded, realmModel); + + // Then + Assert.assertNotNull(decodedState); + Assert.assertEquals("http://i.am.an.url", decodedState.getClientId()); +// Mockito.verify(realmModel).getClientById(tim) + } + +} diff --git a/services/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java b/services/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java index 0b2a286d03e2..0bb485447a54 100755 --- a/services/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java +++ b/services/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java @@ -545,8 +545,7 @@ public SimpleHttp generateTokenRequest(String authorizationCode) { } RealmModel realm = context.getRealm(); - - IdentityBrokerState idpBrokerState = IdentityBrokerState.encoded(stateParam); + IdentityBrokerState idpBrokerState = IdentityBrokerState.encoded(stateParam, realm); ClientModel client = realm.getClientByClientId(idpBrokerState.getClientId()); AuthenticationSessionModel authSession = ClientSessionCode.getClientSession( diff --git a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java index c5ed9001173e..c7d1f923f147 100755 --- a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java +++ b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java @@ -1022,7 +1022,7 @@ private void updateToken(BrokeredIdentityContext context, UserModel federatedUse @Override public AuthenticationSessionModel getAndVerifyAuthenticationSession(String encodedCode) { - IdentityBrokerState state = IdentityBrokerState.encoded(encodedCode); + IdentityBrokerState state = IdentityBrokerState.encoded(encodedCode, realmModel); String code = state.getDecodedState(); String clientId = state.getClientId(); String tabId = state.getTabId(); @@ -1113,7 +1113,7 @@ private AuthenticationRequest createAuthenticationRequest(String providerId, Cli if (clientSessionCode != null) { authSession = clientSessionCode.getClientSession(); String relayState = clientSessionCode.getOrGenerateCode(); - encodedState = IdentityBrokerState.decoded(relayState, authSession.getClient().getClientId(), authSession.getTabId()); + encodedState = IdentityBrokerState.decoded(relayState, authSession.getClient().getId(), authSession.getClient().getClientId(), authSession.getTabId()); } return new AuthenticationRequest(this.session, this.realmModel, authSession, this.request, this.session.getContext().getUri(), encodedState, getRedirectUri(providerId)); diff --git a/services/src/main/java/org/keycloak/social/twitter/TwitterIdentityProvider.java b/services/src/main/java/org/keycloak/social/twitter/TwitterIdentityProvider.java index 0309e503ea2b..548278575021 100755 --- a/services/src/main/java/org/keycloak/social/twitter/TwitterIdentityProvider.java +++ b/services/src/main/java/org/keycloak/social/twitter/TwitterIdentityProvider.java @@ -185,7 +185,7 @@ public Endpoint(RealmModel realm, AuthenticationCallback callback, EventBuilder public Response authResponse(@QueryParam("state") String state, @QueryParam("denied") String denied, @QueryParam("oauth_verifier") String verifier) { - IdentityBrokerState idpState = IdentityBrokerState.encoded(state); + IdentityBrokerState idpState = IdentityBrokerState.encoded(state, realm); String clientId = idpState.getClientId(); String tabId = idpState.getTabId(); if (clientId == null || tabId == null) { From 9752c6f284a975c04eee065c55f864d9da2d8c7a Mon Sep 17 00:00:00 2001 From: eva Date: Sat, 13 Aug 2022 15:56:13 +0200 Subject: [PATCH 2/3] NPE correction to decode and unit tests --- .../provider/util/IdentityBrokerState.java | 52 +++++++++++-------- .../util/IdentityBrokerStateTest.java | 2 - 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/server-spi-private/src/main/java/org/keycloak/broker/provider/util/IdentityBrokerState.java b/server-spi-private/src/main/java/org/keycloak/broker/provider/util/IdentityBrokerState.java index 897a69064b0d..07af68223133 100644 --- a/server-spi-private/src/main/java/org/keycloak/broker/provider/util/IdentityBrokerState.java +++ b/server-spi-private/src/main/java/org/keycloak/broker/provider/util/IdentityBrokerState.java @@ -41,15 +41,20 @@ public class IdentityBrokerState { public static IdentityBrokerState decoded(String state, String clientId, String clientClientId, String tabId) { String clientIdEncoded = clientClientId; // Default use the client.clientId - try { - UUID clientDbUuid = UUID.fromString(clientId); - ByteBuffer bb = ByteBuffer.wrap(new byte[16]); - bb.putLong(clientDbUuid.getMostSignificantBits()); - bb.putLong(clientDbUuid.getLeastSignificantBits()); - byte[] clientUuidBytes = bb.array(); - clientIdEncoded = Base64.getEncoder().encodeToString(clientUuidBytes).replace("=", ""); - } catch (IllegalArgumentException e) { - // Ignore...the clientid in the database was not in UUID format. Just use as is. + if (clientId != null) { + // According to (http://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf) there is a limit on the relaystate of 80 bytes. + // in order to try to adher to the SAML specification we use an encoded value of the client.id (probably UUID) instead of the with + // probability bigger client.clientId. If the client.id is not in UUID format we just use the client.clientid as is + try { + UUID clientDbUuid = UUID.fromString(clientId); + ByteBuffer bb = ByteBuffer.wrap(new byte[16]); + bb.putLong(clientDbUuid.getMostSignificantBits()); + bb.putLong(clientDbUuid.getLeastSignificantBits()); + byte[] clientUuidBytes = bb.array(); + clientIdEncoded = Base64.getEncoder().encodeToString(clientUuidBytes).replace("=", ""); + } catch (IllegalArgumentException e) { + // Ignore...the clientid in the database was not in UUID format. Just use as is. + } } String encodedState = state + "." + tabId + "." + clientIdEncoded; @@ -64,22 +69,25 @@ public static IdentityBrokerState encoded(String encodedState, RealmModel realmM String tabId = (decoded.length > 1) ? decoded[1] : null; String clientId = (decoded.length > 2) ? decoded[2] : null; - try { - byte[] decodedClientId = Base64.getDecoder().decode(clientId); - ByteBuffer bb = ByteBuffer.wrap(decodedClientId); - long first = bb.getLong(); - long second = bb.getLong(); - UUID clientDbUuid = new UUID(first, second); - String clientIdInDb = clientDbUuid.toString(); - ClientModel clientModel = realmModel.getClientById(clientIdInDb); - if (clientModel != null) { - clientId = clientModel.getClientId(); + if (clientId != null) { + try { + // If this decoding succeeds it was the result of the encoding of a UUID client.id - if it fails we interpret it as client.clientId + // in accordance to the method decoded above + byte[] decodedClientId = Base64.getDecoder().decode(clientId); + ByteBuffer bb = ByteBuffer.wrap(decodedClientId); + long first = bb.getLong(); + long second = bb.getLong(); + UUID clientDbUuid = new UUID(first, second); + String clientIdInDb = clientDbUuid.toString(); + ClientModel clientModel = realmModel.getClientById(clientIdInDb); + if (clientModel != null) { + clientId = clientModel.getClientId(); + } + } catch (IllegalArgumentException | BufferUnderflowException e) { + // Ignore...the clientid was not in encoded uuid format. Just use as it is. } - } catch (IllegalArgumentException | BufferUnderflowException e) { - // Ignore...the clientid was not in encoded uuid format. Just use as it is. } - return new IdentityBrokerState(state, clientId, tabId, encodedState); } diff --git a/server-spi-private/src/test/java/org/keycloak/broker/provider/util/IdentityBrokerStateTest.java b/server-spi-private/src/test/java/org/keycloak/broker/provider/util/IdentityBrokerStateTest.java index 1096768ea49c..5e0400d3d99f 100644 --- a/server-spi-private/src/test/java/org/keycloak/broker/provider/util/IdentityBrokerStateTest.java +++ b/server-spi-private/src/test/java/org/keycloak/broker/provider/util/IdentityBrokerStateTest.java @@ -49,7 +49,6 @@ public void testDecodedWithClientIdAnActualUuid() { } @Test - @Ignore public void testEncodedWithClientIdUUid() { // Given String encoded = "gNrGamIDGKpKSI9yOrcFzYTKoFGH779_WNCacAelkhk.vpISZLVDAc0.7UlEjBTPRx6oOgY9DcO8jA"; @@ -68,7 +67,6 @@ public void testEncodedWithClientIdUUid() { } @Test - @Ignore public void testEncodedWithClientIdNotUUid() { // Given String encoded = "gNrGamIDGKpKSI9yOrcFzYTKoFGH779_WNCacAelkhk.vpISZLVDAc0.http://i.am.an.url"; From ae4b7c24c2d4568b5743218d6c780780f8e55f7b Mon Sep 17 00:00:00 2001 From: eva Date: Mon, 22 Aug 2022 09:19:01 +0200 Subject: [PATCH 3/3] Implementing tests without mockito --- server-spi-private/pom.xml | 10 - .../util/IdentityBrokerStateTest.java | 23 +- .../util/IdentityBrokerStateTestHelpers.java | 1787 +++++++++++++++++ 3 files changed, 1797 insertions(+), 23 deletions(-) create mode 100644 server-spi-private/src/test/java/org/keycloak/broker/provider/util/IdentityBrokerStateTestHelpers.java diff --git a/server-spi-private/pom.xml b/server-spi-private/pom.xml index ade516223dc1..6e6af97184a5 100755 --- a/server-spi-private/pom.xml +++ b/server-spi-private/pom.xml @@ -30,10 +30,6 @@ Keycloak Server Private SPI - - 1.9.5 - - org.keycloak @@ -84,12 +80,6 @@ hamcrest test - - org.mockito - mockito-all - ${mockito.version} - test - diff --git a/server-spi-private/src/test/java/org/keycloak/broker/provider/util/IdentityBrokerStateTest.java b/server-spi-private/src/test/java/org/keycloak/broker/provider/util/IdentityBrokerStateTest.java index 5e0400d3d99f..29adcf743737 100644 --- a/server-spi-private/src/test/java/org/keycloak/broker/provider/util/IdentityBrokerStateTest.java +++ b/server-spi-private/src/test/java/org/keycloak/broker/provider/util/IdentityBrokerStateTest.java @@ -1,14 +1,11 @@ package org.keycloak.broker.provider.util; import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; -import org.keycloak.models.ClientModel; -import org.keycloak.models.RealmModel; -import org.mockito.Mockito; +import org.keycloak.models.*; -public class IdentityBrokerStateTest { +public class IdentityBrokerStateTest { @Test public void testDecodedWithClientIdNotUuid() { @@ -52,25 +49,26 @@ public void testDecodedWithClientIdAnActualUuid() { public void testEncodedWithClientIdUUid() { // Given String encoded = "gNrGamIDGKpKSI9yOrcFzYTKoFGH779_WNCacAelkhk.vpISZLVDAc0.7UlEjBTPRx6oOgY9DcO8jA"; - ClientModel clientModel = Mockito.mock(ClientModel.class); - String myClientId = "my-client-id"; - Mockito.when(clientModel.getClientId()).thenReturn(myClientId); - RealmModel realmModel = Mockito.mock(RealmModel.class); - Mockito.when(realmModel.getClientById(Mockito.eq("ed49448c-14cf-471e-a83a-063d0dc3bc8c"))).thenReturn(clientModel); + String clientId = "ed49448c-14cf-471e-a83a-063d0dc3bc8c"; + String clientClientId = "my-client-id"; + ClientModel clientModel = new IdentityBrokerStateTestHelpers.TestClientModel(clientId, clientClientId); + RealmModel realmModel = new IdentityBrokerStateTestHelpers.TestRealmModel(clientId, clientClientId, clientModel); // When IdentityBrokerState decodedState = IdentityBrokerState.encoded(encoded, realmModel); // Then Assert.assertNotNull(decodedState); - Assert.assertEquals(myClientId, decodedState.getClientId()); + Assert.assertEquals(clientClientId, decodedState.getClientId()); } @Test public void testEncodedWithClientIdNotUUid() { // Given String encoded = "gNrGamIDGKpKSI9yOrcFzYTKoFGH779_WNCacAelkhk.vpISZLVDAc0.http://i.am.an.url"; - RealmModel realmModel = Mockito.mock(RealmModel.class); + String clientId = "http://i.am.an.url"; + ClientModel clientModel = new IdentityBrokerStateTestHelpers.TestClientModel(clientId, clientId); + RealmModel realmModel = new IdentityBrokerStateTestHelpers.TestRealmModel(clientId, clientId, clientModel); // When IdentityBrokerState decodedState = IdentityBrokerState.encoded(encoded, realmModel); @@ -78,7 +76,6 @@ public void testEncodedWithClientIdNotUUid() { // Then Assert.assertNotNull(decodedState); Assert.assertEquals("http://i.am.an.url", decodedState.getClientId()); -// Mockito.verify(realmModel).getClientById(tim) } } diff --git a/server-spi-private/src/test/java/org/keycloak/broker/provider/util/IdentityBrokerStateTestHelpers.java b/server-spi-private/src/test/java/org/keycloak/broker/provider/util/IdentityBrokerStateTestHelpers.java new file mode 100644 index 000000000000..13d45100e87c --- /dev/null +++ b/server-spi-private/src/test/java/org/keycloak/broker/provider/util/IdentityBrokerStateTestHelpers.java @@ -0,0 +1,1787 @@ +package org.keycloak.broker.provider.util; + +import org.keycloak.common.enums.SslRequired; +import org.keycloak.component.ComponentModel; +import org.keycloak.models.*; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +public class IdentityBrokerStateTestHelpers { + + public static class TestClientModel implements ClientModel { + + private String id; + + private String clientId; + + public TestClientModel(String id, String clientId) { + this.id = id; + this.clientId = clientId; + } + + @Override + public void updateClient() { + + } + + @Override + public String getId() { + return id; + } + + @Override + public RoleModel getRole(String name) { + return null; + } + + @Override + public RoleModel addRole(String name) { + return null; + } + + @Override + public RoleModel addRole(String id, String name) { + return null; + } + + @Override + public boolean removeRole(RoleModel role) { + return false; + } + + @Override + public Stream getRolesStream() { + return null; + } + + @Override + public Stream getRolesStream(Integer firstResult, Integer maxResults) { + return null; + } + + @Override + public Stream searchForRolesStream(String search, Integer first, Integer max) { + return null; + } + + @Override + public Stream getDefaultRolesStream() { + return null; + } + + @Override + public void addDefaultRole(String name) { + + } + + @Override + public void removeDefaultRoles(String... defaultRoles) { + + } + + @Override + public String getClientId() { + return clientId; + } + + @Override + public void setClientId(String clientId) { + + } + + @Override + public String getName() { + return null; + } + + @Override + public void setName(String name) { + + } + + @Override + public String getDescription() { + return null; + } + + @Override + public void setDescription(String description) { + + } + + @Override + public boolean isEnabled() { + return false; + } + + @Override + public void setEnabled(boolean enabled) { + + } + + @Override + public boolean isAlwaysDisplayInConsole() { + return false; + } + + @Override + public void setAlwaysDisplayInConsole(boolean alwaysDisplayInConsole) { + + } + + @Override + public boolean isSurrogateAuthRequired() { + return false; + } + + @Override + public void setSurrogateAuthRequired(boolean surrogateAuthRequired) { + + } + + @Override + public Set getWebOrigins() { + return null; + } + + @Override + public void setWebOrigins(Set webOrigins) { + + } + + @Override + public void addWebOrigin(String webOrigin) { + + } + + @Override + public void removeWebOrigin(String webOrigin) { + + } + + @Override + public Set getRedirectUris() { + return null; + } + + @Override + public void setRedirectUris(Set redirectUris) { + + } + + @Override + public void addRedirectUri(String redirectUri) { + + } + + @Override + public void removeRedirectUri(String redirectUri) { + + } + + @Override + public String getManagementUrl() { + return null; + } + + @Override + public void setManagementUrl(String url) { + + } + + @Override + public String getRootUrl() { + return null; + } + + @Override + public void setRootUrl(String url) { + + } + + @Override + public String getBaseUrl() { + return null; + } + + @Override + public void setBaseUrl(String url) { + + } + + @Override + public boolean isBearerOnly() { + return false; + } + + @Override + public void setBearerOnly(boolean only) { + + } + + @Override + public int getNodeReRegistrationTimeout() { + return 0; + } + + @Override + public void setNodeReRegistrationTimeout(int timeout) { + + } + + @Override + public String getClientAuthenticatorType() { + return null; + } + + @Override + public void setClientAuthenticatorType(String clientAuthenticatorType) { + + } + + @Override + public boolean validateSecret(String secret) { + return false; + } + + @Override + public String getSecret() { + return null; + } + + @Override + public void setSecret(String secret) { + + } + + @Override + public String getRegistrationToken() { + return null; + } + + @Override + public void setRegistrationToken(String registrationToken) { + + } + + @Override + public String getProtocol() { + return null; + } + + @Override + public void setProtocol(String protocol) { + + } + + @Override + public void setAttribute(String name, String value) { + + } + + @Override + public void removeAttribute(String name) { + + } + + @Override + public String getAttribute(String name) { + return null; + } + + @Override + public Map getAttributes() { + return null; + } + + @Override + public String getAuthenticationFlowBindingOverride(String binding) { + return null; + } + + @Override + public Map getAuthenticationFlowBindingOverrides() { + return null; + } + + @Override + public void removeAuthenticationFlowBindingOverride(String binding) { + + } + + @Override + public void setAuthenticationFlowBindingOverride(String binding, String flowId) { + + } + + @Override + public boolean isFrontchannelLogout() { + return false; + } + + @Override + public void setFrontchannelLogout(boolean flag) { + + } + + @Override + public boolean isFullScopeAllowed() { + return false; + } + + @Override + public void setFullScopeAllowed(boolean value) { + + } + + @Override + public boolean isPublicClient() { + return false; + } + + @Override + public void setPublicClient(boolean flag) { + + } + + @Override + public boolean isConsentRequired() { + return false; + } + + @Override + public void setConsentRequired(boolean consentRequired) { + + } + + @Override + public boolean isStandardFlowEnabled() { + return false; + } + + @Override + public void setStandardFlowEnabled(boolean standardFlowEnabled) { + + } + + @Override + public boolean isImplicitFlowEnabled() { + return false; + } + + @Override + public void setImplicitFlowEnabled(boolean implicitFlowEnabled) { + + } + + @Override + public boolean isDirectAccessGrantsEnabled() { + return false; + } + + @Override + public void setDirectAccessGrantsEnabled(boolean directAccessGrantsEnabled) { + + } + + @Override + public boolean isServiceAccountsEnabled() { + return false; + } + + @Override + public void setServiceAccountsEnabled(boolean serviceAccountsEnabled) { + + } + + @Override + public RealmModel getRealm() { + return null; + } + + @Override + public void addClientScope(ClientScopeModel clientScope, boolean defaultScope) { + + } + + @Override + public void addClientScopes(Set clientScopes, boolean defaultScope) { + + } + + @Override + public void removeClientScope(ClientScopeModel clientScope) { + + } + + @Override + public Map getClientScopes(boolean defaultScope) { + return null; + } + + @Override + public int getNotBefore() { + return 0; + } + + @Override + public void setNotBefore(int notBefore) { + + } + + @Override + public Map getRegisteredNodes() { + return null; + } + + @Override + public void registerNode(String nodeHost, int registrationTime) { + + } + + @Override + public void unregisterNode(String nodeHost) { + + } + + @Override + public Stream getProtocolMappersStream() { + return null; + } + + @Override + public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) { + return null; + } + + @Override + public void removeProtocolMapper(ProtocolMapperModel mapping) { + + } + + @Override + public void updateProtocolMapper(ProtocolMapperModel mapping) { + + } + + @Override + public ProtocolMapperModel getProtocolMapperById(String id) { + return null; + } + + @Override + public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) { + return null; + } + + @Override + public Stream getScopeMappingsStream() { + return null; + } + + @Override + public Stream getRealmScopeMappingsStream() { + return null; + } + + @Override + public void addScopeMapping(RoleModel role) { + + } + + @Override + public void deleteScopeMapping(RoleModel role) { + + } + + @Override + public boolean hasScope(RoleModel role) { + return false; + } + } + + public static class TestRealmModel implements RealmModel { + + private Map clientIdToModel = new HashMap<>(); + private Map clientClientIdToModel = new HashMap<>(); + + public TestRealmModel(String clientId, String clientClientId, ClientModel cm) { + clientIdToModel.put(clientId, cm); + clientClientIdToModel.put(clientClientId, cm); + } + + @Override + public String getId() { + return null; + } + + @Override + public RoleModel getRole(String name) { + return null; + } + + @Override + public RoleModel addRole(String name) { + return null; + } + + @Override + public RoleModel addRole(String id, String name) { + return null; + } + + @Override + public boolean removeRole(RoleModel role) { + return false; + } + + @Override + public Stream getRolesStream() { + return null; + } + + @Override + public Stream getRolesStream(Integer firstResult, Integer maxResults) { + return null; + } + + @Override + public Stream searchForRolesStream(String search, Integer first, Integer max) { + return null; + } + + @Override + public Stream getDefaultRolesStream() { + return null; + } + + @Override + public void addDefaultRole(String name) { + + } + + @Override + public void removeDefaultRoles(String... defaultRoles) { + + } + + @Override + public String getName() { + return null; + } + + @Override + public void setName(String name) { + + } + + @Override + public String getDisplayName() { + return null; + } + + @Override + public void setDisplayName(String displayName) { + + } + + @Override + public String getDisplayNameHtml() { + return null; + } + + @Override + public void setDisplayNameHtml(String displayNameHtml) { + + } + + @Override + public boolean isEnabled() { + return false; + } + + @Override + public void setEnabled(boolean enabled) { + + } + + @Override + public SslRequired getSslRequired() { + return null; + } + + @Override + public void setSslRequired(SslRequired sslRequired) { + + } + + @Override + public boolean isRegistrationAllowed() { + return false; + } + + @Override + public void setRegistrationAllowed(boolean registrationAllowed) { + + } + + @Override + public boolean isRegistrationEmailAsUsername() { + return false; + } + + @Override + public void setRegistrationEmailAsUsername(boolean registrationEmailAsUsername) { + + } + + @Override + public boolean isRememberMe() { + return false; + } + + @Override + public void setRememberMe(boolean rememberMe) { + + } + + @Override + public boolean isEditUsernameAllowed() { + return false; + } + + @Override + public void setEditUsernameAllowed(boolean editUsernameAllowed) { + + } + + @Override + public boolean isUserManagedAccessAllowed() { + return false; + } + + @Override + public void setUserManagedAccessAllowed(boolean userManagedAccessAllowed) { + + } + + @Override + public void setAttribute(String name, String value) { + + } + + @Override + public void removeAttribute(String name) { + + } + + @Override + public String getAttribute(String name) { + return null; + } + + @Override + public Map getAttributes() { + return null; + } + + @Override + public boolean isBruteForceProtected() { + return false; + } + + @Override + public void setBruteForceProtected(boolean value) { + + } + + @Override + public boolean isPermanentLockout() { + return false; + } + + @Override + public void setPermanentLockout(boolean val) { + + } + + @Override + public int getMaxFailureWaitSeconds() { + return 0; + } + + @Override + public void setMaxFailureWaitSeconds(int val) { + + } + + @Override + public int getWaitIncrementSeconds() { + return 0; + } + + @Override + public void setWaitIncrementSeconds(int val) { + + } + + @Override + public int getMinimumQuickLoginWaitSeconds() { + return 0; + } + + @Override + public void setMinimumQuickLoginWaitSeconds(int val) { + + } + + @Override + public long getQuickLoginCheckMilliSeconds() { + return 0; + } + + @Override + public void setQuickLoginCheckMilliSeconds(long val) { + + } + + @Override + public int getMaxDeltaTimeSeconds() { + return 0; + } + + @Override + public void setMaxDeltaTimeSeconds(int val) { + + } + + @Override + public int getFailureFactor() { + return 0; + } + + @Override + public void setFailureFactor(int failureFactor) { + + } + + @Override + public boolean isVerifyEmail() { + return false; + } + + @Override + public void setVerifyEmail(boolean verifyEmail) { + + } + + @Override + public boolean isLoginWithEmailAllowed() { + return false; + } + + @Override + public void setLoginWithEmailAllowed(boolean loginWithEmailAllowed) { + + } + + @Override + public boolean isDuplicateEmailsAllowed() { + return false; + } + + @Override + public void setDuplicateEmailsAllowed(boolean duplicateEmailsAllowed) { + + } + + @Override + public boolean isResetPasswordAllowed() { + return false; + } + + @Override + public void setResetPasswordAllowed(boolean resetPasswordAllowed) { + + } + + @Override + public String getDefaultSignatureAlgorithm() { + return null; + } + + @Override + public void setDefaultSignatureAlgorithm(String defaultSignatureAlgorithm) { + + } + + @Override + public boolean isRevokeRefreshToken() { + return false; + } + + @Override + public void setRevokeRefreshToken(boolean revokeRefreshToken) { + + } + + @Override + public int getRefreshTokenMaxReuse() { + return 0; + } + + @Override + public void setRefreshTokenMaxReuse(int revokeRefreshTokenCount) { + + } + + @Override + public int getSsoSessionIdleTimeout() { + return 0; + } + + @Override + public void setSsoSessionIdleTimeout(int seconds) { + + } + + @Override + public int getSsoSessionMaxLifespan() { + return 0; + } + + @Override + public void setSsoSessionMaxLifespan(int seconds) { + + } + + @Override + public int getSsoSessionIdleTimeoutRememberMe() { + return 0; + } + + @Override + public void setSsoSessionIdleTimeoutRememberMe(int seconds) { + + } + + @Override + public int getSsoSessionMaxLifespanRememberMe() { + return 0; + } + + @Override + public void setSsoSessionMaxLifespanRememberMe(int seconds) { + + } + + @Override + public int getOfflineSessionIdleTimeout() { + return 0; + } + + @Override + public void setOfflineSessionIdleTimeout(int seconds) { + + } + + @Override + public int getAccessTokenLifespan() { + return 0; + } + + @Override + public boolean isOfflineSessionMaxLifespanEnabled() { + return false; + } + + @Override + public void setOfflineSessionMaxLifespanEnabled(boolean offlineSessionMaxLifespanEnabled) { + + } + + @Override + public int getOfflineSessionMaxLifespan() { + return 0; + } + + @Override + public void setOfflineSessionMaxLifespan(int seconds) { + + } + + @Override + public int getClientSessionIdleTimeout() { + return 0; + } + + @Override + public void setClientSessionIdleTimeout(int seconds) { + + } + + @Override + public int getClientSessionMaxLifespan() { + return 0; + } + + @Override + public void setClientSessionMaxLifespan(int seconds) { + + } + + @Override + public int getClientOfflineSessionIdleTimeout() { + return 0; + } + + @Override + public void setClientOfflineSessionIdleTimeout(int seconds) { + + } + + @Override + public int getClientOfflineSessionMaxLifespan() { + return 0; + } + + @Override + public void setClientOfflineSessionMaxLifespan(int seconds) { + + } + + @Override + public void setAccessTokenLifespan(int seconds) { + + } + + @Override + public int getAccessTokenLifespanForImplicitFlow() { + return 0; + } + + @Override + public void setAccessTokenLifespanForImplicitFlow(int seconds) { + + } + + @Override + public int getAccessCodeLifespan() { + return 0; + } + + @Override + public void setAccessCodeLifespan(int seconds) { + + } + + @Override + public int getAccessCodeLifespanUserAction() { + return 0; + } + + @Override + public void setAccessCodeLifespanUserAction(int seconds) { + + } + + @Override + public OAuth2DeviceConfig getOAuth2DeviceConfig() { + return null; + } + + @Override + public CibaConfig getCibaPolicy() { + return null; + } + + @Override + public ParConfig getParPolicy() { + return null; + } + + @Override + public Map getUserActionTokenLifespans() { + return null; + } + + @Override + public int getAccessCodeLifespanLogin() { + return 0; + } + + @Override + public void setAccessCodeLifespanLogin(int seconds) { + + } + + @Override + public int getActionTokenGeneratedByAdminLifespan() { + return 0; + } + + @Override + public void setActionTokenGeneratedByAdminLifespan(int seconds) { + + } + + @Override + public int getActionTokenGeneratedByUserLifespan() { + return 0; + } + + @Override + public void setActionTokenGeneratedByUserLifespan(int seconds) { + + } + + @Override + public int getActionTokenGeneratedByUserLifespan(String actionTokenType) { + return 0; + } + + @Override + public void setActionTokenGeneratedByUserLifespan(String actionTokenType, Integer seconds) { + + } + + @Override + public Stream getRequiredCredentialsStream() { + return null; + } + + @Override + public void addRequiredCredential(String cred) { + + } + + @Override + public PasswordPolicy getPasswordPolicy() { + return null; + } + + @Override + public void setPasswordPolicy(PasswordPolicy policy) { + + } + + @Override + public OTPPolicy getOTPPolicy() { + return null; + } + + @Override + public void setOTPPolicy(OTPPolicy policy) { + + } + + @Override + public WebAuthnPolicy getWebAuthnPolicy() { + return null; + } + + @Override + public void setWebAuthnPolicy(WebAuthnPolicy policy) { + + } + + @Override + public WebAuthnPolicy getWebAuthnPolicyPasswordless() { + return null; + } + + @Override + public void setWebAuthnPolicyPasswordless(WebAuthnPolicy policy) { + + } + + @Override + public RoleModel getRoleById(String id) { + return null; + } + + @Override + public Stream getDefaultGroupsStream() { + return null; + } + + @Override + public void addDefaultGroup(GroupModel group) { + + } + + @Override + public void removeDefaultGroup(GroupModel group) { + + } + + @Override + public Stream getClientsStream() { + return null; + } + + @Override + public Stream getClientsStream(Integer firstResult, Integer maxResults) { + return null; + } + + @Override + public Long getClientsCount() { + return null; + } + + @Override + public Stream getAlwaysDisplayInConsoleClientsStream() { + return null; + } + + @Override + public ClientModel addClient(String name) { + return null; + } + + @Override + public ClientModel addClient(String id, String clientId) { + return null; + } + + @Override + public boolean removeClient(String id) { + return false; + } + + @Override + public ClientModel getClientById(String id) { + return clientIdToModel.get(id); + } + + @Override + public ClientModel getClientByClientId(String clientId) { + return clientClientIdToModel.get(clientId); + } + + @Override + public Stream searchClientByClientIdStream(String clientId, Integer firstResult, Integer maxResults) { + return null; + } + + @Override + public Stream searchClientByAttributes(Map attributes, Integer firstResult, Integer maxResults) { + return null; + } + + @Override + public void updateRequiredCredentials(Set creds) { + + } + + @Override + public Map getBrowserSecurityHeaders() { + return null; + } + + @Override + public void setBrowserSecurityHeaders(Map headers) { + + } + + @Override + public Map getSmtpConfig() { + return null; + } + + @Override + public void setSmtpConfig(Map smtpConfig) { + + } + + @Override + public AuthenticationFlowModel getBrowserFlow() { + return null; + } + + @Override + public void setBrowserFlow(AuthenticationFlowModel flow) { + + } + + @Override + public AuthenticationFlowModel getRegistrationFlow() { + return null; + } + + @Override + public void setRegistrationFlow(AuthenticationFlowModel flow) { + + } + + @Override + public AuthenticationFlowModel getDirectGrantFlow() { + return null; + } + + @Override + public void setDirectGrantFlow(AuthenticationFlowModel flow) { + + } + + @Override + public AuthenticationFlowModel getResetCredentialsFlow() { + return null; + } + + @Override + public void setResetCredentialsFlow(AuthenticationFlowModel flow) { + + } + + @Override + public AuthenticationFlowModel getClientAuthenticationFlow() { + return null; + } + + @Override + public void setClientAuthenticationFlow(AuthenticationFlowModel flow) { + + } + + @Override + public AuthenticationFlowModel getDockerAuthenticationFlow() { + return null; + } + + @Override + public void setDockerAuthenticationFlow(AuthenticationFlowModel flow) { + + } + + @Override + public Stream getAuthenticationFlowsStream() { + return null; + } + + @Override + public AuthenticationFlowModel getFlowByAlias(String alias) { + return null; + } + + @Override + public AuthenticationFlowModel addAuthenticationFlow(AuthenticationFlowModel model) { + return null; + } + + @Override + public AuthenticationFlowModel getAuthenticationFlowById(String id) { + return null; + } + + @Override + public void removeAuthenticationFlow(AuthenticationFlowModel model) { + + } + + @Override + public void updateAuthenticationFlow(AuthenticationFlowModel model) { + + } + + @Override + public Stream getAuthenticationExecutionsStream(String flowId) { + return null; + } + + @Override + public AuthenticationExecutionModel getAuthenticationExecutionById(String id) { + return null; + } + + @Override + public AuthenticationExecutionModel getAuthenticationExecutionByFlowId(String flowId) { + return null; + } + + @Override + public AuthenticationExecutionModel addAuthenticatorExecution(AuthenticationExecutionModel model) { + return null; + } + + @Override + public void updateAuthenticatorExecution(AuthenticationExecutionModel model) { + + } + + @Override + public void removeAuthenticatorExecution(AuthenticationExecutionModel model) { + + } + + @Override + public Stream getAuthenticatorConfigsStream() { + return null; + } + + @Override + public AuthenticatorConfigModel addAuthenticatorConfig(AuthenticatorConfigModel model) { + return null; + } + + @Override + public void updateAuthenticatorConfig(AuthenticatorConfigModel model) { + + } + + @Override + public void removeAuthenticatorConfig(AuthenticatorConfigModel model) { + + } + + @Override + public AuthenticatorConfigModel getAuthenticatorConfigById(String id) { + return null; + } + + @Override + public AuthenticatorConfigModel getAuthenticatorConfigByAlias(String alias) { + return null; + } + + @Override + public Stream getRequiredActionProvidersStream() { + return null; + } + + @Override + public RequiredActionProviderModel addRequiredActionProvider(RequiredActionProviderModel model) { + return null; + } + + @Override + public void updateRequiredActionProvider(RequiredActionProviderModel model) { + + } + + @Override + public void removeRequiredActionProvider(RequiredActionProviderModel model) { + + } + + @Override + public RequiredActionProviderModel getRequiredActionProviderById(String id) { + return null; + } + + @Override + public RequiredActionProviderModel getRequiredActionProviderByAlias(String alias) { + return null; + } + + @Override + public Stream getIdentityProvidersStream() { + return null; + } + + @Override + public IdentityProviderModel getIdentityProviderByAlias(String alias) { + return null; + } + + @Override + public void addIdentityProvider(IdentityProviderModel identityProvider) { + + } + + @Override + public void removeIdentityProviderByAlias(String alias) { + + } + + @Override + public void updateIdentityProvider(IdentityProviderModel identityProvider) { + + } + + @Override + public Stream getIdentityProviderMappersStream() { + return null; + } + + @Override + public Stream getIdentityProviderMappersByAliasStream(String brokerAlias) { + return null; + } + + @Override + public IdentityProviderMapperModel addIdentityProviderMapper(IdentityProviderMapperModel model) { + return null; + } + + @Override + public void removeIdentityProviderMapper(IdentityProviderMapperModel mapping) { + + } + + @Override + public void updateIdentityProviderMapper(IdentityProviderMapperModel mapping) { + + } + + @Override + public IdentityProviderMapperModel getIdentityProviderMapperById(String id) { + return null; + } + + @Override + public IdentityProviderMapperModel getIdentityProviderMapperByName(String brokerAlias, String name) { + return null; + } + + @Override + public ComponentModel addComponentModel(ComponentModel model) { + return null; + } + + @Override + public ComponentModel importComponentModel(ComponentModel model) { + return null; + } + + @Override + public void updateComponent(ComponentModel component) { + + } + + @Override + public void removeComponent(ComponentModel component) { + + } + + @Override + public void removeComponents(String parentId) { + + } + + @Override + public Stream getComponentsStream(String parentId, String providerType) { + return null; + } + + @Override + public Stream getComponentsStream(String parentId) { + return null; + } + + @Override + public Stream getComponentsStream() { + return null; + } + + @Override + public ComponentModel getComponent(String id) { + return null; + } + + @Override + public String getLoginTheme() { + return null; + } + + @Override + public void setLoginTheme(String name) { + + } + + @Override + public String getAccountTheme() { + return null; + } + + @Override + public void setAccountTheme(String name) { + + } + + @Override + public String getAdminTheme() { + return null; + } + + @Override + public void setAdminTheme(String name) { + + } + + @Override + public String getEmailTheme() { + return null; + } + + @Override + public void setEmailTheme(String name) { + + } + + @Override + public int getNotBefore() { + return 0; + } + + @Override + public void setNotBefore(int notBefore) { + + } + + @Override + public boolean isEventsEnabled() { + return false; + } + + @Override + public void setEventsEnabled(boolean enabled) { + + } + + @Override + public long getEventsExpiration() { + return 0; + } + + @Override + public void setEventsExpiration(long expiration) { + + } + + @Override + public Stream getEventsListenersStream() { + return null; + } + + @Override + public void setEventsListeners(Set listeners) { + + } + + @Override + public Stream getEnabledEventTypesStream() { + return null; + } + + @Override + public void setEnabledEventTypes(Set enabledEventTypes) { + + } + + @Override + public boolean isAdminEventsEnabled() { + return false; + } + + @Override + public void setAdminEventsEnabled(boolean enabled) { + + } + + @Override + public boolean isAdminEventsDetailsEnabled() { + return false; + } + + @Override + public void setAdminEventsDetailsEnabled(boolean enabled) { + + } + + @Override + public ClientModel getMasterAdminClient() { + return null; + } + + @Override + public void setMasterAdminClient(ClientModel client) { + + } + + @Override + public RoleModel getDefaultRole() { + return null; + } + + @Override + public void setDefaultRole(RoleModel role) { + + } + + @Override + public boolean isIdentityFederationEnabled() { + return false; + } + + @Override + public boolean isInternationalizationEnabled() { + return false; + } + + @Override + public void setInternationalizationEnabled(boolean enabled) { + + } + + @Override + public Stream getSupportedLocalesStream() { + return null; + } + + @Override + public void setSupportedLocales(Set locales) { + + } + + @Override + public String getDefaultLocale() { + return null; + } + + @Override + public void setDefaultLocale(String locale) { + + } + + @Override + public GroupModel createGroup(String id, String name, GroupModel toParent) { + return null; + } + + @Override + public GroupModel getGroupById(String id) { + return null; + } + + @Override + public Stream getGroupsStream() { + return null; + } + + @Override + public Long getGroupsCount(Boolean onlyTopGroups) { + return null; + } + + @Override + public Long getGroupsCountByNameContaining(String search) { + return null; + } + + @Override + public Stream getTopLevelGroupsStream() { + return null; + } + + @Override + public Stream getTopLevelGroupsStream(Integer first, Integer max) { + return null; + } + + @Override + public Stream searchForGroupByNameStream(String search, Integer first, Integer max) { + return null; + } + + @Override + public boolean removeGroup(GroupModel group) { + return false; + } + + @Override + public void moveGroup(GroupModel group, GroupModel toParent) { + + } + + @Override + public Stream getClientScopesStream() { + return null; + } + + @Override + public ClientScopeModel addClientScope(String name) { + return null; + } + + @Override + public ClientScopeModel addClientScope(String id, String name) { + return null; + } + + @Override + public boolean removeClientScope(String id) { + return false; + } + + @Override + public ClientScopeModel getClientScopeById(String id) { + return null; + } + + @Override + public void addDefaultClientScope(ClientScopeModel clientScope, boolean defaultScope) { + + } + + @Override + public void removeDefaultClientScope(ClientScopeModel clientScope) { + + } + + @Override + public void createOrUpdateRealmLocalizationTexts(String locale, Map localizationTexts) { + + } + + @Override + public boolean removeRealmLocalizationTexts(String locale) { + return false; + } + + @Override + public Map> getRealmLocalizationTexts() { + return null; + } + + @Override + public Map getRealmLocalizationTextsByLocale(String locale) { + return null; + } + + @Override + public Stream getDefaultClientScopesStream(boolean defaultScope) { + return null; + } + + @Override + public ClientInitialAccessModel createClientInitialAccessModel(int expiration, int count) { + return null; + } + + @Override + public ClientInitialAccessModel getClientInitialAccessModel(String id) { + return null; + } + + @Override + public void removeClientInitialAccessModel(String id) { + + } + + @Override + public Stream getClientInitialAccesses() { + return null; + } + + @Override + public void decreaseRemainingCount(ClientInitialAccessModel clientInitialAccess) { + + } + } + +}