KEYCLOAK-2880 Permissions tests for admin endpoints

This commit is contained in:
Stian Thorgersen 2016-04-29 08:29:44 +02:00
parent 7796bf3510
commit 2355db57da
32 changed files with 1228 additions and 52 deletions

View file

@ -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<UserRepresentation> users;
protected List<GroupRepresentation> groups;
protected List<ClientRepresentation> 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() {

View file

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

View file

@ -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<UserSessionRepresentation> getUserSessions(@QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResults);
@Path("offline-session-count")
@GET
@Produces(MediaType.APPLICATION_JSON)
Map<String, Long> getOfflineSessionCount();
@Path("offline-sessions")
@GET
@Produces(MediaType.APPLICATION_JSON)
List<UserSessionRepresentation> 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<String, String> formParams);
@Path("nodes/{node}")
@DELETE
void unregisterNode(final @PathParam("node") String node);
@Path("test-nodes-available")
@GET
GlobalRequestResult testNodesAvailable();
}

View file

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

View file

@ -118,6 +118,10 @@ public interface UserResource {
@Path("sessions")
public List<UserSessionRepresentation> getUserSessions();
@GET
@Path("offline-sessions/{clientId}")
List<UserSessionRepresentation> getOfflineSessions(@PathParam("clientId") String clientId);
@GET
@Path("federated-identity")
public List<FederatedIdentityRepresentation> getFederatedIdentity();

View file

@ -727,7 +727,7 @@ public class AuthenticationManagementResource {
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public List<Map<String, String>> getUnregisteredRequiredActions() {
auth.requireManage();
auth.requireView();
List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(RequiredActionProvider.class);
List<Map<String, String>> unregisteredList = new LinkedList<>();

View file

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

View file

@ -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<String, Long> getApplicationSessionCount() {
auth.requireView();
if (client == null) {
throw new NotFoundException("Could not find client");
}
Map<String, Long> map = new HashMap<>();
map.put("count", session.sessions().getActiveUserSessions(client.getRealm(), client));
return map;
@ -339,6 +379,10 @@ public class ClientResource {
public List<UserSessionRepresentation> 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<UserSessionRepresentation> sessions = new ArrayList<UserSessionRepresentation>();
@ -367,6 +411,10 @@ public class ClientResource {
public Map<String, Long> getOfflineSessionCount() {
auth.requireView();
if (client == null) {
throw new NotFoundException("Could not find client");
}
Map<String, Long> map = new HashMap<>();
map.put("count", session.sessions().getOfflineSessionsCount(client.getRealm(), client));
return map;
@ -388,6 +436,10 @@ public class ClientResource {
public List<UserSessionRepresentation> 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<UserSessionRepresentation> sessions = new ArrayList<UserSessionRepresentation>();
@ -422,6 +474,10 @@ public class ClientResource {
public void registerNode(Map<String, String> 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);

View file

@ -83,6 +83,10 @@ public class ClientRoleMappingsResource {
public List<RoleRepresentation> getClientRoleMappings() {
auth.requireView();
if (user == null || client == null) {
throw new NotFoundException("Not found");
}
Set<RoleModel> mappings = user.getClientRoleMappings(client);
List<RoleRepresentation> mapRep = new ArrayList<RoleRepresentation>();
for (RoleModel roleModel : mappings) {
@ -105,6 +109,10 @@ public class ClientRoleMappingsResource {
public List<RoleRepresentation> getCompositeClientRoleMappings() {
auth.requireView();
if (user == null || client == null) {
throw new NotFoundException("Not found");
}
Set<RoleModel> roles = client.getRoles();
List<RoleRepresentation> mapRep = new ArrayList<RoleRepresentation>();
for (RoleModel roleModel : roles) {
@ -125,6 +133,10 @@ public class ClientRoleMappingsResource {
public List<RoleRepresentation> getAvailableClientRoleMappings() {
auth.requireView();
if (user == null || client == null) {
throw new NotFoundException("Not found");
}
Set<RoleModel> available = client.getRoles();
return getAvailableRoles(user, available);
}
@ -153,6 +165,10 @@ public class ClientRoleMappingsResource {
public void addClientRoleMapping(List<RoleRepresentation> 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<RoleRepresentation> roles) {
auth.requireManage();
if (user == null || client == null) {
throw new NotFoundException("Not found");
}
if (roles == null) {
Set<RoleModel> roleModels = user.getClientRoleMappings(client);
for (RoleModel roleModel : roleModels) {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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();
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) {
try {
this.auth.requireView();
if (identityProviderModel == null) {
throw new javax.ws.rs.NotFoundException();
}
try {
IdentityProviderFactory factory = getIdentityProviderFactory();
return factory.create(identityProviderModel).export(uriInfo, realm, format);
} catch (Exception e) {
@ -224,6 +242,11 @@ public class IdentityProviderResource {
@NoCache
public Map<String, IdentityProviderMapperTypeRepresentation> getMapperTypes() {
this.auth.requireView();
if (identityProviderModel == null) {
throw new javax.ws.rs.NotFoundException();
}
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
Map<String, IdentityProviderMapperTypeRepresentation> types = new HashMap<>();
List<ProviderFactory> factories = sessionFactory.getProviderFactories(IdentityProviderMapper.class);
@ -263,6 +286,11 @@ public class IdentityProviderResource {
@NoCache
public List<IdentityProviderMapperRepresentation> getMappers() {
this.auth.requireView();
if (identityProviderModel == null) {
throw new javax.ws.rs.NotFoundException();
}
List<IdentityProviderMapperRepresentation> 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);

View file

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

View file

@ -88,6 +88,10 @@ public class ProtocolMappersResource {
public List<ProtocolMapperRepresentation> getMappersPerProtocol(@PathParam("protocol") String protocol) {
auth.requireAny();
if (client == null) {
throw new NotFoundException("Could not find client");
}
List<ProtocolMapperRepresentation> mappers = new LinkedList<ProtocolMapperRepresentation>();
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<ProtocolMapperRepresentation> 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<ProtocolMapperRepresentation> getMappers() {
auth.requireAny();
if (client == null) {
throw new NotFoundException("Could not find client");
}
List<ProtocolMapperRepresentation> mappers = new LinkedList<ProtocolMapperRepresentation>();
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);

View file

@ -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<ClientDescriptionConverter> factory : session.getKeycloakSessionFactory().getProviderFactories(ClientDescriptionConverter.class)) {
if (((ClientDescriptionConverterFactory) factory).isSupported(description)) {

View file

@ -110,7 +110,11 @@ public class RealmsAdminResource {
}
protected void addRealmRep(List<RealmRepresentation> 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();

View file

@ -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<RoleRepresentation> getRoles() {
auth.requireAny();
if (roleContainer == null) {
throw new NotFoundException("Could not find client");
}
Set<RoleModel> roleModels = roleContainer.getRoles();
List<RoleRepresentation> roles = new ArrayList<RoleRepresentation>();
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<RoleRepresentation> 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<RoleRepresentation> 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<RoleRepresentation> 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<RoleRepresentation> 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<RoleRepresentation> 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");

View file

@ -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<RoleModel> realmMappings = roleMapper.getRealmRoleMappings();
RealmManager manager = new RealmManager(session);
@ -149,6 +153,10 @@ public class RoleMapperResource {
public List<RoleRepresentation> getRealmRoleMappings() {
auth.requireView();
if (roleMapper == null) {
throw new NotFoundException("User not found");
}
Set<RoleModel> realmMappings = roleMapper.getRealmRoleMappings();
List<RoleRepresentation> realmMappingsRep = new ArrayList<RoleRepresentation>();
for (RoleModel roleModel : realmMappings) {
@ -171,6 +179,10 @@ public class RoleMapperResource {
public List<RoleRepresentation> getCompositeRealmRoleMappings() {
auth.requireView();
if (roleMapper == null) {
throw new NotFoundException("User not found");
}
Set<RoleModel> roles = realm.getRoles();
List<RoleRepresentation> realmMappingsRep = new ArrayList<RoleRepresentation>();
for (RoleModel roleModel : roles) {
@ -193,6 +205,10 @@ public class RoleMapperResource {
public List<RoleRepresentation> getAvailableRealmRoleMappings() {
auth.requireView();
if (roleMapper == null) {
throw new NotFoundException("User not found");
}
Set<RoleModel> available = realm.getRoles();
return ClientRoleMappingsResource.getAvailableRoles(roleMapper, available);
}
@ -208,6 +224,10 @@ public class RoleMapperResource {
public void addRealmRoleMappings(List<RoleRepresentation> 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<RoleRepresentation> roles) {
auth.requireManage();
if (roleMapper == null) {
throw new NotFoundException("User not found");
}
logger.debug("deleteRealmRoleMappings");
if (roles == null) {
Set<RoleModel> 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);
}

View file

@ -75,6 +75,10 @@ public class ScopeMappedClientResource {
public List<RoleRepresentation> getClientScopeMappings() {
auth.requireView();
if (scopeContainer == null) {
throw new NotFoundException("Could not find client");
}
Set<RoleModel> mappings = KeycloakModelUtils.getClientScopeMappings(scopedClient, scopeContainer); //scopedClient.getClientScopeMappings(client);
List<RoleRepresentation> mapRep = new ArrayList<RoleRepresentation>();
for (RoleModel roleModel : mappings) {
@ -97,6 +101,10 @@ public class ScopeMappedClientResource {
public List<RoleRepresentation> getAvailableClientScopeMappings() {
auth.requireView();
if (scopeContainer == null) {
throw new NotFoundException("Could not find client");
}
Set<RoleModel> roles = scopedClient.getRoles();
return ScopeMappedResource.getAvailable(scopeContainer, roles);
}
@ -115,6 +123,10 @@ public class ScopeMappedClientResource {
public List<RoleRepresentation> getCompositeClientScopeMappings() {
auth.requireView();
if (scopeContainer == null) {
throw new NotFoundException("Could not find client");
}
Set<RoleModel> roles = scopedClient.getRoles();
return ScopeMappedResource.getComposite(scopeContainer, roles);
}
@ -129,6 +141,10 @@ public class ScopeMappedClientResource {
public void addClientScopeMapping(List<RoleRepresentation> 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<RoleRepresentation> roles) {
auth.requireManage();
if (scopeContainer == null) {
throw new NotFoundException("Could not find client");
}
if (roles == null) {
Set<RoleModel> roleModels = KeycloakModelUtils.getClientScopeMappings(scopedClient, scopeContainer);//scopedClient.getClientScopeMappings(client);
for (RoleModel roleModel : roleModels) {

View file

@ -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<RoleModel> realmMappings = scopeContainer.getRealmScopeMappings();
if (realmMappings.size() > 0) {
@ -122,6 +126,10 @@ public class ScopeMappedResource {
public List<RoleRepresentation> getRealmScopeMappings() {
auth.requireView();
if (scopeContainer == null) {
throw new NotFoundException("Could not find client");
}
Set<RoleModel> realmMappings = scopeContainer.getRealmScopeMappings();
List<RoleRepresentation> realmMappingsRep = new ArrayList<RoleRepresentation>();
for (RoleModel roleModel : realmMappings) {
@ -142,6 +150,10 @@ public class ScopeMappedResource {
public List<RoleRepresentation> getAvailableRealmScopeMappings() {
auth.requireView();
if (scopeContainer == null) {
throw new NotFoundException("Could not find client");
}
Set<RoleModel> roles = realm.getRoles();
return getAvailable(scopeContainer, roles);
}
@ -171,6 +183,10 @@ public class ScopeMappedResource {
public List<RoleRepresentation> getCompositeRealmScopeMappings() {
auth.requireView();
if (scopeContainer == null) {
throw new NotFoundException("Could not find client");
}
Set<RoleModel> roles = realm.getRoles();
return getComposite(scopeContainer, roles);
}
@ -194,6 +210,10 @@ public class ScopeMappedResource {
public void addRealmScopeMappings(List<RoleRepresentation> 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<RoleRepresentation> roles) {
auth.requireManage();
if (scopeContainer == null) {
throw new NotFoundException("Could not find client");
}
if (roles == null) {
Set<RoleModel> 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);
}
}

View file

@ -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<String, UserFederationMapperTypeRepresentation> getMapperTypes() {
auth.requireView();
if (federationProviderModel == null) {
throw new NotFoundException("Could not find federation provider");
}
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
Map<String, UserFederationMapperTypeRepresentation> types = new HashMap<>();
List<ProviderFactory> factories = sessionFactory.getProviderFactories(UserFederationMapper.class);
@ -234,6 +254,10 @@ public class UserFederationProviderResource {
public List<UserFederationMapperRepresentation> getMappers() {
auth.requireView();
if (federationProviderModel == null) {
throw new NotFoundException("Could not find federation provider");
}
List<UserFederationMapperRepresentation> 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());

View file

@ -227,7 +227,7 @@ public class UserFederationProvidersResource {
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public List<UserFederationProviderRepresentation> getUserFederationInstances() {
auth.requireManage();
auth.requireView();
List<UserFederationProviderRepresentation> reps = new LinkedList<UserFederationProviderRepresentation>();
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;

View file

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

View file

@ -100,6 +100,14 @@
<artifactId>xml-maven-plugin</artifactId>
<version>1.0.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>

View file

@ -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) {
try {
adminClient.realms().realm(realm.getRealm()).remove();
} catch (NotFoundException e) {
}
}
public RealmsResource realmsResouce() {

View file

@ -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 <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
public class PermissionsTest extends AbstractKeycloakTest {
private static final String REALM_NAME = "permissions-test";
private Map<String, Keycloak> clients = new HashMap<>();
@Rule
public GreenMailRule greenMailRule = new GreenMailRule();
@Override
public void addTestRealms(List<RealmRepresentation> 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<RealmRepresentation> 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<ClientRepresentation> 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<Response> 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> 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<String> 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());
}
}
}
}
}

View file

@ -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 <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
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;
}
}

View file

@ -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 <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
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;
}
}

View file

@ -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 <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@ -59,6 +66,15 @@ public class RealmBuilder {
return this;
}
public RealmBuilder testMail() {
Map<String, String> 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<String>());