KEYCLOAK-18311 fix creation of roles during client registration
This commit is contained in:
parent
1baab67f3b
commit
00017b44a3
3 changed files with 56 additions and 5 deletions
|
@ -20,6 +20,7 @@ package org.keycloak.models;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import org.keycloak.provider.ProviderEvent;
|
import org.keycloak.provider.ProviderEvent;
|
||||||
|
|
||||||
|
@ -98,14 +99,21 @@ public interface RoleContainerModel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Default roles are now managed by {@link org.keycloak.models.RealmModel#getDefaultRole()}. This method will be removed.
|
* @deprecated Default roles are now managed by {@link org.keycloak.models.RealmModel#getDefaultRole()}. This method will be removed.
|
||||||
|
* @return List of default roles names or empty list if there are none. Never returns {@code null}.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
default List<String> getDefaultRoles() {
|
default List<String> getDefaultRoles() {
|
||||||
return getDefaultRolesStream().collect(Collectors.toList());
|
Stream<String> defaultRolesStream = getDefaultRolesStream();
|
||||||
|
if (defaultRolesStream != null) {
|
||||||
|
return defaultRolesStream.collect(Collectors.toList());
|
||||||
|
} else {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Default roles are now managed by {@link org.keycloak.models.RealmModel#getDefaultRole()}. This method will be removed.
|
* @deprecated Default roles are now managed by {@link org.keycloak.models.RealmModel#getDefaultRole()}. This method will be removed.
|
||||||
|
* @return Stream of default roles names or empty stream if there are none. Never returns {@code null}.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
Stream<String> getDefaultRolesStream();
|
Stream<String> getDefaultRolesStream();
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package org.keycloak.services.clientregistration;
|
package org.keycloak.services.clientregistration;
|
||||||
|
|
||||||
|
import java.util.stream.Stream;
|
||||||
import org.keycloak.events.EventBuilder;
|
import org.keycloak.events.EventBuilder;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.ClientInitialAccessModel;
|
import org.keycloak.models.ClientInitialAccessModel;
|
||||||
|
@ -65,6 +66,12 @@ public abstract class AbstractClientRegistrationProvider implements ClientRegist
|
||||||
RealmModel realm = session.getContext().getRealm();
|
RealmModel realm = session.getContext().getRealm();
|
||||||
ClientModel clientModel = ClientManager.createClient(session, realm, client);
|
ClientModel clientModel = ClientManager.createClient(session, realm, client);
|
||||||
|
|
||||||
|
if (client.getDefaultRoles() != null) {
|
||||||
|
for (String name : client.getDefaultRoles()) {
|
||||||
|
clientModel.addDefaultRole(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (clientModel.isServiceAccountsEnabled()) {
|
if (clientModel.isServiceAccountsEnabled()) {
|
||||||
new ClientManager(new RealmManager(session)).enableServiceAccount(clientModel);
|
new ClientManager(new RealmManager(session)).enableServiceAccount(clientModel);
|
||||||
}
|
}
|
||||||
|
@ -90,6 +97,11 @@ public abstract class AbstractClientRegistrationProvider implements ClientRegist
|
||||||
|
|
||||||
client.setDirectAccessGrantsEnabled(false);
|
client.setDirectAccessGrantsEnabled(false);
|
||||||
|
|
||||||
|
Stream<String> defaultRolesNames = clientModel.getDefaultRolesStream();
|
||||||
|
if (defaultRolesNames != null) {
|
||||||
|
client.setDefaultRoles(defaultRolesNames.toArray(String[]::new));
|
||||||
|
}
|
||||||
|
|
||||||
event.client(client.getClientId()).success();
|
event.client(client.getClientId()).success();
|
||||||
return client;
|
return client;
|
||||||
} catch (ModelDuplicateException e) {
|
} catch (ModelDuplicateException e) {
|
||||||
|
@ -114,6 +126,11 @@ public abstract class AbstractClientRegistrationProvider implements ClientRegist
|
||||||
rep.setRegistrationAccessToken(registrationAccessToken);
|
rep.setRegistrationAccessToken(registrationAccessToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Stream<String> defaultRolesNames = client.getDefaultRolesStream();
|
||||||
|
if (defaultRolesNames != null) {
|
||||||
|
rep.setDefaultRoles(defaultRolesNames.toArray(String[]::new));
|
||||||
|
}
|
||||||
|
|
||||||
event.client(client.getClientId()).success();
|
event.client(client.getClientId()).success();
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
@ -133,8 +150,17 @@ public abstract class AbstractClientRegistrationProvider implements ClientRegist
|
||||||
RepresentationToModel.updateClient(rep, client);
|
RepresentationToModel.updateClient(rep, client);
|
||||||
RepresentationToModel.updateClientProtocolMappers(rep, client);
|
RepresentationToModel.updateClientProtocolMappers(rep, client);
|
||||||
|
|
||||||
|
if (rep.getDefaultRoles() != null) {
|
||||||
|
client.updateDefaultRoles(rep.getDefaultRoles());
|
||||||
|
}
|
||||||
|
|
||||||
rep = ModelToRepresentation.toRepresentation(client, session);
|
rep = ModelToRepresentation.toRepresentation(client, session);
|
||||||
|
|
||||||
|
Stream<String> defaultRolesNames = client.getDefaultRolesStream();
|
||||||
|
if (defaultRolesNames != null) {
|
||||||
|
rep.setDefaultRoles(defaultRolesNames.toArray(String[]::new));
|
||||||
|
}
|
||||||
|
|
||||||
if (auth.isRegistrationAccessToken()) {
|
if (auth.isRegistrationAccessToken()) {
|
||||||
String registrationAccessToken = ClientRegistrationTokenUtils.updateRegistrationAccessToken(session, client, auth.getRegistrationAuth());
|
String registrationAccessToken = ClientRegistrationTokenUtils.updateRegistrationAccessToken(session, client, auth.getRegistrationAuth());
|
||||||
rep.setRegistrationAccessToken(registrationAccessToken);
|
rep.setRegistrationAccessToken(registrationAccessToken);
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
package org.keycloak.testsuite.client;
|
package org.keycloak.testsuite.client;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.client.registration.Auth;
|
import org.keycloak.client.registration.Auth;
|
||||||
import org.keycloak.client.registration.ClientRegistration;
|
import org.keycloak.client.registration.ClientRegistration;
|
||||||
|
@ -26,7 +26,6 @@ import org.keycloak.client.registration.HttpErrorException;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper;
|
import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper;
|
||||||
import org.keycloak.representations.idm.ClientRepresentation;
|
import org.keycloak.representations.idm.ClientRepresentation;
|
||||||
import org.keycloak.representations.idm.ClientScopeRepresentation;
|
|
||||||
import org.keycloak.representations.idm.OAuth2ErrorRepresentation;
|
import org.keycloak.representations.idm.OAuth2ErrorRepresentation;
|
||||||
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||||
import org.keycloak.representations.idm.UserRepresentation;
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
|
@ -46,13 +45,13 @@ import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
import static org.hamcrest.core.Is.is;
|
import static org.hamcrest.core.Is.is;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||||
|
@ -90,7 +89,7 @@ public class ClientRegistrationTest extends AbstractClientRegistrationTest {
|
||||||
// Remove this client after test
|
// Remove this client after test
|
||||||
getCleanup().addClientUuid(createdClient.getId());
|
getCleanup().addClientUuid(createdClient.getId());
|
||||||
|
|
||||||
return client;
|
return createdClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -174,6 +173,24 @@ public class ClientRegistrationTest extends AbstractClientRegistrationTest {
|
||||||
assertEquals(name, createdClient.getName());
|
assertEquals(name, createdClient.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clientWithDefaultRoles() throws ClientRegistrationException {
|
||||||
|
authCreateClients();
|
||||||
|
ClientRepresentation client = buildClient();
|
||||||
|
client.setDefaultRoles(new String[]{"test-default-role"});
|
||||||
|
|
||||||
|
ClientRepresentation createdClient = registerClient(client);
|
||||||
|
assertThat(createdClient.getDefaultRoles(), Matchers.arrayContaining("test-default-role"));
|
||||||
|
|
||||||
|
authManageClients();
|
||||||
|
ClientRepresentation obtainedClient = reg.get(CLIENT_ID);
|
||||||
|
assertThat(obtainedClient.getDefaultRoles(), Matchers.arrayContaining("test-default-role"));
|
||||||
|
|
||||||
|
client.setDefaultRoles(new String[]{"test-default-role1","test-default-role2"});
|
||||||
|
ClientRepresentation updatedClient = reg.update(client);
|
||||||
|
assertThat(updatedClient.getDefaultRoles(), Matchers.arrayContainingInAnyOrder("test-default-role1","test-default-role2"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInvalidUrlClientValidation() {
|
public void testInvalidUrlClientValidation() {
|
||||||
testClientUriValidation("Root URL is not a valid URL",
|
testClientUriValidation("Root URL is not a valid URL",
|
||||||
|
|
Loading…
Reference in a new issue