KEYCLOAK-12881 KEYCLOAK-13099 Update FederatedIdentities and Groups on POST

This commit is contained in:
Sebastian Laskawiec 2020-02-26 10:05:07 +01:00 committed by Stian Thorgersen
parent ec1c21efe9
commit 8774a0f4ba
5 changed files with 149 additions and 153 deletions

View file

@ -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) {

View file

@ -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();

View file

@ -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;
}
}

View file

@ -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());
}
}

View file

@ -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;
}