KEYCLOAK-3006 Fix admin event inconsistencies related to roles (points 1,3,4,15,16 from JIRA)

This commit is contained in:
mposolda 2016-05-25 22:39:13 +02:00
parent 022be3aee5
commit 882dbc3f25
17 changed files with 142 additions and 105 deletions

View file

@ -43,6 +43,7 @@ import javax.ws.rs.core.UriInfo;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.Set;
@ -196,12 +197,15 @@ public class ClientRoleMappingsResource {
if (roles == null) {
Set<RoleModel> roleModels = user.getClientRoleMappings(client);
roles = new LinkedList<>();
for (RoleModel roleModel : roleModels) {
if (!(roleModel.getContainer() instanceof ClientModel)) {
if (roleModel.getContainer() instanceof ClientModel) {
ClientModel client = (ClientModel) roleModel.getContainer();
if (!client.getId().equals(this.client.getId())) continue;
}
user.deleteRoleMapping(roleModel);
roles.add(ModelToRepresentation.toRepresentation(roleModel));
}
} else {
@ -220,6 +224,7 @@ public class ClientRoleMappingsResource {
}
}
}
adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).representation(roles).success();
}
}

View file

@ -226,9 +226,7 @@ public class RoleByIdResource extends RoleResource {
auth.requireManage();
RoleModel role = getRoleModel(id);
deleteComposites(roles, role);
adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).representation(roles).success();
deleteComposites(adminEvent, uriInfo, roles, role);
}
}

View file

@ -115,7 +115,8 @@ public class RoleContainerResource extends RoleResource {
boolean scopeParamRequired = rep.isScopeParamRequired()==null ? false : rep.isScopeParamRequired();
role.setScopeParamRequired(scopeParamRequired);
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, role.getId()).representation(rep).success();
rep.setId(role.getId());
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, role.getName()).representation(rep).success();
return Response.created(uriInfo.getAbsolutePathBuilder().path(role.getName()).build()).build();
} catch (ModelDuplicateException e) {
@ -332,8 +333,7 @@ public class RoleContainerResource extends RoleResource {
if (role == null) {
throw new NotFoundException("Could not find role");
}
deleteComposites(roles, role);
adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
deleteComposites(adminEvent, uriInfo, roles, role);
}
}

View file

