KEYCLOAK-12881 KEYCLOAK-13099 Update FederatedIdentities and Groups on POST
This commit is contained in:
parent
ec1c21efe9
commit
8774a0f4ba
5 changed files with 149 additions and 153 deletions
|
@ -1745,12 +1745,7 @@ public class RepresentationToModel {
|
|||
}
|
||||
}
|
||||
createCredentials(userRep, session, newRealm, user, false);
|
||||
if (userRep.getFederatedIdentities() != null) {
|
||||
for (FederatedIdentityRepresentation identity : userRep.getFederatedIdentities()) {
|
||||
FederatedIdentityModel mappingModel = new FederatedIdentityModel(identity.getIdentityProvider(), identity.getUserId(), identity.getUserName());
|
||||
session.users().addFederatedIdentity(newRealm, user, mappingModel);
|
||||
}
|
||||
}
|
||||
createFederatedIdentities(userRep, session, newRealm, user);
|
||||
createRoleMappings(userRep, user, newRealm);
|
||||
if (userRep.getClientConsents() != null) {
|
||||
for (UserConsentRepresentation consentRep : userRep.getClientConsents()) {
|
||||
|
@ -1770,8 +1765,12 @@ public class RepresentationToModel {
|
|||
throw new RuntimeException("Unable to find client specified for service account link. Client: " + clientId);
|
||||
}
|
||||
user.setServiceAccountClientLink(client.getId());
|
||||
;
|
||||
}
|
||||
createGroups(userRep, newRealm, user);
|
||||
return user;
|
||||
}
|
||||
|
||||
public static void createGroups(UserRepresentation userRep, RealmModel newRealm, UserModel user) {
|
||||
if (userRep.getGroups() != null) {
|
||||
for (String path : userRep.getGroups()) {
|
||||
GroupModel group = KeycloakModelUtils.findGroupByPath(newRealm, path);
|
||||
|
@ -1782,7 +1781,15 @@ public class RepresentationToModel {
|
|||
user.joinGroup(group);
|
||||
}
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
public static void createFederatedIdentities(UserRepresentation userRep, KeycloakSession session, RealmModel realm, UserModel user) {
|
||||
if (userRep.getFederatedIdentities() != null) {
|
||||
for (FederatedIdentityRepresentation identity : userRep.getFederatedIdentities()) {
|
||||
FederatedIdentityModel mappingModel = new FederatedIdentityModel(identity.getIdentityProvider(), identity.getUserId(), identity.getUserName());
|
||||
session.users().addFederatedIdentity(realm, user, mappingModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void createCredentials(UserRepresentation userRep, KeycloakSession session, RealmModel realm, UserModel user, boolean adminRequest) {
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.keycloak.common.util.ObjectUtil;
|
|||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.events.admin.ResourceType;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.FederatedIdentityModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ModelDuplicateException;
|
||||
import org.keycloak.models.ModelException;
|
||||
|
@ -33,6 +34,7 @@ import org.keycloak.models.UserModel;
|
|||
import org.keycloak.models.utils.ModelToRepresentation;
|
||||
import org.keycloak.models.utils.RepresentationToModel;
|
||||
import org.keycloak.policy.PasswordPolicyNotMetException;
|
||||
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.services.ErrorResponse;
|
||||
import org.keycloak.services.ForbiddenException;
|
||||
|
@ -128,6 +130,9 @@ public class UsersResource {
|
|||
Set<String> emptySet = Collections.emptySet();
|
||||
|
||||
UserResource.updateUserFromRep(user, rep, emptySet, realm, session, false);
|
||||
RepresentationToModel.createFederatedIdentities(rep, session, realm, user);
|
||||
RepresentationToModel.createGroups(rep, realm, user);
|
||||
|
||||
RepresentationToModel.createCredentials(rep, session, realm, user, true);
|
||||
adminEvent.operation(OperationType.CREATE).resourcePath(session.getContext().getUri(), user.getId()).representation(rep).success();
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.hamcrest.Matchers;
|
|||
import org.jboss.arquillian.drone.api.annotation.Drone;
|
||||
import org.jboss.arquillian.graphene.page.Page;
|
||||
import org.jboss.arquillian.test.api.ArquillianResource;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
@ -138,6 +139,15 @@ public class UserTest extends AbstractAdminTest {
|
|||
@Page
|
||||
protected LoginPage loginPage;
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
realm.identityProviders().findAll().stream()
|
||||
.forEach(ip -> realm.identityProviders().get(ip.getAlias()).remove());
|
||||
|
||||
realm.groups().groups().stream()
|
||||
.forEach(g -> realm.groups().group(g.getId()).remove());
|
||||
}
|
||||
|
||||
public String createUser() {
|
||||
return createUser("user1", "user1@localhost");
|
||||
}
|
||||
|
@ -1951,7 +1961,6 @@ public class UserTest extends AbstractAdminTest {
|
|||
|
||||
@Test
|
||||
public void testGetGroupsForUserFullRepresentation() {
|
||||
|
||||
RealmResource realm = adminClient.realms().realm("test");
|
||||
|
||||
String userName = "averagejoe";
|
||||
|
@ -1977,4 +1986,109 @@ public class UserTest extends AbstractAdminTest {
|
|||
assertTrue(userGroups.get(0).getAttributes().containsKey("attribute1"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void groupMembershipPaginated() {
|
||||
String userId = createUser(UserBuilder.create().username("user-a").build());
|
||||
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
GroupRepresentation group = new GroupRepresentation();
|
||||
group.setName("group-" + i);
|
||||
String groupId = createGroup(realm, group).getId();
|
||||
realm.users().get(userId).joinGroup(groupId);
|
||||
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userGroupPath(userId, groupId), group, ResourceType.GROUP_MEMBERSHIP);
|
||||
}
|
||||
|
||||
List<GroupRepresentation> groups = realm.users().get(userId).groups(5, 6);
|
||||
assertEquals(groups.size(), 5);
|
||||
assertNames(groups, "group-5","group-6","group-7","group-8","group-9");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void groupMembershipSearch() {
|
||||
String userId = createUser(UserBuilder.create().username("user-b").build());
|
||||
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
GroupRepresentation group = new GroupRepresentation();
|
||||
group.setName("group-" + i);
|
||||
String groupId = createGroup(realm, group).getId();
|
||||
realm.users().get(userId).joinGroup(groupId);
|
||||
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userGroupPath(userId, groupId), group, ResourceType.GROUP_MEMBERSHIP);
|
||||
}
|
||||
|
||||
List<GroupRepresentation> groups = realm.users().get(userId).groups("-3", 0, 10);
|
||||
assertEquals(1, groups.size());
|
||||
assertNames(groups, "group-3");
|
||||
|
||||
List<GroupRepresentation> groups2 = realm.users().get(userId).groups("1", 0, 10);
|
||||
assertEquals(2, groups2.size());
|
||||
assertNames(groups2, "group-1", "group-10");
|
||||
|
||||
List<GroupRepresentation> groups3 = realm.users().get(userId).groups("1", 2, 10);
|
||||
assertEquals(0, groups3.size());
|
||||
|
||||
List<GroupRepresentation> groups4 = realm.users().get(userId).groups("gr", 2, 10);
|
||||
assertEquals(8, groups4.size());
|
||||
|
||||
List<GroupRepresentation> groups5 = realm.users().get(userId).groups("Gr", 2, 10);
|
||||
assertEquals(8, groups5.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createFederatedIdentities() {
|
||||
String identityProviderAlias = "social-provider-id";
|
||||
String username = "federated-identities";
|
||||
String federatedUserId = "federated-user-id";
|
||||
|
||||
addSampleIdentityProvider();
|
||||
|
||||
UserRepresentation build = UserBuilder.create()
|
||||
.username(username)
|
||||
.federatedLink(identityProviderAlias, federatedUserId)
|
||||
.build();
|
||||
|
||||
//when
|
||||
String userId = createUser(build, false);
|
||||
List<FederatedIdentityRepresentation> obtainedFederatedIdentities = realm.users().get(userId).getFederatedIdentity();
|
||||
|
||||
//then
|
||||
assertEquals(1, obtainedFederatedIdentities.size());
|
||||
assertEquals(federatedUserId, obtainedFederatedIdentities.get(0).getUserId());
|
||||
assertEquals(username, obtainedFederatedIdentities.get(0).getUserName());
|
||||
assertEquals(identityProviderAlias, obtainedFederatedIdentities.get(0).getIdentityProvider());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createUserWithGroups() {
|
||||
String username = "user-with-groups";
|
||||
String groupToBeAdded = "test-group";
|
||||
|
||||
createGroup(realm, GroupBuilder.create().name(groupToBeAdded).build());
|
||||
|
||||
UserRepresentation build = UserBuilder.create()
|
||||
.username(username)
|
||||
.addGroups(groupToBeAdded)
|
||||
.build();
|
||||
|
||||
//when
|
||||
String userId = createUser(build);
|
||||
List<GroupRepresentation> obtainedGroups = realm.users().get(userId).groups();
|
||||
|
||||
//then
|
||||
assertEquals(1, obtainedGroups.size());
|
||||
assertEquals(groupToBeAdded, obtainedGroups.get(0).getName());
|
||||
}
|
||||
|
||||
private GroupRepresentation createGroup(RealmResource realm, GroupRepresentation group) {
|
||||
Response response = realm.groups().add(group);
|
||||
String groupId = ApiUtil.getCreatedId(response);
|
||||
getCleanup().addGroupId(groupId);
|
||||
response.close();
|
||||
|
||||
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.groupPath(groupId), group, ResourceType.GROUP);
|
||||
|
||||
// Set ID to the original rep
|
||||
group.setId(groupId);
|
||||
return group;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,144 +0,0 @@
|
|||
/*
|
||||
* Copyright 2018 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.testsuite.admin.user;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.events.admin.ResourceType;
|
||||
import org.keycloak.representations.idm.GroupRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.testsuite.admin.AbstractAdminTest;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.util.AdminEventPaths;
|
||||
import org.keycloak.testsuite.util.UserBuilder;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.keycloak.testsuite.Assert.assertNames;
|
||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:volker.suschke@bosch-si.com">Volker Suschke</a>
|
||||
* @author <a href="mailto:leon.graser@bosch-si.com">Leon Graser</a>
|
||||
*/
|
||||
@AuthServerContainerExclude(AuthServer.REMOTE)
|
||||
public class UserGroupMembershipTest extends AbstractAdminTest {
|
||||
|
||||
public String createUser() {
|
||||
return createUser("user1", "user1@localhost");
|
||||
}
|
||||
|
||||
public String createUser(String username, String email) {
|
||||
UserRepresentation user = new UserRepresentation();
|
||||
user.setUsername(username);
|
||||
user.setEmail(email);
|
||||
user.setRequiredActions(Collections.emptyList());
|
||||
user.setEnabled(true);
|
||||
|
||||
return createUser(user);
|
||||
}
|
||||
|
||||
private String createUser(UserRepresentation userRep) {
|
||||
Response response = realm.users().create(userRep);
|
||||
String createdId = ApiUtil.getCreatedId(response);
|
||||
response.close();
|
||||
|
||||
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userResourcePath(createdId), userRep, ResourceType.USER);
|
||||
|
||||
getCleanup().addUserId(createdId);
|
||||
|
||||
return createdId;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyCreateUser() {
|
||||
createUser();
|
||||
}
|
||||
|
||||
private GroupRepresentation createGroup(RealmResource realm, GroupRepresentation group) {
|
||||
Response response = realm.groups().add(group);
|
||||
String groupId = ApiUtil.getCreatedId(response);
|
||||
getCleanup().addGroupId(groupId);
|
||||
response.close();
|
||||
|
||||
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.groupPath(groupId), group, ResourceType.GROUP);
|
||||
|
||||
// Set ID to the original rep
|
||||
group.setId(groupId);
|
||||
return group;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void groupMembershipPaginated() {
|
||||
Response response = realm.users().create(UserBuilder.create().username("user-a").build());
|
||||
String userId = ApiUtil.getCreatedId(response);
|
||||
response.close();
|
||||
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userResourcePath(userId), ResourceType.USER);
|
||||
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
GroupRepresentation group = new GroupRepresentation();
|
||||
group.setName("group-" + i);
|
||||
String groupId = createGroup(realm, group).getId();
|
||||
realm.users().get(userId).joinGroup(groupId);
|
||||
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userGroupPath(userId, groupId), group, ResourceType.GROUP_MEMBERSHIP);
|
||||
}
|
||||
|
||||
List<GroupRepresentation> groups = realm.users().get(userId).groups(5, 6);
|
||||
assertEquals(groups.size(), 5);
|
||||
assertNames(groups, "group-5","group-6","group-7","group-8","group-9");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void groupMembershipSearch() {
|
||||
Response response = realm.users().create(UserBuilder.create().username("user-b").build());
|
||||
String userId = ApiUtil.getCreatedId(response);
|
||||
response.close();
|
||||
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userResourcePath(userId), ResourceType.USER);
|
||||
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
GroupRepresentation group = new GroupRepresentation();
|
||||
group.setName("group-" + i);
|
||||
String groupId = createGroup(realm, group).getId();
|
||||
realm.users().get(userId).joinGroup(groupId);
|
||||
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.userGroupPath(userId, groupId), group, ResourceType.GROUP_MEMBERSHIP);
|
||||
}
|
||||
|
||||
List<GroupRepresentation> groups = realm.users().get(userId).groups("-3", 0, 10);
|
||||
assertEquals(1, groups.size());
|
||||
assertNames(groups, "group-3");
|
||||
|
||||
List<GroupRepresentation> groups2 = realm.users().get(userId).groups("1", 0, 10);
|
||||
assertEquals(2, groups2.size());
|
||||
assertNames(groups2, "group-1", "group-10");
|
||||
|
||||
List<GroupRepresentation> groups3 = realm.users().get(userId).groups("1", 2, 10);
|
||||
assertEquals(0, groups3.size());
|
||||
|
||||
List<GroupRepresentation> groups4 = realm.users().get(userId).groups("gr", 2, 10);
|
||||
assertEquals(8, groups4.size());
|
||||
|
||||
List<GroupRepresentation> groups5 = realm.users().get(userId).groups("Gr", 2, 10);
|
||||
assertEquals(8, groups5.size());
|
||||
}
|
||||
|
||||
}
|
|
@ -26,6 +26,7 @@ import org.keycloak.models.credential.OTPCredentialModel;
|
|||
import org.keycloak.models.utils.HmacOTP;
|
||||
import org.keycloak.models.utils.ModelToRepresentation;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
|
||||
/**
|
||||
|
@ -179,6 +180,19 @@ public class UserBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public UserBuilder federatedLink(String identityProvider, String federatedUserId) {
|
||||
if (rep.getFederatedIdentities() == null) {
|
||||
rep.setFederatedIdentities(new LinkedList<>());
|
||||
}
|
||||
FederatedIdentityRepresentation federatedIdentity = new FederatedIdentityRepresentation();
|
||||
federatedIdentity.setUserId(federatedUserId);
|
||||
federatedIdentity.setUserName(rep.getUsername());
|
||||
federatedIdentity.setIdentityProvider(identityProvider);
|
||||
|
||||
rep.getFederatedIdentities().add(federatedIdentity);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UserRepresentation build() {
|
||||
return rep;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue