diff --git a/core/src/main/java/org/keycloak/representations/idm/PartialImportRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/PartialImportRepresentation.java index fab1f56ecc..520c1306c9 100644 --- a/core/src/main/java/org/keycloak/representations/idm/PartialImportRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/idm/PartialImportRepresentation.java @@ -30,7 +30,7 @@ public class PartialImportRepresentation { public enum Policy { SKIP, OVERWRITE, FAIL }; protected Policy policy = Policy.FAIL; - protected String ifResourceExists = ""; + protected String ifResourceExists; protected List users; protected List groups; protected List clients; @@ -67,7 +67,7 @@ public class PartialImportRepresentation { public void setIfResourceExists(String ifResourceExists) { this.ifResourceExists = ifResourceExists; - this.policy = Policy.valueOf(ifResourceExists); + this.policy = ifResourceExists != null ? Policy.valueOf(ifResourceExists) : null; } public Policy getPolicy() { diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientAttributeCertificateResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientAttributeCertificateResource.java index 30d3bfb469..5ede9fed90 100644 --- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientAttributeCertificateResource.java +++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientAttributeCertificateResource.java @@ -60,7 +60,6 @@ public interface ClientAttributeCertificateResource { /** * Upload certificate and eventually private key * - * @param uriInfo * @param input * @return */ @@ -68,12 +67,11 @@ public interface ClientAttributeCertificateResource { @Path("upload") @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.APPLICATION_JSON) - public CertificateRepresentation uploadJks(@Context final UriInfo uriInfo, MultipartFormDataInput input); + public CertificateRepresentation uploadJks(MultipartFormDataInput input); /** * Upload only certificate, not private key * - * @param uriInfo * @param input * @return */ @@ -81,7 +79,7 @@ public interface ClientAttributeCertificateResource { @Path("upload-certificate") @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.APPLICATION_JSON) - public CertificateRepresentation uploadJksCertificate(@Context final UriInfo uriInfo, MultipartFormDataInput input); + public CertificateRepresentation uploadJksCertificate(MultipartFormDataInput input); /** * Get a keystore file for the client, containing private key and public certificate diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientResource.java index 644cc7a8e6..b88937c6fa 100755 --- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientResource.java +++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientResource.java @@ -18,8 +18,10 @@ package org.keycloak.admin.client.resource; import org.jboss.resteasy.annotations.cache.NoCache; +import org.keycloak.representations.adapters.action.GlobalRequestResult; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.CredentialRepresentation; +import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; import javax.ws.rs.Consumes; @@ -99,6 +101,16 @@ public interface ClientResource { @Produces(MediaType.APPLICATION_JSON) public List getUserSessions(@QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResults); + @Path("offline-session-count") + @GET + @Produces(MediaType.APPLICATION_JSON) + Map getOfflineSessionCount(); + + @Path("offline-sessions") + @GET + @Produces(MediaType.APPLICATION_JSON) + List getOfflineUserSessions(@QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResults); + @POST @Path("push-revocation") public void pushRevocation(); @@ -109,4 +121,23 @@ public interface ClientResource { @Path("/roles") public RolesResource roles(); + @Path("/service-account-user") + @GET + @NoCache + @Produces(MediaType.APPLICATION_JSON) + UserRepresentation getServiceAccountUser(); + + @Path("nodes") + @POST + @Consumes(MediaType.APPLICATION_JSON) + void registerNode(Map formParams); + + @Path("nodes/{node}") + @DELETE + void unregisterNode(final @PathParam("node") String node); + + @Path("test-nodes-available") + @GET + GlobalRequestResult testNodesAvailable(); + } \ No newline at end of file diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/IdentityProvidersResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/IdentityProvidersResource.java index 2c577b0d98..e7bfb2acae 100755 --- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/IdentityProvidersResource.java +++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/IdentityProvidersResource.java @@ -26,6 +26,7 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import java.util.List; /** @@ -44,5 +45,5 @@ public interface IdentityProvidersResource { @POST @Path("instances") @Consumes(MediaType.APPLICATION_JSON) - void create(IdentityProviderRepresentation identityProvider); + Response create(IdentityProviderRepresentation identityProvider); } diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/UserResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/UserResource.java index df13c0b756..2df2cbfb7a 100755 --- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/UserResource.java +++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/UserResource.java @@ -118,6 +118,10 @@ public interface UserResource { @Path("sessions") public List getUserSessions(); + @GET + @Path("offline-sessions/{clientId}") + List getOfflineSessions(@PathParam("clientId") String clientId); + @GET @Path("federated-identity") public List getFederatedIdentity(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java b/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java index 3a0e5779ef..0a39094e73 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/AuthenticationManagementResource.java @@ -727,7 +727,7 @@ public class AuthenticationManagementResource { @Produces(MediaType.APPLICATION_JSON) @NoCache public List> getUnregisteredRequiredActions() { - auth.requireManage(); + auth.requireView(); List factories = session.getKeycloakSessionFactory().getProviderFactories(RequiredActionProvider.class); List> unregisteredList = new LinkedList<>(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java index 09186f1867..895bd647ab 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientAttributeCertificateResource.java @@ -93,6 +93,10 @@ public class ClientAttributeCertificateResource { public CertificateRepresentation getKeyInfo() { auth.requireView(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + CertificateRepresentation info = new CertificateRepresentation(); info.setCertificate(client.getAttribute(certificateAttribute)); info.setPrivateKey(client.getAttribute(privateAttribute)); @@ -111,6 +115,10 @@ public class ClientAttributeCertificateResource { public CertificateRepresentation generate() { auth.requireManage(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + CertificateRepresentation info = KeycloakModelUtils.generateKeyPairCertificate(client.getClientId()); client.setAttribute(privateAttribute, info.getPrivateKey()); @@ -136,6 +144,10 @@ public class ClientAttributeCertificateResource { public CertificateRepresentation uploadJks(@Context final UriInfo uriInfo, MultipartFormDataInput input) throws IOException { auth.requireManage(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + CertificateRepresentation info = getCertFromRequest(uriInfo, input); if (info.getPrivateKey() != null) { @@ -169,6 +181,10 @@ public class ClientAttributeCertificateResource { public CertificateRepresentation uploadJksCertificate(@Context final UriInfo uriInfo, MultipartFormDataInput input) throws IOException { auth.requireManage(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + CertificateRepresentation info = getCertFromRequest(uriInfo, input); if (info.getCertificate() != null) { @@ -246,6 +262,10 @@ public class ClientAttributeCertificateResource { public byte[] getKeystore(final KeyStoreConfig config) { auth.requireView(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + if (config.getFormat() != null && !config.getFormat().equals("JKS") && !config.getFormat().equals("PKCS12")) { throw new NotAcceptableException("Only support jks or pkcs12 format."); } @@ -283,6 +303,10 @@ public class ClientAttributeCertificateResource { public byte[] generateAndGetKeystore(final KeyStoreConfig config) { auth.requireManage(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + if (config.getFormat() != null && !config.getFormat().equals("JKS") && !config.getFormat().equals("PKCS12")) { throw new NotAcceptableException("Only support jks or pkcs12 format."); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java index 2d83e84ebe..a1978ac7bf 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java @@ -120,6 +120,10 @@ public class ClientResource { public Response update(final ClientRepresentation rep) { auth.requireManage(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + try { updateClientFromRep(rep, client, session); adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success(); @@ -148,6 +152,10 @@ public class ClientResource { public ClientRepresentation getClient() { auth.requireView(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + return ModelToRepresentation.toRepresentation(client); } @@ -168,6 +176,10 @@ public class ClientResource { public Response getInstallationProvider(@PathParam("providerId") String providerId) { auth.requireView(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + ClientInstallationProvider provider = session.getProvider(ClientInstallationProvider.class, providerId); if (provider == null) throw new NotFoundException("Unknown Provider"); return provider.generateInstallation(session, realm, client, keycloak.getBaseUri(uriInfo)); @@ -182,6 +194,10 @@ public class ClientResource { public void deleteClient() { auth.requireManage(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + new ClientManager(new RealmManager(session)).removeClient(realm, client); adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success(); } @@ -199,6 +215,10 @@ public class ClientResource { public CredentialRepresentation regenerateSecret() { auth.requireManage(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + logger.debug("regenerateSecret"); UserCredentialModel cred = KeycloakModelUtils.generateSecret(client); CredentialRepresentation rep = ModelToRepresentation.toRepresentation(cred); @@ -218,6 +238,10 @@ public class ClientResource { public ClientRepresentation regenerateRegistrationAccessToken() { auth.requireManage(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + String token = ClientRegistrationTokenUtils.updateRegistrationAccessToken(realm, uriInfo, client); ClientRepresentation rep = ModelToRepresentation.toRepresentation(client); @@ -239,6 +263,10 @@ public class ClientResource { public CredentialRepresentation getClientSecret() { auth.requireView(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + logger.debug("getClientSecret"); UserCredentialModel model = UserCredentialModel.secret(client.getSecret()); if (model == null) throw new NotFoundException("Client does not have a secret"); @@ -272,6 +300,10 @@ public class ClientResource { public UserRepresentation getServiceAccountUser() { auth.requireView(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + UserModel user = session.users().getUserByServiceAccountClient(client); if (user == null) { if (client.isServiceAccountsEnabled()) { @@ -295,6 +327,10 @@ public class ClientResource { public GlobalRequestResult pushRevocation() { auth.requireManage(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success(); return new ResourceAdminManager(session).pushClientRevocationPolicy(uriInfo.getRequestUri(), realm, client); @@ -318,6 +354,10 @@ public class ClientResource { public Map getApplicationSessionCount() { auth.requireView(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + Map map = new HashMap<>(); map.put("count", session.sessions().getActiveUserSessions(client.getRealm(), client)); return map; @@ -339,6 +379,10 @@ public class ClientResource { public List getUserSessions(@QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResults) { auth.requireView(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + firstResult = firstResult != null ? firstResult : -1; maxResults = maxResults != null ? maxResults : -1; List sessions = new ArrayList(); @@ -367,6 +411,10 @@ public class ClientResource { public Map getOfflineSessionCount() { auth.requireView(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + Map map = new HashMap<>(); map.put("count", session.sessions().getOfflineSessionsCount(client.getRealm(), client)); return map; @@ -388,6 +436,10 @@ public class ClientResource { public List getOfflineUserSessions(@QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResults) { auth.requireView(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + firstResult = firstResult != null ? firstResult : -1; maxResults = maxResults != null ? maxResults : -1; List sessions = new ArrayList(); @@ -422,6 +474,10 @@ public class ClientResource { public void registerNode(Map formParams) { auth.requireManage(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + String node = formParams.get("node"); if (node == null) { throw new BadRequestException("Node not found in params"); @@ -442,6 +498,10 @@ public class ClientResource { public void unregisterNode(final @PathParam("node") String node) { auth.requireManage(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + if (logger.isDebugEnabled()) logger.debug("Unregister node: " + node); Integer time = client.getRegisteredNodes().get(node); @@ -465,6 +525,10 @@ public class ClientResource { public GlobalRequestResult testNodesAvailable() { auth.requireManage(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + logger.debug("Test availability of cluster nodes"); adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success(); return new ResourceAdminManager(session).testNodesAvailability(uriInfo.getRequestUri(), realm, client); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java index 7307d81233..ff0745b195 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientRoleMappingsResource.java @@ -83,6 +83,10 @@ public class ClientRoleMappingsResource { public List getClientRoleMappings() { auth.requireView(); + if (user == null || client == null) { + throw new NotFoundException("Not found"); + } + Set mappings = user.getClientRoleMappings(client); List mapRep = new ArrayList(); for (RoleModel roleModel : mappings) { @@ -105,6 +109,10 @@ public class ClientRoleMappingsResource { public List getCompositeClientRoleMappings() { auth.requireView(); + if (user == null || client == null) { + throw new NotFoundException("Not found"); + } + Set roles = client.getRoles(); List mapRep = new ArrayList(); for (RoleModel roleModel : roles) { @@ -125,6 +133,10 @@ public class ClientRoleMappingsResource { public List getAvailableClientRoleMappings() { auth.requireView(); + if (user == null || client == null) { + throw new NotFoundException("Not found"); + } + Set available = client.getRoles(); return getAvailableRoles(user, available); } @@ -153,6 +165,10 @@ public class ClientRoleMappingsResource { public void addClientRoleMapping(List roles) { auth.requireManage(); + if (user == null || client == null) { + throw new NotFoundException("Not found"); + } + for (RoleRepresentation role : roles) { RoleModel roleModel = client.getRole(role.getName()); if (roleModel == null || !roleModel.getId().equals(role.getId())) { @@ -174,6 +190,10 @@ public class ClientRoleMappingsResource { public void deleteClientRoleMapping(List roles) { auth.requireManage(); + if (user == null || client == null) { + throw new NotFoundException("Not found"); + } + if (roles == null) { Set roleModels = user.getClientRoleMappings(client); for (RoleModel roleModel : roleModels) { diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplateResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplateResource.java index 49580b1fe7..94e2382377 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplateResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplateResource.java @@ -17,6 +17,7 @@ package org.keycloak.services.resources.admin; import org.jboss.resteasy.annotations.cache.NoCache; +import org.jboss.resteasy.spi.NotFoundException; import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.keycloak.events.admin.OperationType; import org.keycloak.models.ClientTemplateModel; @@ -104,6 +105,10 @@ public class ClientTemplateResource { public Response update(final ClientTemplateRepresentation rep) { auth.requireManage(); + if (template == null) { + throw new NotFoundException("Could not find client template"); + } + try { RepresentationToModel.updateClientTemplate(rep, template); adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success(); @@ -125,6 +130,10 @@ public class ClientTemplateResource { public ClientTemplateRepresentation getClient() { auth.requireView(); + if (template == null) { + throw new NotFoundException("Could not find client template"); + } + return ModelToRepresentation.toRepresentation(template); } @@ -137,6 +146,10 @@ public class ClientTemplateResource { public Response deleteClientTemplate() { auth.requireManage(); + if (template == null) { + throw new NotFoundException("Could not find client template"); + } + try { realm.removeClientTemplate(template.getId()); adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplatesResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplatesResource.java index 36e01791a8..6015a3e212 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplatesResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientTemplatesResource.java @@ -130,10 +130,6 @@ public class ClientTemplatesResource { @Path("{id}") public ClientTemplateResource getClient(final @PathParam("id") String id) { ClientTemplateModel clientModel = realm.getClientTemplateById(id); - if (clientModel == null) { - throw new NotFoundException("Could not find client template"); - } - ClientTemplateResource clientResource = new ClientTemplateResource(realm, auth, clientModel, session, adminEvent); ResteasyProviderFactory.getInstance().injectProperties(clientResource); return clientResource; diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java index 981e752a0f..8690862fae 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java @@ -141,9 +141,6 @@ public class ClientsResource { @Path("{id}") public ClientResource getClient(final @PathParam("id") String id) { ClientModel clientModel = realm.getClientById(id); - if (clientModel == null) { - throw new NotFoundException("Could not find client"); - } session.getContext().setClient(clientModel); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java b/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java index 0563112fd9..49b607be6b 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/GroupResource.java @@ -78,6 +78,11 @@ public class GroupResource { @Produces(MediaType.APPLICATION_JSON) public GroupRepresentation getGroup() { this.auth.requireView(); + + if (group == null) { + throw new NotFoundException("Could not find group by id"); + } + return ModelToRepresentation.toGroupHierarchy(group, true); } @@ -90,6 +95,11 @@ public class GroupResource { @Consumes(MediaType.APPLICATION_JSON) public void updateGroup(GroupRepresentation rep) { this.auth.requireManage(); + + if (group == null) { + throw new NotFoundException("Could not find group by id"); + } + updateGroup(rep, group); adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success(); @@ -99,6 +109,11 @@ public class GroupResource { @DELETE public void deleteGroup() { this.auth.requireManage(); + + if (group == null) { + throw new NotFoundException("Could not find group by id"); + } + realm.removeGroup(group); adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success(); } @@ -117,6 +132,11 @@ public class GroupResource { @Consumes(MediaType.APPLICATION_JSON) public Response addChild(GroupRepresentation rep) { this.auth.requireManage(); + + if (group == null) { + throw new NotFoundException("Could not find group by id"); + } + Response.ResponseBuilder builder = Response.status(204); GroupModel child = null; if (rep.getId() != null) { @@ -182,6 +202,11 @@ public class GroupResource { public List getMembers(@QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResults) { auth.requireView(); + + if (group == null) { + throw new NotFoundException("Could not find group by id"); + } + firstResult = firstResult != null ? firstResult : -1; maxResults = maxResults != null ? maxResults : -1; @@ -194,7 +219,4 @@ public class GroupResource { return results; } - - - } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java index 39e3d4ad73..037235d25e 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/GroupsResource.java @@ -85,10 +85,6 @@ public class GroupsResource { auth.requireView(); GroupModel group = realm.getGroupById(id); - if (group == null) { - throw new NotFoundException("Could not find group by id"); - } - GroupResource resource = new GroupResource(realm, group, session, this.auth, adminEvent); ResteasyProviderFactory.getInstance().injectProperties(resource); return resource; diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java index 355413a1ee..a664b75d16 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProviderResource.java @@ -95,6 +95,11 @@ public class IdentityProviderResource { @Produces(MediaType.APPLICATION_JSON) public IdentityProviderRepresentation getIdentityProvider() { this.auth.requireView(); + + if (identityProviderModel == null) { + throw new javax.ws.rs.NotFoundException(); + } + IdentityProviderRepresentation rep = ModelToRepresentation.toRepresentation(realm, this.identityProviderModel); return rep; } @@ -109,6 +114,10 @@ public class IdentityProviderResource { public Response delete() { this.auth.requireManage(); + if (identityProviderModel == null) { + throw new javax.ws.rs.NotFoundException(); + } + this.realm.removeIdentityProviderByAlias(this.identityProviderModel.getAlias()); adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success(); @@ -126,9 +135,13 @@ public class IdentityProviderResource { @Consumes(MediaType.APPLICATION_JSON) @NoCache public Response update(IdentityProviderRepresentation providerRep) { - try { - this.auth.requireManage(); + this.auth.requireManage(); + if (identityProviderModel == null) { + throw new javax.ws.rs.NotFoundException(); + } + + try { updateIdpFromRep(providerRep, realm, session); adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(providerRep).success(); @@ -207,8 +220,13 @@ public class IdentityProviderResource { @Path("export") @NoCache public Response export(@Context UriInfo uriInfo, @QueryParam("format") String format) { + this.auth.requireView(); + + if (identityProviderModel == null) { + throw new javax.ws.rs.NotFoundException(); + } + try { - this.auth.requireView(); IdentityProviderFactory factory = getIdentityProviderFactory(); return factory.create(identityProviderModel).export(uriInfo, realm, format); } catch (Exception e) { @@ -224,6 +242,11 @@ public class IdentityProviderResource { @NoCache public Map getMapperTypes() { this.auth.requireView(); + + if (identityProviderModel == null) { + throw new javax.ws.rs.NotFoundException(); + } + KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory(); Map types = new HashMap<>(); List factories = sessionFactory.getProviderFactories(IdentityProviderMapper.class); @@ -263,6 +286,11 @@ public class IdentityProviderResource { @NoCache public List getMappers() { this.auth.requireView(); + + if (identityProviderModel == null) { + throw new javax.ws.rs.NotFoundException(); + } + List mappers = new LinkedList<>(); for (IdentityProviderMapperModel model : realm.getIdentityProviderMappersByAlias(identityProviderModel.getAlias())) { mappers.add(ModelToRepresentation.toRepresentation(model)); @@ -281,6 +309,11 @@ public class IdentityProviderResource { @Consumes(MediaType.APPLICATION_JSON) public Response addMapper(IdentityProviderMapperRepresentation mapper) { auth.requireManage(); + + if (identityProviderModel == null) { + throw new javax.ws.rs.NotFoundException(); + } + IdentityProviderMapperModel model = RepresentationToModel.toModel(mapper); model = realm.addIdentityProviderMapper(model); @@ -303,6 +336,11 @@ public class IdentityProviderResource { @Produces(MediaType.APPLICATION_JSON) public IdentityProviderMapperRepresentation getMapperById(@PathParam("id") String id) { auth.requireView(); + + if (identityProviderModel == null) { + throw new javax.ws.rs.NotFoundException(); + } + IdentityProviderMapperModel model = realm.getIdentityProviderMapperById(id); if (model == null) throw new NotFoundException("Model not found"); return ModelToRepresentation.toRepresentation(model); @@ -320,6 +358,11 @@ public class IdentityProviderResource { @Consumes(MediaType.APPLICATION_JSON) public void update(@PathParam("id") String id, IdentityProviderMapperRepresentation rep) { auth.requireManage(); + + if (identityProviderModel == null) { + throw new javax.ws.rs.NotFoundException(); + } + IdentityProviderMapperModel model = realm.getIdentityProviderMapperById(id); if (model == null) throw new NotFoundException("Model not found"); model = RepresentationToModel.toModel(rep); @@ -338,6 +381,11 @@ public class IdentityProviderResource { @Path("mappers/{id}") public void delete(@PathParam("id") String id) { auth.requireManage(); + + if (identityProviderModel == null) { + throw new javax.ws.rs.NotFoundException(); + } + IdentityProviderMapperModel model = realm.getIdentityProviderMapperById(id); if (model == null) throw new NotFoundException("Model not found"); realm.removeIdentityProviderMapper(model); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java index 21ad7dcd2b..a6019304ee 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/IdentityProvidersResource.java @@ -205,10 +205,6 @@ public class IdentityProvidersResource { } } - if (identityProviderModel == null) { - throw new NotFoundException("Could not find identity provider"); - } - IdentityProviderResource identityProviderResource = new IdentityProviderResource(this.auth, realm, session, identityProviderModel, adminEvent); ResteasyProviderFactory.getInstance().injectProperties(identityProviderResource); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java index 9e2470b973..bb3d325ea3 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ProtocolMappersResource.java @@ -88,6 +88,10 @@ public class ProtocolMappersResource { public List getMappersPerProtocol(@PathParam("protocol") String protocol) { auth.requireAny(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + List mappers = new LinkedList(); for (ProtocolMapperModel mapper : client.getProtocolMappers()) { if (mapper.getProtocol().equals(protocol)) mappers.add(ModelToRepresentation.toRepresentation(mapper)); @@ -107,6 +111,10 @@ public class ProtocolMappersResource { public Response createMapper(ProtocolMapperRepresentation rep) { auth.requireManage(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + ProtocolMapperModel model = null; try { model = RepresentationToModel.toModel(rep); @@ -130,6 +138,10 @@ public class ProtocolMappersResource { public void createMapper(List reps) { auth.requireManage(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + ProtocolMapperModel model = null; for (ProtocolMapperRepresentation rep : reps) { model = RepresentationToModel.toModel(rep); @@ -150,6 +162,10 @@ public class ProtocolMappersResource { public List getMappers() { auth.requireAny(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + List mappers = new LinkedList(); for (ProtocolMapperModel mapper : client.getProtocolMappers()) { mappers.add(ModelToRepresentation.toRepresentation(mapper)); @@ -170,6 +186,10 @@ public class ProtocolMappersResource { public ProtocolMapperRepresentation getMapperById(@PathParam("id") String id) { auth.requireAny(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + ProtocolMapperModel model = client.getProtocolMapperById(id); if (model == null) throw new NotFoundException("Model not found"); return ModelToRepresentation.toRepresentation(model); @@ -188,6 +208,10 @@ public class ProtocolMappersResource { public void update(@PathParam("id") String id, ProtocolMapperRepresentation rep) { auth.requireManage(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + ProtocolMapperModel model = client.getProtocolMapperById(id); if (model == null) throw new NotFoundException("Model not found"); model = RepresentationToModel.toModel(rep); @@ -206,6 +230,10 @@ public class ProtocolMappersResource { public void delete(@PathParam("id") String id) { auth.requireManage(); + if (client == null) { + throw new NotFoundException("Could not find client"); + } + ProtocolMapperModel model = client.getProtocolMapperById(id); if (model == null) throw new NotFoundException("Model not found"); client.removeProtocolMapper(model); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java index 67bd7a3f23..24f3dc3252 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmAdminResource.java @@ -142,7 +142,11 @@ public class RealmAdminResource { @POST @Produces(MediaType.APPLICATION_JSON) public ClientRepresentation convertClientDescription(String description) { - auth.requireManage(); + auth.init(Resource.CLIENT).requireManage(); + + if (realm == null) { + throw new NotFoundException("Realm not found."); + } for (ProviderFactory factory : session.getKeycloakSessionFactory().getProviderFactories(ClientDescriptionConverter.class)) { if (((ClientDescriptionConverterFactory) factory).isSupported(description)) { diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java index 939e61636d..c6407c715a 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RealmsAdminResource.java @@ -110,7 +110,11 @@ public class RealmsAdminResource { } protected void addRealmRep(List reps, RealmModel realm, ClientModel realmManagementClient) { - if (auth.hasAppRole(realmManagementClient, AdminRoles.MANAGE_REALM)) { + if (!auth.hasOneOfAppRole(realmManagementClient, AdminRoles.ALL_REALM_ROLES)) { + throw new ForbiddenException(); + } + + if (auth.hasAppRole(realmManagementClient, AdminRoles.VIEW_REALM)) { reps.add(ModelToRepresentation.toRepresentation(realm, false)); } else if (auth.hasOneOfAppRole(realmManagementClient, AdminRoles.ALL_REALM_ROLES)) { RealmRepresentation rep = new RealmRepresentation(); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java index 39e88dc4a1..12dfc544b8 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleContainerResource.java @@ -29,6 +29,7 @@ import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.services.ErrorResponse; +import javax.ws.rs.BadRequestException; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; @@ -77,6 +78,10 @@ public class RoleContainerResource extends RoleResource { public List getRoles() { auth.requireAny(); + if (roleContainer == null) { + throw new NotFoundException("Could not find client"); + } + Set roleModels = roleContainer.getRoles(); List roles = new ArrayList(); for (RoleModel roleModel : roleModels) { @@ -96,6 +101,14 @@ public class RoleContainerResource extends RoleResource { public Response createRole(final RoleRepresentation rep) { auth.requireManage(); + if (roleContainer == null) { + throw new NotFoundException("Could not find client"); + } + + if (rep.getName() == null) { + throw new BadRequestException(); + } + try { RoleModel role = roleContainer.addRole(rep.getName()); role.setDescription(rep.getDescription()); @@ -123,6 +136,10 @@ public class RoleContainerResource extends RoleResource { public RoleRepresentation getRole(final @PathParam("role-name") String roleName) { auth.requireView(); + if (roleContainer == null) { + throw new NotFoundException("Could not find client"); + } + RoleModel roleModel = roleContainer.getRole(roleName); if (roleModel == null) { throw new NotFoundException("Could not find role"); @@ -142,6 +159,10 @@ public class RoleContainerResource extends RoleResource { public void deleteRole(final @PathParam("role-name") String roleName) { auth.requireManage(); + if (roleContainer == null) { + throw new NotFoundException("Could not find client"); + } + RoleRepresentation rep = getRole(roleName); RoleModel role = roleContainer.getRole(roleName); if (role == null) { @@ -166,6 +187,10 @@ public class RoleContainerResource extends RoleResource { public Response updateRole(final @PathParam("role-name") String roleName, final RoleRepresentation rep) { auth.requireManage(); + if (roleContainer == null) { + throw new NotFoundException("Could not find client"); + } + RoleModel role = roleContainer.getRole(roleName); if (role == null) { throw new NotFoundException("Could not find role"); @@ -193,6 +218,10 @@ public class RoleContainerResource extends RoleResource { public void addComposites(final @PathParam("role-name") String roleName, List roles) { auth.requireManage(); + if (roleContainer == null) { + throw new NotFoundException("Could not find client"); + } + RoleModel role = roleContainer.getRole(roleName); if (role == null) { throw new NotFoundException("Could not find role"); @@ -211,7 +240,11 @@ public class RoleContainerResource extends RoleResource { @NoCache @Produces(MediaType.APPLICATION_JSON) public Set getRoleComposites(final @PathParam("role-name") String roleName) { - auth.requireManage(); + auth.requireView(); + + if (roleContainer == null) { + throw new NotFoundException("Could not find client"); + } RoleModel role = roleContainer.getRole(roleName); if (role == null) { @@ -231,7 +264,11 @@ public class RoleContainerResource extends RoleResource { @NoCache @Produces(MediaType.APPLICATION_JSON) public Set getRealmRoleComposites(final @PathParam("role-name") String roleName) { - auth.requireManage(); + auth.requireView(); + + if (roleContainer == null) { + throw new NotFoundException("Could not find client"); + } RoleModel role = roleContainer.getRole(roleName); if (role == null) { @@ -254,7 +291,11 @@ public class RoleContainerResource extends RoleResource { public Set getClientRoleComposites(@Context final UriInfo uriInfo, final @PathParam("role-name") String roleName, final @PathParam("client") String client) { - auth.requireManage(); + auth.requireView(); + + if (roleContainer == null) { + throw new NotFoundException("Could not find client"); + } RoleModel role = roleContainer.getRole(roleName); if (role == null) { @@ -283,6 +324,10 @@ public class RoleContainerResource extends RoleResource { List roles) { auth.requireManage(); + if (roleContainer == null) { + throw new NotFoundException("Could not find client"); + } + RoleModel role = roleContainer.getRole(roleName); if (role == null) { throw new NotFoundException("Could not find role"); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java b/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java index f6df8aa905..d8fe9041d7 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/RoleMapperResource.java @@ -104,6 +104,10 @@ public class RoleMapperResource { public MappingsRepresentation getRoleMappings() { auth.requireView(); + if (roleMapper == null) { + throw new NotFoundException("User not found"); + } + MappingsRepresentation all = new MappingsRepresentation(); Set realmMappings = roleMapper.getRealmRoleMappings(); RealmManager manager = new RealmManager(session); @@ -149,6 +153,10 @@ public class RoleMapperResource { public List getRealmRoleMappings() { auth.requireView(); + if (roleMapper == null) { + throw new NotFoundException("User not found"); + } + Set realmMappings = roleMapper.getRealmRoleMappings(); List realmMappingsRep = new ArrayList(); for (RoleModel roleModel : realmMappings) { @@ -171,6 +179,10 @@ public class RoleMapperResource { public List getCompositeRealmRoleMappings() { auth.requireView(); + if (roleMapper == null) { + throw new NotFoundException("User not found"); + } + Set roles = realm.getRoles(); List realmMappingsRep = new ArrayList(); for (RoleModel roleModel : roles) { @@ -193,6 +205,10 @@ public class RoleMapperResource { public List getAvailableRealmRoleMappings() { auth.requireView(); + if (roleMapper == null) { + throw new NotFoundException("User not found"); + } + Set available = realm.getRoles(); return ClientRoleMappingsResource.getAvailableRoles(roleMapper, available); } @@ -208,6 +224,10 @@ public class RoleMapperResource { public void addRealmRoleMappings(List roles) { auth.requireManage(); + if (roleMapper == null) { + throw new NotFoundException("User not found"); + } + logger.debugv("** addRealmRoleMappings: {0}", roles); for (RoleRepresentation role : roles) { @@ -231,6 +251,10 @@ public class RoleMapperResource { public void deleteRealmRoleMappings(List roles) { auth.requireManage(); + if (roleMapper == null) { + throw new NotFoundException("User not found"); + } + logger.debug("deleteRealmRoleMappings"); if (roles == null) { Set roleModels = roleMapper.getRealmRoleMappings(); @@ -262,10 +286,6 @@ public class RoleMapperResource { @Path("clients/{client}") public ClientRoleMappingsResource getUserClientRoleMappingsResource(@PathParam("client") String client) { ClientModel clientModel = realm.getClientById(client); - if (clientModel == null) { - throw new NotFoundException("Client not found"); - } - return new ClientRoleMappingsResource(uriInfo, session, realm, auth, roleMapper, clientModel, adminEvent); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java index 7861caf56b..2ff4d2f37e 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedClientResource.java @@ -75,6 +75,10 @@ public class ScopeMappedClientResource { public List getClientScopeMappings() { auth.requireView(); + if (scopeContainer == null) { + throw new NotFoundException("Could not find client"); + } + Set mappings = KeycloakModelUtils.getClientScopeMappings(scopedClient, scopeContainer); //scopedClient.getClientScopeMappings(client); List mapRep = new ArrayList(); for (RoleModel roleModel : mappings) { @@ -97,6 +101,10 @@ public class ScopeMappedClientResource { public List getAvailableClientScopeMappings() { auth.requireView(); + if (scopeContainer == null) { + throw new NotFoundException("Could not find client"); + } + Set roles = scopedClient.getRoles(); return ScopeMappedResource.getAvailable(scopeContainer, roles); } @@ -115,6 +123,10 @@ public class ScopeMappedClientResource { public List getCompositeClientScopeMappings() { auth.requireView(); + if (scopeContainer == null) { + throw new NotFoundException("Could not find client"); + } + Set roles = scopedClient.getRoles(); return ScopeMappedResource.getComposite(scopeContainer, roles); } @@ -129,6 +141,10 @@ public class ScopeMappedClientResource { public void addClientScopeMapping(List roles) { auth.requireManage(); + if (scopeContainer == null) { + throw new NotFoundException("Could not find client"); + } + for (RoleRepresentation role : roles) { RoleModel roleModel = scopedClient.getRole(role.getName()); if (roleModel == null) { @@ -149,6 +165,10 @@ public class ScopeMappedClientResource { public void deleteClientScopeMapping(List roles) { auth.requireManage(); + if (scopeContainer == null) { + throw new NotFoundException("Could not find client"); + } + if (roles == null) { Set roleModels = KeycloakModelUtils.getClientScopeMappings(scopedClient, scopeContainer);//scopedClient.getClientScopeMappings(client); for (RoleModel roleModel : roleModels) { diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java index 00fb31da69..1f2fbe7084 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ScopeMappedResource.java @@ -78,6 +78,10 @@ public class ScopeMappedResource { public MappingsRepresentation getScopeMappings() { auth.requireView(); + if (scopeContainer == null) { + throw new NotFoundException("Could not find client"); + } + MappingsRepresentation all = new MappingsRepresentation(); Set realmMappings = scopeContainer.getRealmScopeMappings(); if (realmMappings.size() > 0) { @@ -122,6 +126,10 @@ public class ScopeMappedResource { public List getRealmScopeMappings() { auth.requireView(); + if (scopeContainer == null) { + throw new NotFoundException("Could not find client"); + } + Set realmMappings = scopeContainer.getRealmScopeMappings(); List realmMappingsRep = new ArrayList(); for (RoleModel roleModel : realmMappings) { @@ -142,6 +150,10 @@ public class ScopeMappedResource { public List getAvailableRealmScopeMappings() { auth.requireView(); + if (scopeContainer == null) { + throw new NotFoundException("Could not find client"); + } + Set roles = realm.getRoles(); return getAvailable(scopeContainer, roles); } @@ -171,6 +183,10 @@ public class ScopeMappedResource { public List getCompositeRealmScopeMappings() { auth.requireView(); + if (scopeContainer == null) { + throw new NotFoundException("Could not find client"); + } + Set roles = realm.getRoles(); return getComposite(scopeContainer, roles); } @@ -194,6 +210,10 @@ public class ScopeMappedResource { public void addRealmScopeMappings(List roles) { auth.requireManage(); + if (scopeContainer == null) { + throw new NotFoundException("Could not find client"); + } + for (RoleRepresentation role : roles) { RoleModel roleModel = realm.getRoleById(role.getId()); if (roleModel == null) { @@ -215,6 +235,10 @@ public class ScopeMappedResource { public void deleteRealmScopeMappings(List roles) { auth.requireManage(); + if (scopeContainer == null) { + throw new NotFoundException("Could not find client"); + } + if (roles == null) { Set roleModels = scopeContainer.getRealmScopeMappings(); for (RoleModel roleModel : roleModels) { @@ -237,9 +261,6 @@ public class ScopeMappedResource { @Path("clients/{client}") public ScopeMappedClientResource getClientByIdScopeMappings(@PathParam("client") String client) { ClientModel clientModel = realm.getClientById(client); - if (clientModel == null) { - throw new NotFoundException("Client not found"); - } return new ScopeMappedClientResource(realm, auth, this.scopeContainer, session, clientModel, adminEvent); } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java index 312690c092..0d15f9b2f0 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java @@ -101,6 +101,10 @@ public class UserFederationProviderResource { public void updateProviderInstance(UserFederationProviderRepresentation rep) { auth.requireManage(); + if (federationProviderModel == null) { + throw new NotFoundException("Could not find federation provider"); + } + String displayName = rep.getDisplayName(); if (displayName != null && displayName.trim().equals("")) { displayName = null; @@ -131,6 +135,10 @@ public class UserFederationProviderResource { public UserFederationProviderRepresentation getProviderInstance() { auth.requireView(); + if (federationProviderModel == null) { + throw new NotFoundException("Could not find federation provider"); + } + return ModelToRepresentation.toRepresentation(this.federationProviderModel); } @@ -143,6 +151,10 @@ public class UserFederationProviderResource { public void deleteProviderInstance() { auth.requireManage(); + if (federationProviderModel == null) { + throw new NotFoundException("Could not find federation provider"); + } + realm.removeUserFederationProvider(this.federationProviderModel); new UsersSyncManager().notifyToRefreshPeriodicSync(session, realm, this.federationProviderModel, true); @@ -162,6 +174,10 @@ public class UserFederationProviderResource { public UserFederationSyncResult syncUsers(@QueryParam("action") String action) { auth.requireManage(); + if (federationProviderModel == null) { + throw new NotFoundException("Could not find federation provider"); + } + logger.debug("Syncing users"); UsersSyncManager syncManager = new UsersSyncManager(); @@ -190,6 +206,10 @@ public class UserFederationProviderResource { public Map getMapperTypes() { auth.requireView(); + if (federationProviderModel == null) { + throw new NotFoundException("Could not find federation provider"); + } + KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory(); Map types = new HashMap<>(); List factories = sessionFactory.getProviderFactories(UserFederationMapper.class); @@ -234,6 +254,10 @@ public class UserFederationProviderResource { public List getMappers() { auth.requireView(); + if (federationProviderModel == null) { + throw new NotFoundException("Could not find federation provider"); + } + List mappers = new LinkedList<>(); for (UserFederationMapperModel model : realm.getUserFederationMappersByFederationProvider(this.federationProviderModel.getId())) { mappers.add(ModelToRepresentation.toRepresentation(realm, model)); @@ -273,6 +297,10 @@ public class UserFederationProviderResource { public Response addMapper(UserFederationMapperRepresentation mapper) { auth.requireManage(); + if (federationProviderModel == null) { + throw new NotFoundException("Could not find federation provider"); + } + UserFederationMapperModel model = RepresentationToModel.toModel(realm, mapper); validateModel(model); @@ -299,6 +327,10 @@ public class UserFederationProviderResource { public UserFederationMapperRepresentation getMapperById(@PathParam("id") String id) { auth.requireView(); + if (federationProviderModel == null) { + throw new NotFoundException("Could not find federation provider"); + } + UserFederationMapperModel model = realm.getUserFederationMapperById(id); if (model == null) throw new NotFoundException("Model not found"); return ModelToRepresentation.toRepresentation(realm, model); @@ -317,6 +349,10 @@ public class UserFederationProviderResource { public void update(@PathParam("id") String id, UserFederationMapperRepresentation rep) { auth.requireManage(); + if (federationProviderModel == null) { + throw new NotFoundException("Could not find federation provider"); + } + UserFederationMapperModel model = realm.getUserFederationMapperById(id); if (model == null) throw new NotFoundException("Model not found"); model = RepresentationToModel.toModel(realm, rep); @@ -339,6 +375,10 @@ public class UserFederationProviderResource { public void delete(@PathParam("id") String id) { auth.requireManage(); + if (federationProviderModel == null) { + throw new NotFoundException("Could not find federation provider"); + } + UserFederationMapperModel model = realm.getUserFederationMapperById(id); if (model == null) throw new NotFoundException("Model not found"); realm.removeUserFederationMapper(model); @@ -358,6 +398,10 @@ public class UserFederationProviderResource { public UserFederationSyncResult syncMapperData(@PathParam("id") String mapperId, @QueryParam("direction") String direction) { auth.requireManage(); + if (federationProviderModel == null) { + throw new NotFoundException("Could not find federation provider"); + } + UserFederationMapperModel mapperModel = realm.getUserFederationMapperById(mapperId); if (mapperModel == null) throw new NotFoundException("Mapper model not found"); UserFederationMapper mapper = session.getProvider(UserFederationMapper.class, mapperModel.getFederationMapperType()); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java index d7e66b1353..7e0e7a268b 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UserFederationProvidersResource.java @@ -227,7 +227,7 @@ public class UserFederationProvidersResource { @Produces(MediaType.APPLICATION_JSON) @NoCache public List getUserFederationInstances() { - auth.requireManage(); + auth.requireView(); List reps = new LinkedList(); for (UserFederationProviderModel model : realm.getUserFederationProviders()) { @@ -242,10 +242,6 @@ public class UserFederationProvidersResource { this.auth.requireView(); UserFederationProviderModel model = KeycloakModelUtils.findUserFederationProviderById(id, realm); - if (model == null) { - throw new NotFoundException("Could not find federation provider"); - } - UserFederationProviderResource instanceResource = new UserFederationProviderResource(session, realm, this.auth, model, adminEvent); ResteasyProviderFactory.getInstance().injectProperties(instanceResource); return instanceResource; diff --git a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java index dc51cdc9a0..bbc6a963aa 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/UsersResource.java @@ -702,12 +702,9 @@ public class UsersResource { @Path("{id}/role-mappings") public RoleMapperResource getRoleMappings(@PathParam("id") String id) { + auth.init(RealmAuth.Resource.USER); UserModel user = session.users().getUserById(id, realm); - if (user == null) { - throw new NotFoundException("User not found"); - } - auth.init(RealmAuth.Resource.USER); RoleMapperResource resource = new RoleMapperResource(realm, auth, user, adminEvent); ResteasyProviderFactory.getInstance().injectProperties(resource); diff --git a/testsuite/integration-arquillian/pom.xml b/testsuite/integration-arquillian/pom.xml index 5266731c2f..882eab4cc1 100644 --- a/testsuite/integration-arquillian/pom.xml +++ b/testsuite/integration-arquillian/pom.xml @@ -100,6 +100,14 @@ xml-maven-plugin 1.0.1 + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java index 8dfcdf0210..257512bae1 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java @@ -161,7 +161,7 @@ public abstract class AbstractKeycloakTest { resetTimeOffset(); } -// removeTestRealms(); // keeping test realms after test to be able to inspect failures, instead deleting existing realms before import + removeTestRealms(); // Remove realms after tests. Tests should cleanup after themselves! // adminClient.close(); // keeping admin connection open } @@ -243,7 +243,10 @@ public abstract class AbstractKeycloakTest { } public void removeRealm(RealmRepresentation realm) { - adminClient.realms().realm(realm.getRealm()).remove(); + try { + adminClient.realms().realm(realm.getRealm()).remove(); + } catch (NotFoundException e) { + } } public RealmsResource realmsResouce() { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java new file mode 100644 index 0000000000..b7fd462265 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java @@ -0,0 +1,651 @@ +/* + * Copyright 2016 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; + +import org.junit.Rule; +import org.junit.Test; +import org.keycloak.admin.client.Keycloak; +import org.keycloak.admin.client.resource.RealmResource; +import org.keycloak.models.AdminRoles; +import org.keycloak.models.Constants; +import org.keycloak.representations.KeyStoreConfig; +import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation; +import org.keycloak.representations.idm.AuthenticationExecutionRepresentation; +import org.keycloak.representations.idm.AuthenticationFlowRepresentation; +import org.keycloak.representations.idm.AuthenticatorConfigRepresentation; +import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.ClientTemplateRepresentation; +import org.keycloak.representations.idm.GroupRepresentation; +import org.keycloak.representations.idm.IdentityProviderRepresentation; +import org.keycloak.representations.idm.PartialImportRepresentation; +import org.keycloak.representations.idm.ProtocolMapperRepresentation; +import org.keycloak.representations.idm.RealmEventsConfigRepresentation; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.representations.idm.RequiredActionProviderRepresentation; +import org.keycloak.representations.idm.RoleRepresentation; +import org.keycloak.representations.idm.UserFederationMapperRepresentation; +import org.keycloak.representations.idm.UserFederationProviderRepresentation; +import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.services.resources.admin.RealmAuth.Resource; +import org.keycloak.testsuite.AbstractKeycloakTest; +import org.keycloak.testsuite.Assert; +import org.keycloak.testsuite.arquillian.AuthServerTestEnricher; +import org.keycloak.testsuite.util.ClientBuilder; +import org.keycloak.testsuite.util.CredentialBuilder; +import org.keycloak.testsuite.util.FederatedIdentityBuilder; +import org.keycloak.testsuite.util.GreenMailRule; +import org.keycloak.testsuite.util.IdentityProviderBuilder; +import org.keycloak.testsuite.util.RealmBuilder; +import org.keycloak.testsuite.util.UserBuilder; + +import javax.ws.rs.ClientErrorException; +import javax.ws.rs.core.Response; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; + +import static org.junit.Assert.*; + +/** + * @author Stian Thorgersen + */ +public class PermissionsTest extends AbstractKeycloakTest { + + private static final String REALM_NAME = "permissions-test"; + + private Map clients = new HashMap<>(); + + @Rule + public GreenMailRule greenMailRule = new GreenMailRule(); + + @Override + public void addTestRealms(List testRealms) { + RealmBuilder builder = RealmBuilder.create().name(REALM_NAME).testMail(); + builder.client(ClientBuilder.create().clientId("test-client").publicClient().directAccessGrants()); + + builder.user(UserBuilder.create().username(AdminRoles.REALM_ADMIN).role(Constants.REALM_MANAGEMENT_CLIENT_ID, AdminRoles.REALM_ADMIN).addPassword("password")); + clients.put(AdminRoles.REALM_ADMIN, Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, AdminRoles.REALM_ADMIN, "password", "test-client", "secret")); + + builder.user(UserBuilder.create().username("none").addPassword("password")); + clients.put("none", Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, "none", "password", "test-client", "secret")); + + for (String role : AdminRoles.ALL_REALM_ROLES) { + builder.user(UserBuilder.create().username(role).role(Constants.REALM_MANAGEMENT_CLIENT_ID, role).addPassword("password")); + clients.put(role, Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", REALM_NAME, role, "password", "test-client")); + } + testRealms.add(builder.build()); + + RealmBuilder builder2 = RealmBuilder.create().name("realm2"); + builder2.client(ClientBuilder.create().clientId("test-client").publicClient().directAccessGrants()); + builder2.user(UserBuilder.create().username("admin").role(Constants.REALM_MANAGEMENT_CLIENT_ID, AdminRoles.REALM_ADMIN).addPassword("password")); + testRealms.add(builder2.build()); + + clients.put("REALM2", Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", "realm2", "admin", "password", "test-client")); + } + + @Override + public void beforeAbstractKeycloakTest() throws Exception { + super.beforeAbstractKeycloakTest(); + + clients.put("master-admin", adminClient); + + RealmResource master = adminClient.realm("master"); + + { + Response response = master.users().create(UserBuilder.create().username("permissions-test-master-none").build()); + String userId = ApiUtil.getCreatedId(response); + response.close(); + + master.users().get(userId).resetPassword(CredentialBuilder.create().password("password").build()); + + clients.put("master-none", Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", "master", "permissions-test-master-none", "password", Constants.ADMIN_CLI_CLIENT_ID)); + } + + for (String role : AdminRoles.ALL_REALM_ROLES) { + Response response = master.users().create(UserBuilder.create().username("permissions-test-master-" + role).build()); + String userId = ApiUtil.getCreatedId(response); + response.close(); + + master.users().get(userId).resetPassword(CredentialBuilder.create().password("password").build()); + String clientId = master.clients().findByClientId(REALM_NAME + "-realm").get(0).getId(); + RoleRepresentation roleRep = master.clients().get(clientId).roles().get(role).toRepresentation(); + master.users().get(userId).roles().clientLevel(clientId).add(Collections.singletonList(roleRep)); + + clients.put("master-" + role, Keycloak.getInstance(AuthServerTestEnricher.getAuthServerContextRoot() + "/auth", "master", "permissions-test-master-" + role, "password", Constants.ADMIN_CLI_CLIENT_ID)); + } + } + + @Override + public void afterAbstractKeycloakTest() { + super.afterAbstractKeycloakTest(); + + for (UserRepresentation u : adminClient.realm("master").users().search("permissions-test-master-", 0, 100)) { + adminClient.realm("master").users().get(u.getId()).remove(); + } + } + + @Test + public void realms() { + // Check returned realms + invoke((realm) -> { clients.get("master-none").realms().findAll(); }, clients.get("none"), false); + invoke((realm) -> { clients.get("none").realms().findAll(); }, clients.get("none"), false); + Assert.assertNames(clients.get("master-admin").realms().findAll(), "master", REALM_NAME, "realm2"); + Assert.assertNames(clients.get(AdminRoles.REALM_ADMIN).realms().findAll(), REALM_NAME); + Assert.assertNames(clients.get("REALM2").realms().findAll(), "realm2"); + + // Check realm only contains name if missing view realm permission + List realms = clients.get(AdminRoles.VIEW_USERS).realms().findAll(); + Assert.assertNames(realms, REALM_NAME); + assertGettersEmpty(realms.get(0)); + + realms = clients.get(AdminRoles.VIEW_REALM).realms().findAll(); + Assert.assertNames(realms, REALM_NAME); + assertNotNull(realms.get(0).getAccessTokenLifespan()); + + // Create realm + invoke((realm) -> { clients.get("master-admin").realms().create(RealmBuilder.create().name("master").build()); }, adminClient, true); + invoke((realm) -> { clients.get("master-" + AdminRoles.MANAGE_USERS).realms().create(RealmBuilder.create().name("master").build()); }, adminClient, false); + invoke((realm) -> { clients.get(AdminRoles.REALM_ADMIN).realms().create(RealmBuilder.create().name("master").build()); }, adminClient, false); + + // Get realm + invoke((realm) -> { realm.toRepresentation(); }, Resource.REALM, false, true); + assertGettersEmpty(clients.get(AdminRoles.VIEW_USERS).realm(REALM_NAME).toRepresentation()); + + invoke((realm) -> { realm.update(new RealmRepresentation()); }, Resource.REALM, true); + invoke((realm) -> { realm.pushRevocation(); }, Resource.REALM, true); + invoke((realm) -> { realm.deleteSession("nosuch"); }, Resource.USER, true); + invoke((realm) -> { realm.getClientSessionStats(); }, Resource.REALM, false); + + invoke((realm) -> { realm.getDefaultGroups(); }, Resource.REALM, false); + invoke((realm) -> { realm.addDefaultGroup("nosuch"); }, Resource.REALM, true); + invoke((realm) -> { realm.removeDefaultGroup("nosuch"); }, Resource.REALM, true); + invoke((realm) -> { realm.getGroupByPath("nosuch"); }, Resource.REALM, false); + + invoke((realm, response) -> { response.set(realm.testLDAPConnection("nosuch", "nosuch", "nosuch", "nosuch", "nosuch")); }, Resource.REALM, true); + + invoke((realm, response) -> { response.set(realm.partialImport(new PartialImportRepresentation())); }, Resource.REALM, true); + invoke((realm) -> { realm.clearRealmCache(); }, Resource.REALM, true); + invoke((realm) -> { realm.clearUserCache(); }, Resource.REALM, true); + + // Delete realm + invoke((realm) -> { clients.get("master-admin").realms().realm("nosuch").remove(); }, adminClient, true); + invoke((realm) -> { clients.get("REALM2").realms().realm(REALM_NAME).remove(); }, adminClient, false); + invoke((realm) -> { clients.get(AdminRoles.MANAGE_USERS).realms().realm(REALM_NAME).remove(); }, adminClient, false); + invoke((realm) -> { clients.get(AdminRoles.REALM_ADMIN).realms().realm(REALM_NAME).remove(); }, adminClient, true); + + // TODO + // invoke((realm) -> { realm.logoutAll(); }, Resource.USER, true); + } + + @Test + public void events() { + invoke((realm) -> { realm.getRealmEventsConfig(); }, Resource.EVENTS, false); + invoke((realm) -> { realm.updateRealmEventsConfig(new RealmEventsConfigRepresentation()); }, Resource.EVENTS, true); + invoke((realm) -> { realm.getEvents(); }, Resource.EVENTS, false); + invoke((realm) -> { realm.getAdminEvents(); }, Resource.EVENTS, false); + invoke((realm) -> { realm.clearEvents(); }, Resource.EVENTS, true); + invoke((realm) -> { realm.clearAdminEvents(); }, Resource.EVENTS, true); + } + + @Test + public void attackDetection() { + invoke((realm) -> { realm.attackDetection().bruteForceUserStatus("nosuch"); }, Resource.USER, false); + invoke((realm) -> { realm.attackDetection().clearBruteForceForUser("nosuch"); }, Resource.USER, true); + invoke((realm) -> { realm.attackDetection().clearAllBruteForce(); }, Resource.USER, true); + } + + @Test + public void clients() { + invoke((realm) -> { realm.clients().findAll(); }, Resource.CLIENT, false, true); + List l = clients.get(AdminRoles.VIEW_USERS).realm(REALM_NAME).clients().findAll(); + assertGettersEmpty(l.get(0)); + + invoke((realm) -> { realm.convertClientDescription("blahblah"); }, Resource.CLIENT, true); + invoke((realm, response) -> { response.set(realm.clients().create(ClientBuilder.create().clientId("foo").build())); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").toRepresentation(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clients().get("nosuch").getInstallationProvider("nosuch"); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clients().get("nosuch").update(new ClientRepresentation()); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").remove(); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").generateNewSecret(); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").regenerateRegistrationAccessToken(); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").getSecret(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clients().get("nosuch").getServiceAccountUser(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clients().get("nosuch").pushRevocation(); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").getApplicationSessionCount(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clients().get("nosuch").getUserSessions(0, 100); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clients().get("nosuch").getOfflineSessionCount(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clients().get("nosuch").getOfflineUserSessions(0, 100); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clients().get("nosuch").registerNode(new HashMap<>()); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").unregisterNode("nosuch"); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").testNodesAvailable(); }, Resource.CLIENT, true); + + invoke((realm) -> { realm.clients().get("nosuch").getCertficateResource("nosuch").generate(); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").getCertficateResource("nosuch").generateAndGetKeystore(new KeyStoreConfig()); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").getCertficateResource("nosuch").getKeyInfo(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clients().get("nosuch").getCertficateResource("nosuch").getKeystore(new KeyStoreConfig()); }, Resource.CLIENT, false); + + // TODO + // invoke((realm) -> { realm.clients().get("nosuch").getCertficateResource("nosuch").uploadJks(null); }, Resource.CLIENT, true); + // invoke((realm) -> { realm.clients().get("nosuch").getCertficateResource("nosuch").uploadJksCertificate(null); }, Resource.CLIENT, true); + + invoke((realm) -> { realm.clients().get("nosuch").getProtocolMappers().createMapper(Collections.EMPTY_LIST); }, Resource.CLIENT, true); + invoke((realm, response) -> { response.set(realm.clients().get("nosuch").getProtocolMappers().createMapper(new ProtocolMapperRepresentation())); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").getProtocolMappers().getMapperById("nosuch"); }, Resource.CLIENT, false, true); + invoke((realm) -> { realm.clients().get("nosuch").getProtocolMappers().getMappers(); }, Resource.CLIENT, false, true); + invoke((realm) -> { realm.clients().get("nosuch").getProtocolMappers().getMappersPerProtocol("nosuch"); }, Resource.CLIENT, false, true); + invoke((realm) -> { realm.clients().get("nosuch").getProtocolMappers().update("nosuch", new ProtocolMapperRepresentation()); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").getProtocolMappers().delete("nosuch"); }, Resource.CLIENT, true); + + invoke((realm) -> { realm.clients().get("nosuch").getScopeMappings().getAll(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clients().get("nosuch").getScopeMappings().realmLevel().listAll(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clients().get("nosuch").getScopeMappings().realmLevel().listEffective(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clients().get("nosuch").getScopeMappings().realmLevel().listAvailable(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clients().get("nosuch").getScopeMappings().realmLevel().add(Collections.emptyList()); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").getScopeMappings().realmLevel().remove(Collections.emptyList()); }, Resource.CLIENT, true); + + invoke((realm) -> { realm.clients().get("nosuch").roles().list(); }, Resource.CLIENT, false, true); + invoke((realm) -> { realm.clients().get("nosuch").roles().create(new RoleRepresentation()); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").roles().get("nosuch").toRepresentation(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clients().get("nosuch").roles().deleteRole("nosuch"); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").roles().get("nosuch").update(new RoleRepresentation()); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").roles().get("nosuch").addComposites(Collections.emptyList()); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").roles().get("nosuch").deleteComposites(Collections.emptyList()); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clients().get("nosuch").roles().get("nosuch").getRoleComposites(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clients().get("nosuch").roles().get("nosuch").getRealmRoleComposites(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clients().get("nosuch").roles().get("nosuch").getClientRoleComposites("nosuch"); }, Resource.CLIENT, false); + } + + @Test + public void clientTemplates() { + invoke((realm) -> { realm.clientTemplates().findAll(); }, Resource.CLIENT, false); + invoke((realm, response) -> { response.set(realm.clientTemplates().create(new ClientTemplateRepresentation())); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clientTemplates().get("nosuch").toRepresentation(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clientTemplates().get("nosuch").update(new ClientTemplateRepresentation()); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clientTemplates().get("nosuch").remove(); }, Resource.CLIENT, true); + + invoke((realm) -> { realm.clientTemplates().get("nosuch").getProtocolMappers().getMappers(); }, Resource.CLIENT, false, true); + invoke((realm) -> { realm.clientTemplates().get("nosuch").getProtocolMappers().getMappersPerProtocol("nosuch"); }, Resource.CLIENT, false, true); + invoke((realm) -> { realm.clientTemplates().get("nosuch").getProtocolMappers().getMapperById("nosuch"); }, Resource.CLIENT, false, true); + invoke((realm) -> { realm.clientTemplates().get("nosuch").getProtocolMappers().update("nosuch", new ProtocolMapperRepresentation()); }, Resource.CLIENT, true); + invoke((realm, response) -> { response.set(realm.clientTemplates().get("nosuch").getProtocolMappers().createMapper(new ProtocolMapperRepresentation())); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clientTemplates().get("nosuch").getProtocolMappers().createMapper(Collections.emptyList()); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clientTemplates().get("nosuch").getProtocolMappers().delete("nosuch"); }, Resource.CLIENT, true); + + invoke((realm) -> { realm.clientTemplates().get("nosuch").getScopeMappings().getAll(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clientTemplates().get("nosuch").getScopeMappings().realmLevel().listAll(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clientTemplates().get("nosuch").getScopeMappings().realmLevel().listAvailable(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clientTemplates().get("nosuch").getScopeMappings().realmLevel().listEffective(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clientTemplates().get("nosuch").getScopeMappings().realmLevel().add(Collections.emptyList()); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clientTemplates().get("nosuch").getScopeMappings().realmLevel().remove(Collections.emptyList()); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clientTemplates().get("nosuch").getScopeMappings().clientLevel("nosuch").listAll(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clientTemplates().get("nosuch").getScopeMappings().clientLevel("nosuch").listAvailable(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clientTemplates().get("nosuch").getScopeMappings().clientLevel("nosuch").listEffective(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clientTemplates().get("nosuch").getScopeMappings().clientLevel("nosuch").add(Collections.emptyList()); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clientTemplates().get("nosuch").getScopeMappings().clientLevel("nosuch").remove(Collections.emptyList()); }, Resource.CLIENT, true); + } + + @Test + public void clientInitialAccess() { + invoke((realm) -> { realm.clientInitialAccess().list(); }, Resource.CLIENT, false); + invoke((realm) -> { realm.clientInitialAccess().create(new ClientInitialAccessCreatePresentation()); }, Resource.CLIENT, true); + invoke((realm) -> { realm.clientInitialAccess().delete("nosuch"); }, Resource.CLIENT, true); + } + + @Test + public void roles() { + invoke((realm) -> { realm.roles().list(); }, Resource.REALM, false, true); + invoke((realm) -> { realm.roles().get("nosuch").toRepresentation(); }, Resource.REALM, false); + invoke((realm) -> { realm.roles().get("nosuch").update(new RoleRepresentation()); }, Resource.REALM, true); + invoke((realm) -> { realm.roles().create(new RoleRepresentation()); }, Resource.REALM, true); + invoke((realm) -> { realm.roles().deleteRole("nosuch"); }, Resource.REALM, true); + invoke((realm) -> { realm.roles().get("nosuch").getRoleComposites(); }, Resource.REALM, false); + invoke((realm) -> { realm.roles().get("nosuch").addComposites(Collections.emptyList()); }, Resource.REALM, true); + invoke((realm) -> { realm.roles().get("nosuch").deleteComposites(Collections.emptyList()); }, Resource.REALM, true); + invoke((realm) -> { realm.roles().get("nosuch").getRoleComposites(); }, Resource.REALM, false); + invoke((realm) -> { realm.roles().get("nosuch").getRealmRoleComposites(); }, Resource.REALM, false); + invoke((realm) -> { realm.roles().get("nosuch").getClientRoleComposites("nosuch"); }, Resource.REALM, false); + } + + @Test + public void flows() { + invoke((realm) -> { realm.flows().getFormProviders(); }, Resource.REALM, false); + invoke((realm) -> { realm.flows().getAuthenticatorProviders(); }, Resource.REALM, false); + invoke((realm) -> { realm.flows().getClientAuthenticatorProviders(); }, Resource.REALM, false, true); + invoke((realm) -> { realm.flows().getFormActionProviders(); }, Resource.REALM, false); + invoke((realm) -> { realm.flows().getFlows(); }, Resource.REALM, false, true); + invoke((realm, response) -> { response.set(realm.flows().createFlow(new AuthenticationFlowRepresentation())); }, Resource.REALM, true); + invoke((realm) -> { realm.flows().getFlow("nosuch"); }, Resource.REALM, false); + invoke((realm) -> { realm.flows().deleteFlow("nosuch"); }, Resource.REALM, true); + invoke((realm, response) -> { response.set(realm.flows().copy("nosuch", new HashMap<>())); }, Resource.REALM, true); + invoke((realm) -> { realm.flows().addExecutionFlow("nosuch", new HashMap<>()); }, Resource.REALM, true); + invoke((realm) -> { realm.flows().addExecution("nosuch", new HashMap<>()); }, Resource.REALM, true); + invoke((realm) -> { realm.flows().getExecutions("nosuch"); }, Resource.REALM, false); + invoke((realm) -> { realm.flows().updateExecutions("nosuch", new AuthenticationExecutionInfoRepresentation()); }, Resource.REALM, true); + AuthenticationExecutionRepresentation rep = new AuthenticationExecutionRepresentation(); + rep.setAuthenticator("auth-cookie"); + rep.setRequirement("OPTIONAL"); + invoke((realm, response) -> { response.set(realm.flows().addExecution(rep)); }, Resource.REALM, true); + invoke((realm) -> { realm.flows().raisePriority("nosuch"); }, Resource.REALM, true); + invoke((realm) -> { realm.flows().lowerPriority("nosuch"); }, Resource.REALM, true); + invoke((realm) -> { realm.flows().removeExecution("nosuch"); }, Resource.REALM, true); + invoke((realm, response) -> { response.set(realm.flows().newExecutionConfig("nosuch", new AuthenticatorConfigRepresentation())); }, Resource.REALM, true); + invoke((realm) -> { realm.flows().getAuthenticatorConfig("nosuch", "nosuch"); }, Resource.REALM, false); + invoke((realm) -> { realm.flows().getUnregisteredRequiredActions(); }, Resource.REALM, false); + invoke((realm) -> { realm.flows().registereRequiredAction(new HashMap<>()); }, Resource.REALM, true); + invoke((realm) -> { realm.flows().getRequiredActions(); }, Resource.REALM, false, true); + invoke((realm) -> { realm.flows().getRequiredAction("nosuch"); }, Resource.REALM, false); + invoke((realm) -> { realm.flows().updateRequiredAction("nosuch"); }, Resource.REALM, true); + invoke((realm) -> { realm.flows().updateRequiredAction("nosuch", new RequiredActionProviderRepresentation()); }, Resource.REALM, true); + invoke((realm) -> { realm.flows().getAuthenticatorConfigDescription("nosuch"); }, Resource.REALM, false); + invoke((realm) -> { realm.flows().getPerClientConfigDescription(); }, Resource.REALM, false, true); + invoke((realm, response) -> { response.set(realm.flows().createAuthenticatorConfig(new AuthenticatorConfigRepresentation())); }, Resource.REALM, true); + invoke((realm) -> { realm.flows().getAuthenticatorConfig("nosuch"); }, Resource.REALM, false); + invoke((realm) -> { realm.flows().removeAuthenticatorConfig("nosuch"); }, Resource.REALM, true); + invoke((realm) -> { realm.flows().updateAuthenticatorConfig("nosuch", new AuthenticatorConfigRepresentation()); }, Resource.REALM, true); + } + + @Test + public void rolesById() { + invoke((realm) -> { realm.rolesById().getRole("nosuch"); }, Resource.REALM, false, true); + invoke((realm) -> { realm.rolesById().updateRole("nosuch", new RoleRepresentation()); }, Resource.REALM, true); + invoke((realm) -> { realm.rolesById().deleteRole("nosuch"); }, Resource.REALM, true); + invoke((realm) -> { realm.rolesById().getRoleComposites("nosuch"); }, Resource.REALM, false, true); + invoke((realm) -> { realm.rolesById().addComposites("nosuch", Collections.emptyList()); }, Resource.REALM, true); + invoke((realm) -> { realm.rolesById().deleteComposites("nosuch", Collections.emptyList()); }, Resource.REALM, true); + invoke((realm) -> { realm.rolesById().getRoleComposites("nosuch"); }, Resource.REALM, false, true); + invoke((realm) -> { realm.rolesById().getRealmRoleComposites("nosuch"); }, Resource.REALM, false, true); + invoke((realm) -> { realm.rolesById().getClientRoleComposites("nosuch", "nosuch"); }, Resource.REALM, false, true); + } + + @Test + public void groups() { + invoke((realm) -> { realm.groups().groups(); }, Resource.USER, false); + invoke((realm, response) -> { response.set(realm.groups().add(new GroupRepresentation())); }, Resource.USER, true); + + invoke((realm) -> { realm.groups().group("nosuch").toRepresentation(); }, Resource.USER, false); + invoke((realm) -> { realm.groups().group("nosuch").update(new GroupRepresentation()); }, Resource.USER, true); + invoke((realm) -> { realm.groups().group("nosuch").remove(); }, Resource.USER, true); + invoke((realm) -> { realm.groups().group("nosuch").members(0, 100); }, Resource.USER, false); + invoke((realm, response) -> { response.set(realm.groups().group("nosuch").subGroup(new GroupRepresentation())); }, Resource.USER, true); + + invoke((realm) -> { realm.groups().group("nosuch").roles().getAll(); }, Resource.USER, false); + invoke((realm) -> { realm.groups().group("nosuch").roles().realmLevel().listAll(); }, Resource.USER, false); + invoke((realm) -> { realm.groups().group("nosuch").roles().realmLevel().listEffective(); }, Resource.USER, false); + invoke((realm) -> { realm.groups().group("nosuch").roles().realmLevel().listAvailable(); }, Resource.USER, false); + invoke((realm) -> { realm.groups().group("nosuch").roles().realmLevel().add(Collections.emptyList()); }, Resource.USER, true); + invoke((realm) -> { realm.groups().group("nosuch").roles().realmLevel().remove(Collections.emptyList()); }, Resource.USER, true); + invoke((realm) -> { realm.groups().group("nosuch").roles().clientLevel("nosuch").listAll(); }, Resource.USER, false); + invoke((realm) -> { realm.groups().group("nosuch").roles().clientLevel("nosuch").listEffective(); }, Resource.USER, false); + invoke((realm) -> { realm.groups().group("nosuch").roles().clientLevel("nosuch").listAvailable(); }, Resource.USER, false); + invoke((realm) -> { realm.groups().group("nosuch").roles().clientLevel("nosuch").add(Collections.emptyList()); }, Resource.USER, true); + invoke((realm) -> { realm.groups().group("nosuch").roles().clientLevel("nosuch").remove(Collections.emptyList()); }, Resource.USER, true); + } + + // Permissions for impersonation tested in ImpersonationTest + @Test + public void users() { + invoke((realm) -> { realm.users().get("nosuch").toRepresentation(); }, Resource.USER, false); + invoke((realm, response) -> { response.set(realm.users().create(UserBuilder.create().username("testuser").build())); }, Resource.USER, true); + invoke((realm) -> { realm.users().get("nosuch").update(UserBuilder.create().enabled(true).build()); }, Resource.USER, true); + invoke((realm) -> { realm.users().search("foo", 0, 1); }, Resource.USER, false); + invoke((realm) -> { realm.users().count(); }, Resource.USER, false); + invoke((realm) -> { realm.users().get("nosuch").getUserSessions(); }, Resource.USER, false); + invoke((realm) -> { realm.users().get("nosuch").getOfflineSessions("nosuch"); }, Resource.USER, false); + invoke((realm) -> { realm.users().get("nosuch").getFederatedIdentity(); }, Resource.USER, false); + invoke((realm, response) -> { response.set(realm.users().get("nosuch").addFederatedIdentity("nosuch", FederatedIdentityBuilder.create().identityProvider("nosuch").userId("nosuch").userName("nosuch").build())); }, Resource.USER, true); + invoke((realm) -> { realm.users().get("nosuch").removeFederatedIdentity("nosuch"); }, Resource.USER, true); + invoke((realm) -> { realm.users().get("nosuch").getConsents(); }, Resource.USER, false); + invoke((realm) -> { realm.users().get("nosuch").revokeConsent("testclient"); }, Resource.USER, true); + invoke((realm) -> { realm.users().get("nosuch").logout(); }, Resource.USER, true); + invoke((realm) -> { realm.users().get("nosuch").remove(); }, Resource.USER, true); + invoke((realm) -> { realm.users().get("nosuch").resetPassword(CredentialBuilder.create().password("password").build()); }, Resource.USER, true); + invoke((realm) -> { realm.users().get("nosuch").removeTotp(); }, Resource.USER, true); + invoke((realm) -> { realm.users().get("nosuch").resetPasswordEmail(); }, Resource.USER, true); + invoke((realm) -> { realm.users().get("nosuch").executeActionsEmail(Collections.emptyList()); }, Resource.USER, true); + invoke((realm) -> { realm.users().get("nosuch").sendVerifyEmail(); }, Resource.USER, true); + invoke((realm) -> { realm.users().get("nosuch").groups(); }, Resource.USER, false); + invoke((realm) -> { realm.users().get("nosuch").leaveGroup("nosuch"); }, Resource.USER, true); + invoke((realm) -> { realm.users().get("nosuch").joinGroup("nosuch"); }, Resource.USER, true); + + invoke((realm) -> { realm.users().get("nosuch").roles().getAll(); }, Resource.USER, false); + invoke((realm) -> { realm.users().get("nosuch").roles().realmLevel().listAll(); }, Resource.USER, false); + invoke((realm) -> { realm.users().get("nosuch").roles().realmLevel().listAvailable(); }, Resource.USER, false); + invoke((realm) -> { realm.users().get("nosuch").roles().realmLevel().listEffective(); }, Resource.USER, false); + invoke((realm) -> { realm.users().get("nosuch").roles().realmLevel().add(Collections.emptyList()); }, Resource.USER, true); + invoke((realm) -> { realm.users().get("nosuch").roles().realmLevel().remove(Collections.emptyList()); }, Resource.USER, true); + + invoke((realm) -> { realm.users().get("nosuch").roles().clientLevel("nosuch").listAll(); }, Resource.USER, false); + invoke((realm) -> { realm.users().get("nosuch").roles().clientLevel("nosuch").listAvailable(); }, Resource.USER, false); + invoke((realm) -> { realm.users().get("nosuch").roles().clientLevel("nosuch").listEffective(); }, Resource.USER, false); + invoke((realm) -> { realm.users().get("nosuch").roles().clientLevel("nosuch").add(Collections.emptyList()); }, Resource.USER, true); + invoke((realm) -> { realm.users().get("nosuch").roles().clientLevel("nosuch").remove(Collections.emptyList()); }, Resource.USER, true); + } + + @Test + public void identityProviders() { + invoke((realm) -> { realm.identityProviders().findAll(); }, Resource.IDENTITY_PROVIDER, false); + invoke((realm, response) -> { response.set(realm.identityProviders().create(IdentityProviderBuilder.create().providerId("nosuch").alias("foo").build())); }, Resource.IDENTITY_PROVIDER, true); + + invoke((realm) -> { realm.identityProviders().get("nosuch").toRepresentation(); }, Resource.IDENTITY_PROVIDER, false); + invoke((realm) -> { realm.identityProviders().get("nosuch").update(new IdentityProviderRepresentation()); }, Resource.IDENTITY_PROVIDER, true); + invoke((realm, response) -> { response.set(realm.identityProviders().get("nosuch").export("saml")); }, Resource.IDENTITY_PROVIDER, false); + invoke((realm) -> { realm.identityProviders().get("nosuch").remove(); }, Resource.IDENTITY_PROVIDER, true); + + // TODO Mappers + // TODO importFrom + } + + @Test + public void userFederation() { + invoke((realm) -> { realm.userFederation().getProviderInstances(); }, Resource.USER, false); + invoke((realm) -> { realm.userFederation().getProviderFactories(); }, Resource.USER, false); + invoke((realm) -> { realm.userFederation().getProviderFactory("nosuch"); }, Resource.USER, false); + + UserFederationProviderRepresentation rep = new UserFederationProviderRepresentation(); + rep.setProviderName("ldap"); + invoke((realm, response) -> { response.set(realm.userFederation().create(rep)); }, Resource.USER, true); + invoke((realm) -> { realm.userFederation().get("nosuch").toRepresentation(); }, Resource.USER, false); + invoke((realm) -> { realm.userFederation().get("nosuch").update(new UserFederationProviderRepresentation()); }, Resource.USER, true); + invoke((realm) -> { realm.userFederation().get("nosuch").remove(); }, Resource.USER, true); + invoke((realm) -> { realm.userFederation().get("nosuch").syncUsers("nosuch"); }, Resource.USER, true); + invoke((realm) -> { realm.userFederation().get("nosuch").getMapperTypes(); }, Resource.USER, false); + invoke((realm) -> { realm.userFederation().get("nosuch").getMappers(); }, Resource.USER, false); + invoke((realm, response) -> { response.set(realm.userFederation().get("nosuch").addMapper(new UserFederationMapperRepresentation())); }, Resource.USER, true); + invoke((realm) -> { realm.userFederation().get("nosuch").getMapperById("nosuch"); }, Resource.USER, false); + invoke((realm) -> { realm.userFederation().get("nosuch").syncMapperData("nosuch", "nosuch"); }, Resource.USER, true); + } + + private void invoke(Invocation invocation, Resource resource, boolean manage) { + invoke((realm, response) -> { invocation.invoke(realm); }, resource, manage); + } + + private void invoke(Invocation invocation, Resource resource, boolean manage, boolean skipDifferentRole) { + invoke((realm, response) -> { invocation.invoke(realm); }, resource, manage, skipDifferentRole); + } + + private void invoke(InvocationWithResponse invocation, Resource resource, boolean manage) { + invoke(invocation, resource, manage, false); + } + + private void invoke(InvocationWithResponse invocation, Resource resource, boolean manage, boolean skipDifferentRole) { + String viewRole = getViewRole(resource); + String manageRole = getManageRole(resource); + String differentViewRole = getDifferentViewRole(resource); + String differentManageRole = getDifferentManageRole(resource); + + invoke(invocation, clients.get("master-none"), false); + invoke(invocation, clients.get("master-admin"), true); + invoke(invocation, clients.get("master-" + viewRole), !manage); + invoke(invocation, clients.get("master-" + manageRole), true); + if (!skipDifferentRole) { + invoke(invocation, clients.get("master-" + differentViewRole), false); + invoke(invocation, clients.get("master-" + differentManageRole), false); + } + + invoke(invocation, clients.get("none"), false); + invoke(invocation, clients.get(AdminRoles.REALM_ADMIN), true); + invoke(invocation, clients.get(viewRole), !manage); + invoke(invocation, clients.get(manageRole), true); + if (!skipDifferentRole) { + invoke(invocation, clients.get(differentViewRole), false); + invoke(invocation, clients.get(differentManageRole), false); + } + + invoke(invocation, clients.get("REALM2"), false); + } + + private void invoke(Invocation invocation, Keycloak client, boolean expectSuccess) { + invoke((realm, response) -> { invocation.invoke(realm); }, client, expectSuccess); + } + + private void invoke(InvocationWithResponse invocation, Keycloak client, boolean expectSuccess) { + int statusCode; + try { + AtomicReference responseReference = new AtomicReference<>(); + invocation.invoke(client.realm(REALM_NAME), responseReference); + Response response = responseReference.get(); + if (response != null) { + statusCode = response.getStatus(); + } else { + // OK (we don't care about the exact status code + statusCode = 200; + } + } catch (ClientErrorException e) { + statusCode = e.getResponse().getStatus(); + } + + if (expectSuccess) { + if (!(statusCode == 200 || statusCode == 201 || statusCode == 204 || statusCode == 404 || statusCode == 409 || statusCode == 400)) { + fail("Expected permitted, but was " + statusCode); + } + } else { + if (statusCode != 403) { + fail("Expected 403, but was " + statusCode); + } + } + } + + private String getViewRole(Resource resource) { + switch (resource) { + case CLIENT: + return AdminRoles.VIEW_CLIENTS; + case USER: + return AdminRoles.VIEW_USERS; + case REALM: + return AdminRoles.VIEW_REALM; + case EVENTS: + return AdminRoles.VIEW_EVENTS; + case IDENTITY_PROVIDER: + return AdminRoles.VIEW_IDENTITY_PROVIDERS; + default: + throw new RuntimeException("Unexpected resouce"); + } + } + + private String getManageRole(Resource resource) { + switch (resource) { + case CLIENT: + return AdminRoles.MANAGE_CLIENTS; + case USER: + return AdminRoles.MANAGE_USERS; + case REALM: + return AdminRoles.MANAGE_REALM; + case EVENTS: + return AdminRoles.MANAGE_EVENTS; + case IDENTITY_PROVIDER: + return AdminRoles.MANAGE_IDENTITY_PROVIDERS; + default: + throw new RuntimeException("Unexpected resouce"); + } + } + + private String getDifferentViewRole(Resource resource) { + switch (resource) { + case CLIENT: + return AdminRoles.VIEW_USERS; + case USER: + return AdminRoles.VIEW_CLIENTS; + case REALM: + return AdminRoles.VIEW_EVENTS; + case EVENTS: + return AdminRoles.VIEW_IDENTITY_PROVIDERS; + case IDENTITY_PROVIDER: + return AdminRoles.VIEW_REALM; + default: + throw new RuntimeException("Unexpected resouce"); + } + } + + private String getDifferentManageRole(Resource resource) { + switch (resource) { + case CLIENT: + return AdminRoles.MANAGE_USERS; + case USER: + return AdminRoles.MANAGE_CLIENTS; + case REALM: + return AdminRoles.MANAGE_EVENTS; + case EVENTS: + return AdminRoles.MANAGE_IDENTITY_PROVIDERS; + case IDENTITY_PROVIDER: + return AdminRoles.MANAGE_REALM; + default: + throw new RuntimeException("Unexpected resouce"); + } + } + + public interface Invocation { + + void invoke(RealmResource realm); + + } + + public interface InvocationWithResponse { + + void invoke(RealmResource realm, AtomicReference response); + + } + + private void assertGettersEmpty(RealmRepresentation rep) { + assertGettersEmpty(rep, "getRealm"); + } + + private void assertGettersEmpty(ClientRepresentation rep) { + assertGettersEmpty(rep, "getId", "getClientId", "getDescription"); + } + + private void assertGettersEmpty(Object rep, String... ignore) { + List ignoreList = Arrays.asList(ignore); + + for (Method m : rep.getClass().getDeclaredMethods()) { + if (m.getParameters().length == 0 && m.getName().startsWith("get") && !ignoreList.contains(m.getName())) { + try { + Object o = m.invoke(rep); + assertNull("Expected " + m.getName() + " to be null", o); + } catch (Exception e) { + fail(e.getMessage()); + } + } + } + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/FederatedIdentityBuilder.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/FederatedIdentityBuilder.java new file mode 100644 index 0000000000..2374f7fddb --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/FederatedIdentityBuilder.java @@ -0,0 +1,58 @@ +/* + * Copyright 2016 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.util; + +import org.keycloak.representations.idm.FederatedIdentityRepresentation; +import org.keycloak.services.util.P3PHelper; + +/** + * @author Stian Thorgersen + */ +public class FederatedIdentityBuilder { + + private final FederatedIdentityRepresentation rep; + + public static FederatedIdentityBuilder create() { + FederatedIdentityRepresentation rep = new FederatedIdentityRepresentation(); + return new FederatedIdentityBuilder(rep); + } + + private FederatedIdentityBuilder(FederatedIdentityRepresentation rep) { + this.rep = rep; + } + + public FederatedIdentityBuilder identityProvider(String identityProvider) { + rep.setIdentityProvider(identityProvider); + return this; + } + + public FederatedIdentityBuilder userId(String userId) { + rep.setUserId(userId); + return this; + } + + public FederatedIdentityBuilder userName(String userName) { + rep.setUserName(userName); + return this; + } + + public FederatedIdentityRepresentation build() { + return rep; + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/IdentityProviderBuilder.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/IdentityProviderBuilder.java new file mode 100644 index 0000000000..bc3dae6d04 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/IdentityProviderBuilder.java @@ -0,0 +1,51 @@ +/* + * Copyright 2016 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.util; + +import org.keycloak.representations.idm.IdentityProviderRepresentation; + +/** + * @author Stian Thorgersen + */ +public class IdentityProviderBuilder { + + private IdentityProviderRepresentation rep = new IdentityProviderRepresentation(); + + public static IdentityProviderBuilder create() { + return new IdentityProviderBuilder(); + } + + private IdentityProviderBuilder() { + rep.setEnabled(true); + } + + public IdentityProviderBuilder alias(String alias) { + rep.setAlias(alias); + return this; + } + + public IdentityProviderBuilder providerId(String providerId) { + rep.setProviderId(providerId); + return this; + } + + public IdentityProviderRepresentation build() { + return rep; + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmBuilder.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmBuilder.java index 0283b65710..3d322b3732 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmBuilder.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/RealmBuilder.java @@ -20,8 +20,15 @@ package org.keycloak.testsuite.util; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import sun.security.krb5.Realm; +import java.util.HashMap; import java.util.LinkedList; +import java.util.Map; + +import static org.keycloak.testsuite.util.MailServerConfiguration.FROM; +import static org.keycloak.testsuite.util.MailServerConfiguration.HOST; +import static org.keycloak.testsuite.util.MailServerConfiguration.PORT; /** * @author Stian Thorgersen @@ -59,6 +66,15 @@ public class RealmBuilder { return this; } + public RealmBuilder testMail() { + Map config = new HashMap<>(); + config.put("from", MailServerConfiguration.FROM); + config.put("host", MailServerConfiguration.HOST); + config.put("port", MailServerConfiguration.PORT); + rep.setSmtpServer(config); + return this; + } + public RealmBuilder testEventListener() { if (rep.getEventsListeners() == null) { rep.setEventsListeners(new LinkedList());