@ -50,6 +50,7 @@ import javax.ws.rs.core.UriInfo;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@ -236,8 +237,9 @@ public class RoleMapperResource {
throw new NotFoundException("Role not found");
}
roleMapper.grantRole(roleModel);
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, role.getId()).representation(roles).success();
}
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(roles).success();
}
/**
@ -258,10 +260,13 @@ public class RoleMapperResource {
logger.debug("deleteRealmRoleMappings");
if (roles == null) {
Set<RoleModel> roleModels = roleMapper.getRealmRoleMappings();
roles = new LinkedList<>();
for (RoleModel roleModel : roleModels) {
roleMapper.deleteRoleMapping(roleModel);
roles.add(ModelToRepresentation.toRepresentation(roleModel));
}
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(roles).success();
} else {
for (RoleRepresentation role : roles) {
RoleModel roleModel = realm.getRole(role.getName());
@ -276,11 +281,12 @@ public class RoleMapperResource {
throw new ErrorResponseException(me.getMessage(), MessageFormat.format(messages.getProperty(me.getMessage(), me.getMessage()), me.getParameters()),
Response.Status.BAD_REQUEST);
}
adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo, role.getId()).representation(roles).success();
}
}
adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).representation(roles).success();
}
@Path("clients/{client}")

View file

@ -65,9 +65,9 @@ public abstract class RoleResource {
throw new NotFoundException("Could not find composite role");
}
role.addCompositeRole(composite);
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, rep.getId()).representation(roles).success();
}
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo).representation(roles).success();
}
protected Set<RoleRepresentation> getRoleComposites(RoleModel role) {
@ -102,7 +102,7 @@ public abstract class RoleResource {
return composites;
}
protected void deleteComposites(List<RoleRepresentation> roles, RoleModel role) {
protected void deleteComposites(AdminEventBuilder adminEvent, UriInfo uriInfo, List<RoleRepresentation> roles, RoleModel role) {
for (RoleRepresentation rep : roles) {
RoleModel composite = realm.getRoleById(rep.getId());
if (composite == null) {
@ -110,5 +110,7 @@ public abstract class RoleResource {
}
role.removeCompositeRole(composite);
}
adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).representation(roles).success();
}
}

View file

@ -38,6 +38,7 @@ import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
@ -151,8 +152,9 @@ public class ScopeMappedClientResource {
throw new NotFoundException("Role not found");
}
scopeContainer.addScopeMapping(roleModel);
adminEvent.operation(OperationType.CREATE).resourcePath(session.getContext().getUri(), roleModel.getId()).representation(roles).success();
}
adminEvent.operation(OperationType.CREATE).resourcePath(session.getContext().getUri()).representation(roles).success();
}
/**
@ -171,10 +173,13 @@ public class ScopeMappedClientResource {
if (roles == null) {
Set<RoleModel> roleModels = KeycloakModelUtils.getClientScopeMappings(scopedClient, scopeContainer);//scopedClient.getClientScopeMappings(client);
roles = new LinkedList<>();
for (RoleModel roleModel : roleModels) {
scopeContainer.deleteScopeMapping(roleModel);
roles.add(ModelToRepresentation.toRepresentation(roleModel));
}
adminEvent.operation(OperationType.DELETE).resourcePath(session.getContext().getUri()).representation(roles).success();
} else {
for (RoleRepresentation role : roles) {
RoleModel roleModel = scopedClient.getRole(role.getName());
@ -182,8 +187,9 @@ public class ScopeMappedClientResource {
throw new NotFoundException("Role not found");
}
scopeContainer.deleteScopeMapping(roleModel);
adminEvent.operation(OperationType.DELETE).resourcePath(session.getContext().getUri(), roleModel.getId()).representation(roles).success();
}
}
adminEvent.operation(OperationType.DELETE).resourcePath(session.getContext().getUri()).representation(roles).success();
}
}

View file

@ -42,6 +42,7 @@ import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -220,8 +221,9 @@ public class ScopeMappedResource {
throw new NotFoundException("Role not found");
}
scopeContainer.addScopeMapping(roleModel);
adminEvent.operation(OperationType.CREATE).resourcePath(session.getContext().getUri(), role.getId()).representation(roles).success();
}
adminEvent.operation(OperationType.CREATE).resourcePath(session.getContext().getUri()).representation(roles).success();
}
/**
@ -241,10 +243,13 @@ public class ScopeMappedResource {
if (roles == null) {
Set<RoleModel> roleModels = scopeContainer.getRealmScopeMappings();
roles = new LinkedList<>();
for (RoleModel roleModel : roleModels) {
scopeContainer.deleteScopeMapping(roleModel);
roles.add(ModelToRepresentation.toRepresentation(roleModel));
}
adminEvent.operation(OperationType.DELETE).resourcePath(session.getContext().getUri()).representation(roles).success();
} else {
for (RoleRepresentation role : roles) {
RoleModel roleModel = realm.getRoleById(role.getId());
@ -252,10 +257,11 @@ public class ScopeMappedResource {
throw new NotFoundException("Client not found");
}
scopeContainer.deleteScopeMapping(roleModel);
adminEvent.operation(OperationType.DELETE).resourcePath(session.getContext().getUri(), roleModel.getId()).representation(roles).success();
}
}
adminEvent.operation(OperationType.DELETE).resourcePath(session.getContext().getUri()).representation(roles).success();
}
@Path("clients/{client}")

View file

@ -17,7 +17,6 @@
package org.keycloak.testsuite.admin;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.resource.ClientResource;
@ -43,10 +42,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.keycloak.services.resources.admin.ScopeMappedResource;
import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.util.AdminEventPaths;
import org.keycloak.testsuite.util.AssertAdminEvents;
import org.keycloak.testsuite.util.ClientBuilder;
import org.keycloak.testsuite.util.CredentialBuilder;
import org.keycloak.testsuite.util.OAuthClient;
@ -154,7 +151,7 @@ public class ClientTest extends AbstractAdminTest {
RoleRepresentation role = new RoleRepresentation("test", "test", false);
realm.clients().get(id).roles().create(role);
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, Matchers.startsWith(AdminEventPaths.clientRolesResourcePath(id)), role);
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(id, "test"), role);
ClientRepresentation foundClientRep = realm.clients().get(id).toRepresentation();
foundClientRep.setDefaultRoles(new String[]{"test"});
@ -327,28 +324,24 @@ public class ClientTest extends AbstractAdminTest {
realm.roles().create(roleRep1);
realm.roles().create(roleRep2);
AssertAdminEvents.ExpectedAdminEvent adminEvent = assertAdminEvents.expect()
.realmId(realmId)
.operationType(OperationType.CREATE)
.resourcePath(Matchers.startsWith(AdminEventPaths.rolesResourcePath()));
adminEvent.representation(roleRep1).assertEvent();
adminEvent.representation(roleRep2).assertEvent();
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role1"), roleRep1);
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role2"), roleRep2);
roleRep1 = realm.roles().get("role1").toRepresentation();
roleRep2 = realm.roles().get("role2").toRepresentation();
realm.roles().get("role1").addComposites(Collections.singletonList(roleRep2));
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, Matchers.startsWith(AdminEventPaths.roleResourceCompositesPath("role1")));
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourceCompositesPath("role1"), Collections.singletonList(roleRep2));
String accountMgmtId = realm.clients().findByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).get(0).getId();
RoleRepresentation viewAccountRoleRep = realm.clients().get(accountMgmtId).roles().get(AccountRoles.VIEW_PROFILE).toRepresentation();
scopesResource.realmLevel().add(Collections.singletonList(roleRep1));
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientScopeMappingsRealmLevelPath(id) + "/" + roleRep1.getId());
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientScopeMappingsRealmLevelPath(id), Collections.singletonList(roleRep1));
scopesResource.clientLevel(accountMgmtId).add(Collections.singletonList(viewAccountRoleRep));
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientScopeMappingsClientLevelPath(id, accountMgmtId) + "/" + viewAccountRoleRep.getId());
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientScopeMappingsClientLevelPath(id, accountMgmtId), Collections.singletonList(viewAccountRoleRep));
Assert.assertNames(scopesResource.realmLevel().listAll(), "role1");
Assert.assertNames(scopesResource.realmLevel().listEffective(), "role1", "role2");
@ -362,10 +355,10 @@ public class ClientTest extends AbstractAdminTest {
Assert.assertNames(scopesResource.getAll().getClientMappings().get(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID).getMappings(), AccountRoles.VIEW_PROFILE);
scopesResource.realmLevel().remove(Collections.singletonList(roleRep1));
assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientScopeMappingsRealmLevelPath(id) + "/" + roleRep1.getId());
assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientScopeMappingsRealmLevelPath(id), Collections.singletonList(roleRep1));
scopesResource.clientLevel(accountMgmtId).remove(Collections.singletonList(viewAccountRoleRep));
assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientScopeMappingsClientLevelPath(id, accountMgmtId) + "/" + viewAccountRoleRep.getId());
assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.clientScopeMappingsClientLevelPath(id, accountMgmtId), Collections.singletonList(viewAccountRoleRep));
Assert.assertNames(scopesResource.realmLevel().listAll());
Assert.assertNames(scopesResource.realmLevel().listEffective());

View file

@ -17,7 +17,6 @@
package org.keycloak.testsuite.admin;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.admin.client.resource.RoleByIdResource;
@ -120,9 +119,7 @@ public class RoleByIdResourceTest extends AbstractAdminTest {
l.add(RoleBuilder.create().id(ids.get("role-c")).build());
resource.addComposites(ids.get("role-a"), l);
// TODO adminEvents: Fix once composite roles events will be fixed...
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, Matchers.startsWith(AdminEventPaths.roleByIdResourceCompositesPath(ids.get("role-a"))));
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, Matchers.startsWith(AdminEventPaths.roleByIdResourceCompositesPath(ids.get("role-a"))));
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleByIdResourceCompositesPath(ids.get("role-a")), l);
Set<RoleRepresentation> composites = resource.getRoleComposites(ids.get("role-a"));
@ -136,7 +133,7 @@ public class RoleByIdResourceTest extends AbstractAdminTest {
Assert.assertNames(clientComposites, "role-c");
resource.deleteComposites(ids.get("role-a"), l);
assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleByIdResourceCompositesPath(ids.get("role-a")));
assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleByIdResourceCompositesPath(ids.get("role-a")), l);
assertFalse(resource.getRole(ids.get("role-a")).isComposite());
assertEquals(0, resource.getRoleComposites(ids.get("role-a")).size());

View file

@ -796,14 +796,16 @@ public class UserTest extends AbstractAdminTest {
l.add(realm.roles().get("realm-role").toRepresentation());
l.add(realm.roles().get("realm-composite").toRepresentation());
roles.realmLevel().add(l);
assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.userRealmRoleMappingsPath(userId)));
assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.userRealmRoleMappingsPath(userId)));
assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userRealmRoleMappingsPath(userId), l);
// Add client roles
roles.clientLevel(clientUuid).add(Collections.singletonList(realm.clients().get(clientUuid).roles().get("client-role").toRepresentation()));
roles.clientLevel(clientUuid).add(Collections.singletonList(realm.clients().get(clientUuid).roles().get("client-composite").toRepresentation()));
assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid)));
assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid)));
List<RoleRepresentation> list = Collections.singletonList(realm.clients().get(clientUuid).roles().get("client-role").toRepresentation());
roles.clientLevel(clientUuid).add(list);
assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid), list);
list = Collections.singletonList(realm.clients().get(clientUuid).roles().get("client-composite").toRepresentation());
roles.clientLevel(clientUuid).add(list);
assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid), list);
// List realm roles
assertNames(roles.realmLevel().listAll(), "realm-role", "realm-composite", "user", "offline_access");
@ -825,16 +827,14 @@ public class UserTest extends AbstractAdminTest {
// Remove realm role
RoleRepresentation realmRoleRep = realm.roles().get("realm-role").toRepresentation();
roles.realmLevel().remove(Collections.singletonList(realmRoleRep));
assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userRealmRoleMappingsPath(userId) + "/" + realmRoleRep.getId());
assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userRealmRoleMappingsPath(userId), Collections.singletonList(realmRoleRep));
assertNames(roles.realmLevel().listAll(), "realm-composite", "user", "offline_access");
// Remove client role
RoleRepresentation clientRoleRep = realm.clients().get(clientUuid).roles().get("client-role").toRepresentation();
roles.clientLevel(clientUuid).remove(Collections.singletonList(clientRoleRep));
// TODO: Inconsistency between event for delete realm role mapping and client role mapping (the latter doesn't have roleRep.getId() in the path)
assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid));
assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.userClientRoleMappingsPath(userId, clientUuid), Collections.singletonList(clientRoleRep));
assertNames(roles.clientLevel(clientUuid).listAll(), "client-composite");
}

View file

@ -17,7 +17,6 @@
package org.keycloak.testsuite.admin.client;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@ -27,7 +26,6 @@ import org.keycloak.events.admin.OperationType;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.util.AdminEventPaths;
import org.keycloak.testsuite.util.RoleBuilder;
import java.util.LinkedList;
import java.util.List;
@ -75,15 +73,17 @@ public class ClientRolesTest extends AbstractClientTest {
@Test
public void testAddRole() {
rolesRsc.create(makeRole("role1"));
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.clientRolesResourcePath(clientDbId)));
RoleRepresentation role1 = makeRole("role1");
rolesRsc.create(role1);
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role1"), role1);
assertTrue(hasRole(rolesRsc, "role1"));
}
@Test
public void testRemoveRole() {
rolesRsc.create(makeRole("role2"));
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.clientRolesResourcePath(clientDbId)));
RoleRepresentation role2 = makeRole("role2");
rolesRsc.create(role2);
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role2"), role2);
rolesRsc.deleteRole("role2");
assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role2"));
@ -93,25 +93,26 @@ public class ClientRolesTest extends AbstractClientTest {
@Test
public void testComposites() {
rolesRsc.create(makeRole("role-a"));
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.clientRolesResourcePath(clientDbId)));
RoleRepresentation roleA = makeRole("role-a");
rolesRsc.create(roleA);
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role-a"), roleA);
assertFalse(rolesRsc.get("role-a").toRepresentation().isComposite());
assertEquals(0, rolesRsc.get("role-a").getRoleComposites().size());
rolesRsc.create(makeRole("role-b"));
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.clientRolesResourcePath(clientDbId)));
RoleRepresentation roleB = makeRole("role-b");
rolesRsc.create(roleB);
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientDbId, "role-b"), roleB);
testRealmResource().roles().create(makeRole("role-c"));
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.rolesResourcePath()));
RoleRepresentation roleC = makeRole("role-c");
testRealmResource().roles().create(roleC);
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.roleResourcePath("role-c"), roleC);
List<RoleRepresentation> l = new LinkedList<>();
l.add(rolesRsc.get("role-b").toRepresentation());
l.add(testRealmResource().roles().get("role-c").toRepresentation());
rolesRsc.get("role-a").addComposites(l);
// TODO adminEvents: Fix once composite roles events will be fixed...
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.clientRoleResourceCompositesPath(clientDbId, "role-a")));
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.clientRoleResourceCompositesPath(clientDbId, "role-a")));
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientRoleResourceCompositesPath(clientDbId, "role-a"), l);
Set<RoleRepresentation> composites = rolesRsc.get("role-a").getRoleComposites();
@ -125,7 +126,7 @@ public class ClientRolesTest extends AbstractClientTest {
Assert.assertNames(clientComposites, "role-b");
rolesRsc.get("role-a").deleteComposites(l);
assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientRoleResourceCompositesPath(clientDbId, "role-a"));
assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientRoleResourceCompositesPath(clientDbId, "role-a"), l);
assertFalse(rolesRsc.get("role-a").toRepresentation().isComposite());
assertEquals(0, rolesRsc.get("role-a").getRoleComposites().size());

View file

@ -26,7 +26,6 @@ import org.junit.Before;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
import org.keycloak.admin.client.resource.ClientTemplateResource;
import org.keycloak.admin.client.resource.ClientTemplatesResource;
import org.keycloak.admin.client.resource.ProtocolMappersResource;
import org.keycloak.events.admin.OperationType;

View file

@ -27,7 +27,6 @@ import javax.ws.rs.BadRequestException;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.core.Response;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.admin.client.resource.ClientTemplatesResource;
@ -162,7 +161,7 @@ public class ClientTemplateTest extends AbstractClientTest {
// Add role2 as composite to role1
testRealmResource().roles().get("role1").addComposites(Collections.singletonList(roleRep2));
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.roleResourceCompositesPath("role1")));
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.roleResourceCompositesPath("role1"), Collections.singletonList(roleRep2));
// create client template
ClientTemplateRepresentation templateRep = new ClientTemplateRepresentation();
@ -176,10 +175,10 @@ public class ClientTemplateTest extends AbstractClientTest {
RoleMappingResource scopesResource = clientTemplates().get(templateId).getScopeMappings();
scopesResource.realmLevel().add(Collections.singletonList(roleRep1));
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId) + "/" + roleRep1.getId());
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep1));
scopesResource.clientLevel(accountMgmtId).add(Collections.singletonList(viewAccountRoleRep));
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsClientLevelPath(templateId, accountMgmtId) + "/" + viewAccountRoleRep.getId());
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsClientLevelPath(templateId, accountMgmtId), Collections.singletonList(viewAccountRoleRep));
// test that scopes are available (also through composite role)
List<RoleRepresentation> allRealm = scopesResource.realmLevel().listAll();
@ -198,10 +197,10 @@ public class ClientTemplateTest extends AbstractClientTest {
// remove scopes
scopesResource.realmLevel().remove(Collections.singletonList(roleRep1));
assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId) + "/" + roleRep1.getId());
assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep1));
scopesResource.clientLevel(accountMgmtId).remove(Collections.singletonList(viewAccountRoleRep));
assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateScopeMappingsClientLevelPath(templateId, accountMgmtId) + "/" + viewAccountRoleRep.getId());
assertAdminEvents.assertEvent(getRealmId(), OperationType.DELETE, AdminEventPaths.clientTemplateScopeMappingsClientLevelPath(templateId, accountMgmtId), Collections.singletonList(viewAccountRoleRep));
// assert scopes are removed
allRealm = scopesResource.realmLevel().listAll();
@ -256,7 +255,7 @@ public class ClientTemplateTest extends AbstractClientTest {
// Add realm role to scopes of clientTemplate
clientTemplates().get(templateId).getScopeMappings().realmLevel().add(Collections.singletonList(roleRep));
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId) + "/" + roleRep.getId());
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.clientTemplateScopeMappingsRealmLevelPath(templateId), Collections.singletonList(roleRep));
List<RoleRepresentation> roleReps = clientTemplates().get(templateId).getScopeMappings().realmLevel().listAll();
Assert.assertEquals(1, roleReps.size());
@ -279,7 +278,7 @@ public class ClientTemplateTest extends AbstractClientTest {
roleRep.setName(roleName);
testRealmResource().roles().create(roleRep);
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, Matchers.startsWith(AdminEventPaths.rolesResourcePath()));
assertAdminEvents.assertEvent(getRealmId(), OperationType.CREATE, AdminEventPaths.roleResourcePath(roleName), roleRep);
return testRealmResource().roles().get(roleName).toRepresentation();
}

View file

@ -23,6 +23,7 @@ import org.junit.Test;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.RoleMappingResource;
import org.keycloak.events.admin.OperationType;
import org.keycloak.models.RoleModel;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.CredentialRepresentation;
@ -109,7 +110,7 @@ public class GroupTest extends AbstractGroupTest {
RoleRepresentation role = new RoleRepresentation();
role.setName("foo-role");
realm.clients().get(client.getId()).roles().create(role);
assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.clientRolesResourcePath(clientUuid)), role);
assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientUuid, "foo-role"), role);
role = realm.clients().get(client.getId()).roles().get("foo-role").toRepresentation();
GroupRepresentation group = new GroupRepresentation();
@ -119,7 +120,7 @@ public class GroupTest extends AbstractGroupTest {
List<RoleRepresentation> list = new LinkedList<>();
list.add(role);
realm.groups().group(group.getId()).roles().clientLevel(client.getId()).add(list);
assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientUuid));
assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientUuid), list);
realm.clients().get(client.getId()).remove();
assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.clientResourcePath(clientUuid));
@ -169,7 +170,7 @@ public class GroupTest extends AbstractGroupTest {
List<RoleRepresentation> roles = new LinkedList<>();
roles.add(topRole);
realm.groups().group(topGroup.getId()).roles().realmLevel().add(roles);
assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.groupRolesRealmRolesPath(topGroup.getId())));
assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(topGroup.getId()), roles);
GroupRepresentation level2Group = new GroupRepresentation();
level2Group.setName("level2");
@ -196,7 +197,7 @@ public class GroupTest extends AbstractGroupTest {
roles.clear();
roles.add(level2Role);
realm.groups().group(level2Group.getId()).roles().realmLevel().add(roles);
assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.groupRolesRealmRolesPath(level2Group.getId())));
assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(level2Group.getId()), roles);
GroupRepresentation level3Group = new GroupRepresentation();
level3Group.setName("level3");
@ -209,7 +210,7 @@ public class GroupTest extends AbstractGroupTest {
roles.clear();
roles.add(level3Role);
realm.groups().group(level3Group.getId()).roles().realmLevel().add(roles);
assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.groupRolesRealmRolesPath(level3Group.getId())));
assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(level3Group.getId()), roles);
topGroup = realm.getGroupByPath("/top");
assertEquals(1, topGroup.getRealmRoles().size());
@ -417,14 +418,15 @@ public class GroupTest extends AbstractGroupTest {
l.add(realm.roles().get("realm-role").toRepresentation());
l.add(realm.roles().get("realm-composite").toRepresentation());
roles.realmLevel().add(l);
assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.groupRolesRealmRolesPath(group.getId())));
assertAdminEvents.assertEvent("test", OperationType.CREATE, Matchers.startsWith(AdminEventPaths.groupRolesRealmRolesPath(group.getId())));
assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesRealmRolesPath(group.getId()), l);
// Add client roles
roles.clientLevel(clientId).add(Collections.singletonList(realm.clients().get(clientId).roles().get("client-role").toRepresentation()));
roles.clientLevel(clientId).add(Collections.singletonList(realm.clients().get(clientId).roles().get("client-composite").toRepresentation()));
assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId));
assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId));
RoleRepresentation clientRole = realm.clients().get(clientId).roles().get("client-role").toRepresentation();
RoleRepresentation clientComposite = realm.clients().get(clientId).roles().get("client-composite").toRepresentation();
roles.clientLevel(clientId).add(Collections.singletonList(clientRole));
roles.clientLevel(clientId).add(Collections.singletonList(clientComposite));
assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientRole));
assertAdminEvents.assertEvent("test", OperationType.CREATE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientComposite));
// List realm roles
assertNames(roles.realmLevel().listAll(), "realm-role", "realm-composite");
@ -443,16 +445,15 @@ public class GroupTest extends AbstractGroupTest {
assertNames(all.getClientMappings().get("myclient").getMappings(), "client-role", "client-composite");
// Remove realm role
// TODO adminEvents: DEleting group realmRole mapping has ID in the end. For deleting clientRole not.
RoleRepresentation realmRoleRep = realm.roles().get("realm-role").toRepresentation();
roles.realmLevel().remove(Collections.singletonList(realmRoleRep));
assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupRolesRealmRolesPath(group.getId()) + "/" + realmRoleRep.getId());
assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupRolesRealmRolesPath(group.getId()), Collections.singletonList(realmRoleRep));
assertNames(roles.realmLevel().listAll(), "realm-composite");
// Remove client role
RoleRepresentation clientRoleRep = realm.clients().get(clientId).roles().get("client-role").toRepresentation();
roles.clientLevel(clientId).remove(Collections.singletonList(clientRoleRep));
assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId));
assertAdminEvents.assertEvent("test", OperationType.DELETE, AdminEventPaths.groupRolesClientRolesPath(group.getId(), clientId), Collections.singletonList(clientRoleRep));
assertNames(roles.clientLevel(clientId).listAll(), "client-composite");
}

View file

@ -17,10 +17,8 @@
package org.keycloak.testsuite.admin.realm;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.admin.client.resource.RoleByIdResource;
import org.keycloak.admin.client.resource.RolesResource;
import org.keycloak.events.admin.OperationType;
import org.keycloak.representations.idm.ClientRepresentation;
@ -80,12 +78,11 @@ public class RealmRolesTest extends AbstractAdminTest {
resource = adminClient.realm(REALM_NAME).roles();
// ResourcePath for event for creating role contains roleID instead of roleName (looks like a bug...)
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath(ids.get("role-a")), roleA);
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath(ids.get("role-b")), roleB);
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role-a"), roleA);
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("role-b"), roleB);
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientResourcePath(clientUuid), clientRep);
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientUuid, ids.get("role-c")), roleC);
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.clientRoleResourcePath(clientUuid, "role-c"), roleC);
}
@Test
@ -138,9 +135,8 @@ public class RealmRolesTest extends AbstractAdminTest {
l.add(RoleBuilder.create().id(ids.get("role-b")).build());
l.add(RoleBuilder.create().id(ids.get("role-c")).build());
resource.get("role-a").addComposites(l);
// TODO adminEvents: Fix once composite roles events will be fixed...
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, Matchers.startsWith(AdminEventPaths.roleResourceCompositesPath("role-a")));
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, Matchers.startsWith(AdminEventPaths.roleResourceCompositesPath("role-a")));
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourceCompositesPath("role-a"), l);
Set<RoleRepresentation> composites = resource.get("role-a").getRoleComposites();
@ -154,7 +150,7 @@ public class RealmRolesTest extends AbstractAdminTest {
Assert.assertNames(clientComposites, "role-c");
resource.get("role-a").deleteComposites(l);
assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleResourceCompositesPath("role-a"));
assertAdminEvents.assertEvent(realmId, OperationType.DELETE, AdminEventPaths.roleResourceCompositesPath("role-a"), l);
assertFalse(resource.get("role-a").toRepresentation().isComposite());
assertEquals(0, resource.get("role-a").getRoleComposites().size());

View file

@ -282,7 +282,7 @@ public class RealmTest extends AbstractAdminTest {
public void deleteDefaultRole() {
RoleRepresentation role = new RoleRepresentation("test", "test", false);
realm.roles().create(role);
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, Matchers.startsWith(AdminEventPaths.rolesResourcePath()));
assertAdminEvents.assertEvent(realmId, OperationType.CREATE, AdminEventPaths.roleResourcePath("test"), role);
assertNotNull(realm.roles().get("test").toRepresentation());

View file

@ -17,12 +17,18 @@
package org.keycloak.testsuite.util;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.core.Response;
import com.fasterxml.jackson.core.type.TypeReference;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
@ -37,7 +43,9 @@ import org.keycloak.jose.jws.JWSInputException;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.idm.AdminEventRepresentation;
import org.keycloak.representations.idm.AuthDetailsRepresentation;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.Assert;
import org.keycloak.util.JsonSerialization;
@ -200,16 +208,34 @@ public class AssertAdminEvents implements TestRule {
Assert.assertEquals(expectedAuth.getClientId(), actualAuth.getClientId());
}
// Representation - compare the non-null fields of "expected" representation with the actual representation
// Representation comparison
if (expectedRep != null) {
if (actual.getRepresentation() == null) {
Assert.fail("Expected representation " + expectedRep + " but no representation was available on actual event");
} else {
try {
Object actualRep = JsonSerialization.readValue(actual.getRepresentation(), expectedRep.getClass());
if (expectedRep instanceof Map) {
// Special comparing of representations of type map. All of "expected" must be available on "actual"
if (expectedRep instanceof List) {
// List of roles. All must be available in actual representation
List<RoleRepresentation> expectedRoles = (List<RoleRepresentation>) expectedRep;
List<RoleRepresentation> actualRoles = JsonSerialization.readValue(new ByteArrayInputStream(actual.getRepresentation().getBytes()), new TypeReference<List<RoleRepresentation>>() {
});
Map<String, String> expectedRolesMap = new HashMap<>();
for (RoleRepresentation role : expectedRoles) {
expectedRolesMap.put(role.getId(), role.getName());
}
Map<String, String> actualRolesMap = new HashMap<>();
for (RoleRepresentation role : actualRoles) {
actualRolesMap.put(role.getId(), role.getName());
}
Assert.assertEquals(expectedRolesMap, actualRolesMap);
} else if (expectedRep instanceof Map) {
Object actualRep = JsonSerialization.readValue(actual.getRepresentation(), Map.class);
// Comparing of map representations. All of "expected" key-values must be available on "actual" map from the event
Map<?, ?> expectedRepMap = (Map) expectedRep;
Map<?, ?> actualRepMap = (Map) actualRep;
@ -221,7 +247,9 @@ public class AssertAdminEvents implements TestRule {
}
}
} else {
// Reflection-baseed comparing for other types
Object actualRep = JsonSerialization.readValue(actual.getRepresentation(), expectedRep.getClass());
// Reflection-based comparing for other types - compare the non-null fields of "expected" representation with the "actual" representation from the event
for (Method method : Reflections.getAllDeclaredMethods(expectedRep.getClass())) {
if (method.getName().startsWith("get") || method.getName().startsWith("is")) {
Object expectedValue = Reflections.invokeMethod(method, expectedRep);