KEYCLOAK-2491 Fix permissions in admin console to match permissions in admin endpoints

This commit is contained in:
Stian Thorgersen 2016-04-20 09:09:58 +02:00
parent b3d40c6f85
commit 04d76b0052
32 changed files with 206 additions and 75 deletions

View file

@ -80,7 +80,8 @@ public class AttackDetectionResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public Map<String, Object> bruteForceUserStatus(@PathParam("username") String username) {
auth.hasView();
auth.requireView();
Map<String, Object> data = new HashMap<>();
data.put("disabled", false);
data.put("numFailures", 0);
@ -110,6 +111,7 @@ public class AttackDetectionResource {
@DELETE
public void clearBruteForceForUser(@PathParam("username") String username) {
auth.requireManage();
UsernameLoginFailureModel model = session.sessions().getUserLoginFailure(realm, username.toLowerCase());
if (model != null) {
session.sessions().removeUserLoginFailure(realm, username);
@ -127,6 +129,7 @@ public class AttackDetectionResource {
@DELETE
public void clearAllBruteForce() {
auth.requireManage();
session.sessions().removeAllUserLoginFailures(realm);
adminEvent.operation(OperationType.DELETE).success();
}

View file

@ -101,7 +101,8 @@ public class AuthenticationManagementResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public List<Map<String, Object>> getFormProviders() {
this.auth.requireView();
auth.requireView();
List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(FormAuthenticator.class);
return buildProviderMetadata(factories);
}
@ -116,7 +117,8 @@ public class AuthenticationManagementResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public List<Map<String, Object>> getAuthenticatorProviders() {
this.auth.requireView();
auth.requireView();
List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(Authenticator.class);
return buildProviderMetadata(factories);
}
@ -131,7 +133,8 @@ public class AuthenticationManagementResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public List<Map<String, Object>> getClientAuthenticatorProviders() {
this.auth.requireView();
auth.requireAny();
List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(ClientAuthenticator.class);
return buildProviderMetadata(factories);
}
@ -160,7 +163,8 @@ public class AuthenticationManagementResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public List<Map<String, Object>> getFormActionProviders() {
this.auth.requireView();
auth.requireView();
List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(FormAction.class);
return buildProviderMetadata(factories);
}
@ -176,7 +180,8 @@ public class AuthenticationManagementResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public List<AuthenticationFlowRepresentation> getFlows() {
this.auth.requireView();
auth.requireAny();
List<AuthenticationFlowRepresentation> flows = new LinkedList<>();
for (AuthenticationFlowModel flow : realm.getAuthenticationFlows()) {
if (flow.isTopLevel()) {
@ -197,7 +202,7 @@ public class AuthenticationManagementResource {
@NoCache
@Consumes(MediaType.APPLICATION_JSON)
public Response createFlow(AuthenticationFlowRepresentation flow) {
this.auth.requireManage();
auth.requireManage();
if (flow.getAlias() == null || flow.getAlias().isEmpty()) {
return ErrorResponse.exists("Failed to create flow with empty alias name");
@ -222,7 +227,7 @@ public class AuthenticationManagementResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public AuthenticationFlowRepresentation getFlow(@PathParam("id") String id) {
this.auth.requireView();
auth.requireView();
AuthenticationFlowModel flow = realm.getAuthenticationFlowById(id);
if (flow == null) {
@ -240,7 +245,7 @@ public class AuthenticationManagementResource {
@DELETE
@NoCache
public void deleteFlow(@PathParam("id") String id) {
this.auth.requireView();
auth.requireManage();
AuthenticationFlowModel flow = realm.getAuthenticationFlowById(id);
if (flow == null) {
@ -273,7 +278,7 @@ public class AuthenticationManagementResource {
@NoCache
@Consumes(MediaType.APPLICATION_JSON)
public Response copy(@PathParam("flowAlias") String flowAlias, Map<String, String> data) {
this.auth.requireManage();
auth.requireManage();
String newName = data.get("newName");
if (realm.getFlowByAlias(newName) != null) {
@ -329,7 +334,7 @@ public class AuthenticationManagementResource {
@NoCache
@Consumes(MediaType.APPLICATION_JSON)
public void addExecutionFlow(@PathParam("flowAlias") String flowAlias, Map<String, String> data) {
this.auth.requireManage();
auth.requireManage();
AuthenticationFlowModel parentFlow = realm.getFlowByAlias(flowAlias);
if (parentFlow == null) {
@ -377,7 +382,7 @@ public class AuthenticationManagementResource {
@NoCache
@Consumes(MediaType.APPLICATION_JSON)
public void addExecution(@PathParam("flowAlias") String flowAlias, Map<String, String> data) {
this.auth.requireManage();
auth.requireManage();
AuthenticationFlowModel parentFlow = realm.getFlowByAlias(flowAlias);
if (parentFlow == null) {
@ -419,7 +424,7 @@ public class AuthenticationManagementResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public Response getExecutions(@PathParam("flowAlias") String flowAlias) {
this.auth.requireView();
auth.requireView();
AuthenticationFlowModel flow = realm.getFlowByAlias(flowAlias);
if (flow == null) {
@ -495,7 +500,7 @@ public class AuthenticationManagementResource {
@NoCache
@Consumes(MediaType.APPLICATION_JSON)
public void updateExecutions(@PathParam("flowAlias") String flowAlias, AuthenticationExecutionInfoRepresentation rep) {
this.auth.requireManage();
auth.requireManage();
AuthenticationFlowModel flow = realm.getFlowByAlias(flowAlias);
if (flow == null) {
@ -525,7 +530,8 @@ public class AuthenticationManagementResource {
@NoCache
@Consumes(MediaType.APPLICATION_JSON)
public Response addExecution(AuthenticationExecutionRepresentation execution) {
this.auth.requireManage();
auth.requireManage();
AuthenticationExecutionModel model = RepresentationToModel.toModel(realm, execution);
AuthenticationFlowModel parentFlow = getParentFlow(model);
if (parentFlow.isBuiltIn()) {
@ -557,7 +563,7 @@ public class AuthenticationManagementResource {
@POST
@NoCache
public void raisePriority(@PathParam("executionId") String execution) {
this.auth.requireManage();
auth.requireManage();
AuthenticationExecutionModel model = realm.getAuthenticationExecutionById(execution);
if (model == null) {
@ -601,7 +607,7 @@ public class AuthenticationManagementResource {
@POST
@NoCache
public void lowerPriority(@PathParam("executionId") String execution) {
this.auth.requireManage();
auth.requireManage();
AuthenticationExecutionModel model = realm.getAuthenticationExecutionById(execution);
if (model == null) {
@ -639,7 +645,7 @@ public class AuthenticationManagementResource {
@DELETE
@NoCache
public void removeExecution(@PathParam("executionId") String execution) {
this.auth.requireManage();
auth.requireManage();
AuthenticationExecutionModel model = realm.getAuthenticationExecutionById(execution);
if (model == null) {
@ -673,7 +679,7 @@ public class AuthenticationManagementResource {
@NoCache
@Consumes(MediaType.APPLICATION_JSON)
public Response newExecutionConfig(@PathParam("executionId") String execution, AuthenticatorConfigRepresentation json) {
this.auth.requireManage();
auth.requireManage();
AuthenticationExecutionModel model = realm.getAuthenticationExecutionById(execution);
if (model == null) {
@ -699,7 +705,8 @@ public class AuthenticationManagementResource {
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public AuthenticatorConfigRepresentation getAuthenticatorConfig(@PathParam("executionId") String execution,@PathParam("id") String id) {
this.auth.requireView();
auth.requireView();
AuthenticatorConfigModel config = realm.getAuthenticatorConfigById(id);
if (config == null) {
throw new NotFoundException("Could not find authenticator config");
@ -718,6 +725,8 @@ public class AuthenticationManagementResource {
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public List<Map<String, String>> getUnregisteredRequiredActions() {
auth.requireManage();
List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(RequiredActionProvider.class);
List<Map<String, String>> unregisteredList = new LinkedList<>();
for (ProviderFactory factory : factories) {
@ -750,6 +759,8 @@ public class AuthenticationManagementResource {
@Consumes(MediaType.APPLICATION_JSON)
@NoCache
public void registereRequiredAction(Map<String, String> data) {
auth.requireManage();
String providerId = data.get("providerId");
String name = data.get("name");
RequiredActionProviderModel requiredAction = new RequiredActionProviderModel();
@ -772,6 +783,8 @@ public class AuthenticationManagementResource {
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public List<RequiredActionProviderRepresentation> getRequiredActions() {
auth.requireAny();
List<RequiredActionProviderRepresentation> list = new LinkedList<>();
for (RequiredActionProviderModel model : realm.getRequiredActionProviders()) {
RequiredActionProviderRepresentation rep = toRepresentation(model);
@ -799,6 +812,8 @@ public class AuthenticationManagementResource {
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public RequiredActionProviderRepresentation getRequiredAction(@PathParam("alias") String alias) {
auth.requireView();
RequiredActionProviderModel model = realm.getRequiredActionProviderByAlias(alias);
if (model == null) {
throw new NotFoundException("Failed to find required action");
@ -817,7 +832,8 @@ public class AuthenticationManagementResource {
@PUT
@Consumes(MediaType.APPLICATION_JSON)
public void updateRequiredAction(@PathParam("alias") String alias, RequiredActionProviderRepresentation rep) {
this.auth.requireManage();
auth.requireManage();
RequiredActionProviderModel model = realm.getRequiredActionProviderByAlias(alias);
if (model == null) {
throw new NotFoundException("Failed to find required action");
@ -840,7 +856,8 @@ public class AuthenticationManagementResource {
@Path("required-actions/{alias}")
@DELETE
public void updateRequiredAction(@PathParam("alias") String alias) {
this.auth.requireManage();
auth.requireManage();
RequiredActionProviderModel model = realm.getRequiredActionProviderByAlias(alias);
if (model == null) {
throw new NotFoundException("Failed to find required action.");
@ -856,7 +873,8 @@ public class AuthenticationManagementResource {
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public AuthenticatorConfigInfoRepresentation getAuthenticatorConfigDescription(@PathParam("providerId") String providerId) {
this.auth.requireView();
auth.requireView();
ConfigurableAuthenticatorFactory factory = CredentialHelper.getConfigurableAuthenticatorFactory(session, providerId);
if (factory == null) {
throw new NotFoundException("Could not find authenticator provider");
@ -892,7 +910,8 @@ public class AuthenticationManagementResource {
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public Map<String, List<ConfigPropertyRepresentation>> getPerClientConfigDescription() {
this.auth.requireView();
auth.requireAny();
List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(ClientAuthenticator.class);
Map<String, List<ConfigPropertyRepresentation>> toReturn = new HashMap<>();
@ -921,7 +940,8 @@ public class AuthenticationManagementResource {
@POST
@NoCache
public Response createAuthenticatorConfig(AuthenticatorConfigRepresentation rep) {
this.auth.requireManage();
auth.requireManage();
AuthenticatorConfigModel config = realm.addAuthenticatorConfig(RepresentationToModel.toModel(rep));
return Response.created(uriInfo.getAbsolutePathBuilder().path(config.getId()).build()).build();
}
@ -935,7 +955,8 @@ public class AuthenticationManagementResource {
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public AuthenticatorConfigRepresentation getAuthenticatorConfig(@PathParam("id") String id) {
this.auth.requireView();
auth.requireView();
AuthenticatorConfigModel config = realm.getAuthenticatorConfigById(id);
if (config == null) {
throw new NotFoundException("Could not find authenticator config");
@ -952,7 +973,8 @@ public class AuthenticationManagementResource {
@DELETE
@NoCache
public void removeAuthenticatorConfig(@PathParam("id") String id) {
this.auth.requireManage();
auth.requireManage();
AuthenticatorConfigModel config = realm.getAuthenticatorConfigById(id);
if (config == null) {
throw new NotFoundException("Could not find authenticator config");
@ -981,7 +1003,8 @@ public class AuthenticationManagementResource {
@Consumes(MediaType.APPLICATION_JSON)
@NoCache
public void updateAuthenticatorConfig(@PathParam("id") String id, AuthenticatorConfigRepresentation rep) {
this.auth.requireManage();
auth.requireManage();
AuthenticatorConfigModel exists = realm.getAuthenticatorConfigById(id);
if (exists == null) {
throw new NotFoundException("Could not find authenticator config");

View file

@ -91,6 +91,8 @@ public class ClientAttributeCertificateResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public CertificateRepresentation getKeyInfo() {
auth.requireView();
CertificateRepresentation info = new CertificateRepresentation();
info.setCertificate(client.getAttribute(certificateAttribute));
info.setPrivateKey(client.getAttribute(privateAttribute));
@ -132,6 +134,8 @@ public class ClientAttributeCertificateResource {
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public CertificateRepresentation uploadJks(@Context final UriInfo uriInfo, MultipartFormDataInput input) throws IOException {
auth.requireManage();
CertificateRepresentation info = getCertFromRequest(uriInfo, input);
if (info.getPrivateKey() != null) {
@ -163,6 +167,8 @@ public class ClientAttributeCertificateResource {
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public CertificateRepresentation uploadJksCertificate(@Context final UriInfo uriInfo, MultipartFormDataInput input) throws IOException {
auth.requireManage();
CertificateRepresentation info = getCertFromRequest(uriInfo, input);
if (info.getCertificate() != null) {
@ -239,6 +245,7 @@ public class ClientAttributeCertificateResource {
@Consumes(MediaType.APPLICATION_JSON)
public byte[] getKeystore(final KeyStoreConfig config) {
auth.requireView();
if (config.getFormat() != null && !config.getFormat().equals("JKS") && !config.getFormat().equals("PKCS12")) {
throw new NotAcceptableException("Only support jks or pkcs12 format.");
}

View file

@ -91,6 +91,8 @@ public class ClientInitialAccessResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<ClientInitialAccessPresentation> list() {
auth.requireView();
List<ClientInitialAccessModel> models = session.sessions().listClientInitialAccess(realm);
List<ClientInitialAccessPresentation> reps = new LinkedList<>();
for (ClientInitialAccessModel m : models) {
@ -103,6 +105,8 @@ public class ClientInitialAccessResource {
@DELETE
@Path("{id}")
public void delete(final @PathParam("id") String id) {
auth.requireManage();
session.sessions().removeClientInitialAccessModel(realm, id);
}

View file

@ -147,6 +147,7 @@ public class ClientResource {
@Produces(MediaType.APPLICATION_JSON)
public ClientRepresentation getClient() {
auth.requireView();
return ModelToRepresentation.toRepresentation(client);
}
@ -165,6 +166,8 @@ public class ClientResource {
@NoCache
@Path("installation/providers/{providerId}")
public Response getInstallationProvider(@PathParam("providerId") String providerId) {
auth.requireView();
ClientInstallationProvider provider = session.getProvider(ClientInstallationProvider.class, providerId);
if (provider == null) throw new NotFoundException("Unknown Provider");
return provider.generateInstallation(session, realm, client, keycloak.getBaseUri(uriInfo));
@ -178,6 +181,7 @@ public class ClientResource {
@NoCache
public void deleteClient() {
auth.requireManage();
new ClientManager(new RealmManager(session)).removeClient(realm, client);
adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
}
@ -290,6 +294,7 @@ public class ClientResource {
@POST
public GlobalRequestResult pushRevocation() {
auth.requireManage();
adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
return new ResourceAdminManager(session).pushClientRevocationPolicy(uriInfo.getRequestUri(), realm, client);
@ -312,6 +317,7 @@ public class ClientResource {
@Produces(MediaType.APPLICATION_JSON)
public Map<String, Long> getApplicationSessionCount() {
auth.requireView();
Map<String, Long> map = new HashMap<>();
map.put("count", session.sessions().getActiveUserSessions(client.getRealm(), client));
return map;
@ -332,6 +338,7 @@ public class ClientResource {
@Produces(MediaType.APPLICATION_JSON)
public List<UserSessionRepresentation> getUserSessions(@QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResults) {
auth.requireView();
firstResult = firstResult != null ? firstResult : -1;
maxResults = maxResults != null ? maxResults : -1;
List<UserSessionRepresentation> sessions = new ArrayList<UserSessionRepresentation>();
@ -359,6 +366,7 @@ public class ClientResource {
@Produces(MediaType.APPLICATION_JSON)
public Map<String, Long> getOfflineSessionCount() {
auth.requireView();
Map<String, Long> map = new HashMap<>();
map.put("count", session.sessions().getOfflineSessionsCount(client.getRealm(), client));
return map;
@ -379,6 +387,7 @@ public class ClientResource {
@Produces(MediaType.APPLICATION_JSON)
public List<UserSessionRepresentation> getOfflineUserSessions(@QueryParam("first") Integer firstResult, @QueryParam("max") Integer maxResults) {
auth.requireView();
firstResult = firstResult != null ? firstResult : -1;
maxResults = maxResults != null ? maxResults : -1;
List<UserSessionRepresentation> sessions = new ArrayList<UserSessionRepresentation>();
@ -412,6 +421,7 @@ public class ClientResource {
@Consumes(MediaType.APPLICATION_JSON)
public void registerNode(Map<String, String> formParams) {
auth.requireManage();
String node = formParams.get("node");
if (node == null) {
throw new BadRequestException("Node not found in params");
@ -431,6 +441,7 @@ public class ClientResource {
@NoCache
public void unregisterNode(final @PathParam("node") String node) {
auth.requireManage();
if (logger.isDebugEnabled()) logger.debug("Unregister node: " + node);
Integer time = client.getRegisteredNodes().get(node);
@ -453,6 +464,7 @@ public class ClientResource {
@NoCache
public GlobalRequestResult testNodesAvailable() {
auth.requireManage();
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

@ -123,6 +123,7 @@ public class ClientTemplateResource {
@Produces(MediaType.APPLICATION_JSON)
public ClientTemplateRepresentation getClient() {
auth.requireView();
return ModelToRepresentation.toRepresentation(template);
}
@ -134,6 +135,7 @@ public class ClientTemplateResource {
@NoCache
public void deleteClientTemplate() {
auth.requireManage();
realm.removeClientTemplate(template.getId());
adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
}

View file

@ -75,7 +75,7 @@ public class ClientTemplatesResource {
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public List<ClientTemplateRepresentation> getClientTemplates() {
auth.requireAny();
auth.requireView();
List<ClientTemplateRepresentation> rep = new ArrayList<>();
List<ClientTemplateModel> clientModels = realm.getClientTemplates();

View file

@ -69,7 +69,8 @@ public class GroupsResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public List<GroupRepresentation> getGroups() {
this.auth.requireView();
auth.requireView();
return ModelToRepresentation.toGroupHierarchy(realm, false);
}
@ -81,7 +82,8 @@ public class GroupsResource {
*/
@Path("{id}")
public GroupResource getGroupById(@PathParam("id") String id) {
this.auth.requireView();
auth.requireView();
GroupModel group = realm.getGroupById(id);
if (group == null) {
throw new NotFoundException("Could not find group by id");
@ -101,7 +103,8 @@ public class GroupsResource {
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response addTopLevelGroup(GroupRepresentation rep) {
this.auth.requireManage();
auth.requireManage();
GroupModel child = null;
Response.ResponseBuilder builder = Response.status(204);
if (rep.getId() != null) {

View file

@ -28,6 +28,7 @@ import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.services.ErrorResponse;
import org.keycloak.services.ServicesLogger;
import org.keycloak.services.resources.admin.RealmAuth.Resource;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
@ -71,7 +72,7 @@ public class ProtocolMappersResource {
this.client = client;
this.adminEvent = adminEvent;
auth.init(RealmAuth.Resource.USER);
auth.init(Resource.CLIENT);
}
/**
@ -85,7 +86,8 @@ public class ProtocolMappersResource {
@Path("protocol/{protocol}")
@Produces(MediaType.APPLICATION_JSON)
public List<ProtocolMapperRepresentation> getMappersPerProtocol(@PathParam("protocol") String protocol) {
auth.requireView();
auth.requireAny();
List<ProtocolMapperRepresentation> mappers = new LinkedList<ProtocolMapperRepresentation>();
for (ProtocolMapperModel mapper : client.getProtocolMappers()) {
if (mapper.getProtocol().equals(protocol)) mappers.add(ModelToRepresentation.toRepresentation(mapper));
@ -127,6 +129,7 @@ public class ProtocolMappersResource {
@Consumes(MediaType.APPLICATION_JSON)
public void createMapper(List<ProtocolMapperRepresentation> reps) {
auth.requireManage();
ProtocolMapperModel model = null;
for (ProtocolMapperRepresentation rep : reps) {
model = RepresentationToModel.toModel(rep);
@ -145,7 +148,8 @@ public class ProtocolMappersResource {
@Path("models")
@Produces(MediaType.APPLICATION_JSON)
public List<ProtocolMapperRepresentation> getMappers() {
auth.requireView();
auth.requireAny();
List<ProtocolMapperRepresentation> mappers = new LinkedList<ProtocolMapperRepresentation>();
for (ProtocolMapperModel mapper : client.getProtocolMappers()) {
mappers.add(ModelToRepresentation.toRepresentation(mapper));
@ -164,7 +168,8 @@ public class ProtocolMappersResource {
@Path("models/{id}")
@Produces(MediaType.APPLICATION_JSON)
public ProtocolMapperRepresentation getMapperById(@PathParam("id") String id) {
auth.requireView();
auth.requireAny();
ProtocolMapperModel model = client.getProtocolMapperById(id);
if (model == null) throw new NotFoundException("Model not found");
return ModelToRepresentation.toRepresentation(model);
@ -182,6 +187,7 @@ public class ProtocolMappersResource {
@Consumes(MediaType.APPLICATION_JSON)
public void update(@PathParam("id") String id, ProtocolMapperRepresentation rep) {
auth.requireManage();
ProtocolMapperModel model = client.getProtocolMapperById(id);
if (model == null) throw new NotFoundException("Model not found");
model = RepresentationToModel.toModel(rep);
@ -199,6 +205,7 @@ public class ProtocolMappersResource {
@Path("models/{id}")
public void delete(@PathParam("id") String id) {
auth.requireManage();
ProtocolMapperModel model = client.getProtocolMapperById(id);
if (model == null) throw new NotFoundException("Model not found");
client.removeProtocolMapper(model);

View file

@ -54,6 +54,7 @@ import org.keycloak.representations.idm.AdminEventRepresentation;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.EventRepresentation;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.representations.idm.PartialImportRepresentation;
import org.keycloak.representations.idm.RealmEventsConfigRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
@ -64,6 +65,7 @@ import org.keycloak.services.managers.ResourceAdminManager;
import org.keycloak.services.ServicesLogger;
import org.keycloak.services.managers.UsersSyncManager;
import org.keycloak.services.ErrorResponse;
import org.keycloak.services.resources.admin.RealmAuth.Resource;
import org.keycloak.timer.TimerProvider;
import javax.ws.rs.Consumes;
@ -127,6 +129,7 @@ public class RealmAdminResource {
this.adminEvent = adminEvent.realm(realm);
auth.init(RealmAuth.Resource.REALM);
auth.requireAny();
}
/**
@ -139,6 +142,8 @@ public class RealmAdminResource {
@POST
@Produces(MediaType.APPLICATION_JSON)
public ClientRepresentation convertClientDescription(String description) {
auth.requireManage();
for (ProviderFactory<ClientDescriptionConverter> factory : session.getKeycloakSessionFactory().getProviderFactories(ClientDescriptionConverter.class)) {
if (((ClientDescriptionConverterFactory) factory).isSupported(description)) {
return factory.create(session).convertToInternal(description);
@ -224,6 +229,13 @@ public class RealmAdminResource {
RealmRepresentation rep = new RealmRepresentation();
rep.setRealm(realm.getName());
if (auth.init(Resource.IDENTITY_PROVIDER).hasView()) {
RealmRepresentation r = ModelToRepresentation.toRepresentation(realm, false);
rep.setIdentityProviders(r.getIdentityProviders());
rep.setIdentityProviderMappers(r.getIdentityProviderMappers());
}
return rep;
}
}
@ -337,6 +349,7 @@ public class RealmAdminResource {
@POST
public GlobalRequestResult pushRevocation() {
auth.requireManage();
adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
return new ResourceAdminManager(session).pushRealmRevocationPolicy(uriInfo.getRequestUri(), realm);
}
@ -350,6 +363,7 @@ public class RealmAdminResource {
@POST
public GlobalRequestResult logoutAll() {
auth.init(RealmAuth.Resource.USER).requireManage();
session.sessions().removeUserSessions(realm);
adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
return new ResourceAdminManager(session).logoutAll(uriInfo.getRequestUri(), realm);
@ -365,6 +379,7 @@ public class RealmAdminResource {
@DELETE
public void deleteSession(@PathParam("session") String sessionId) {
auth.init(RealmAuth.Resource.USER).requireManage();
UserSessionModel userSession = session.sessions().getUserSession(realm, sessionId);
if (userSession == null) throw new NotFoundException("Sesssion not found");
AuthenticationManager.backchannelLogout(session, realm, userSession, uriInfo, connection, headers, true);
@ -386,6 +401,7 @@ public class RealmAdminResource {
@Produces(MediaType.APPLICATION_JSON)
public List<Map<String, String>> getClientSessionStats() {
auth.requireView();
List<Map<String, String>> data = new LinkedList<Map<String, String>>();
for (ClientModel client : realm.getClients()) {
long size = session.sessions().getActiveUserSessions(client.getRealm(), client);
@ -691,7 +707,8 @@ public class RealmAdminResource {
@Produces(MediaType.APPLICATION_JSON)
@Path("default-groups")
public List<GroupRepresentation> getDefaultGroups() {
this.auth.requireView();
auth.requireView();
List<GroupRepresentation> defaults = new LinkedList<>();
for (GroupModel group : realm.getDefaultGroups()) {
defaults.add(ModelToRepresentation.toRepresentation(group, false));
@ -702,7 +719,8 @@ public class RealmAdminResource {
@NoCache
@Path("default-groups/{groupId}")
public void addDefaultGroup(@PathParam("groupId") String groupId) {
this.auth.requireManage();
auth.requireManage();
GroupModel group = realm.getGroupById(groupId);
if (group == null) {
throw new NotFoundException("Group not found");
@ -714,7 +732,8 @@ public class RealmAdminResource {
@NoCache
@Path("default-groups/{groupId}")
public void removeDefaultGroup(@PathParam("groupId") String groupId) {
this.auth.requireManage();
auth.requireManage();
GroupModel group = realm.getGroupById(groupId);
if (group == null) {
throw new NotFoundException("Group not found");
@ -736,7 +755,8 @@ public class RealmAdminResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public GroupRepresentation getGroupByPath(@PathParam("path") String path) {
this.auth.requireView();
auth.requireView();
GroupModel found = KeycloakModelUtils.findGroupByPath(realm, path);
if (found == null) {
throw new NotFoundException("Group path does not exist");
@ -756,6 +776,7 @@ public class RealmAdminResource {
@Consumes(MediaType.APPLICATION_JSON)
public Response partialImport(PartialImportRepresentation rep) {
auth.requireManage();
PartialImportManager partialImport = new PartialImportManager(rep, session, realm, adminEvent);
return partialImport.saveResources();
}
@ -768,6 +789,7 @@ public class RealmAdminResource {
@POST
public void clearRealmCache() {
auth.requireManage();
adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
CacheRealmProvider cache = session.getProvider(CacheRealmProvider.class);
if (cache != null) {
@ -783,6 +805,7 @@ public class RealmAdminResource {
@POST
public void clearUserCache() {
auth.requireManage();
adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
CacheUserProvider cache = session.getProvider(CacheUserProvider.class);
if (cache != null) {

View file

@ -79,8 +79,9 @@ public class RoleByIdResource extends RoleResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public RoleRepresentation getRole(final @PathParam("role-id") String id) {
auth.requireAny();
RoleModel roleModel = getRoleModel(id);
auth.requireView();
return getRole(roleModel);
}
@ -111,8 +112,9 @@ public class RoleByIdResource extends RoleResource {
@DELETE
@NoCache
public void deleteRole(final @PathParam("role-id") String id) {
RoleModel role = getRoleModel(id);
auth.requireManage();
RoleModel role = getRoleModel(id);
deleteRole(role);
adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
}
@ -127,8 +129,9 @@ public class RoleByIdResource extends RoleResource {
@PUT
@Consumes(MediaType.APPLICATION_JSON)
public void updateRole(final @PathParam("role-id") String id, final RoleRepresentation rep) {
RoleModel role = getRoleModel(id);
auth.requireManage();
RoleModel role = getRoleModel(id);
updateRole(rep, role);
adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(rep).success();
}
@ -143,8 +146,9 @@ public class RoleByIdResource extends RoleResource {
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void addComposites(final @PathParam("role-id") String id, List<RoleRepresentation> roles) {
RoleModel role = getRoleModel(id);
auth.requireManage();
RoleModel role = getRoleModel(id);
addComposites(adminEvent, uriInfo, roles, role);
}
@ -161,6 +165,7 @@ public class RoleByIdResource extends RoleResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getRoleComposites(final @PathParam("role-id") String id) {
auth.requireAny();
if (logger.isDebugEnabled()) logger.debug("*** getRoleComposites: '" + id + "'");
RoleModel role = getRoleModel(id);
@ -179,8 +184,9 @@ public class RoleByIdResource extends RoleResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getRealmRoleComposites(final @PathParam("role-id") String id) {
auth.requireAny();
RoleModel role = getRoleModel(id);
auth.requireView();
return getRealmRoleComposites(role);
}
@ -197,8 +203,9 @@ public class RoleByIdResource extends RoleResource {
@Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getClientRoleComposites(final @PathParam("role-id") String id,
final @PathParam("client") String client) {
auth.requireAny();
RoleModel role = getRoleModel(id);
auth.requireView();
ClientModel clientModel = realm.getClientById(client);
if (clientModel == null) {
throw new NotFoundException("Could not find client");
@ -219,8 +226,9 @@ public class RoleByIdResource extends RoleResource {
@Produces(MediaType.APPLICATION_JSON)
public Set<RoleRepresentation> getClientByIdRoleComposites(final @PathParam("role-id") String role,
final @PathParam("client") String client) {
auth.requireAny();
RoleModel roleModel = getRoleModel(role);
auth.requireView();
ClientModel clientModel = realm.getClientById(client);
if (clientModel == null) {
throw new NotFoundException("Could not find client");
@ -239,8 +247,9 @@ public class RoleByIdResource extends RoleResource {
@DELETE
@Consumes(MediaType.APPLICATION_JSON)
public void deleteComposites(final @PathParam("role-id") String id, List<RoleRepresentation> roles) {
RoleModel role = getRoleModel(id);
auth.requireManage();
RoleModel role = getRoleModel(id);
deleteComposites(roles, role);
adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).representation(roles).success();

View file

@ -100,6 +100,7 @@ public class UserFederationProviderResource {
@Consumes(MediaType.APPLICATION_JSON)
public void updateProviderInstance(UserFederationProviderRepresentation rep) {
auth.requireManage();
String displayName = rep.getDisplayName();
if (displayName != null && displayName.trim().equals("")) {
displayName = null;
@ -129,6 +130,7 @@ public class UserFederationProviderResource {
@Produces(MediaType.APPLICATION_JSON)
public UserFederationProviderRepresentation getProviderInstance() {
auth.requireView();
return ModelToRepresentation.toRepresentation(this.federationProviderModel);
}
@ -157,9 +159,10 @@ public class UserFederationProviderResource {
@Path("sync")
@NoCache
public UserFederationSyncResult syncUsers(@QueryParam("action") String action) {
logger.debug("Syncing users");
auth.requireManage();
logger.debug("Syncing users");
UsersSyncManager syncManager = new UsersSyncManager();
UserFederationSyncResult syncResult;
if ("triggerFullSync".equals(action)) {
@ -183,7 +186,8 @@ public class UserFederationProviderResource {
@Path("mapper-types")
@NoCache
public Map<String, UserFederationMapperTypeRepresentation> getMapperTypes() {
this.auth.requireView();
auth.requireView();
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
Map<String, UserFederationMapperTypeRepresentation> types = new HashMap<>();
List<ProviderFactory> factories = sessionFactory.getProviderFactories(UserFederationMapper.class);
@ -226,7 +230,8 @@ public class UserFederationProviderResource {
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public List<UserFederationMapperRepresentation> getMappers() {
this.auth.requireView();
auth.requireView();
List<UserFederationMapperRepresentation> mappers = new LinkedList<>();
for (UserFederationMapperModel model : realm.getUserFederationMappersByFederationProvider(this.federationProviderModel.getId())) {
mappers.add(ModelToRepresentation.toRepresentation(realm, model));
@ -265,6 +270,7 @@ public class UserFederationProviderResource {
@Consumes(MediaType.APPLICATION_JSON)
public Response addMapper(UserFederationMapperRepresentation mapper) {
auth.requireManage();
UserFederationMapperModel model = RepresentationToModel.toModel(realm, mapper);
validateModel(model);
@ -290,6 +296,7 @@ public class UserFederationProviderResource {
@Produces(MediaType.APPLICATION_JSON)
public UserFederationMapperRepresentation getMapperById(@PathParam("id") String id) {
auth.requireView();
UserFederationMapperModel model = realm.getUserFederationMapperById(id);
if (model == null) throw new NotFoundException("Model not found");
return ModelToRepresentation.toRepresentation(realm, model);
@ -307,6 +314,7 @@ public class UserFederationProviderResource {
@Consumes(MediaType.APPLICATION_JSON)
public void update(@PathParam("id") String id, UserFederationMapperRepresentation rep) {
auth.requireManage();
UserFederationMapperModel model = realm.getUserFederationMapperById(id);
if (model == null) throw new NotFoundException("Model not found");
model = RepresentationToModel.toModel(realm, rep);
@ -328,6 +336,7 @@ public class UserFederationProviderResource {
@Path("mappers/{id}")
public void delete(@PathParam("id") String id) {
auth.requireManage();
UserFederationMapperModel model = realm.getUserFederationMapperById(id);
if (model == null) throw new NotFoundException("Model not found");
realm.removeUserFederationMapper(model);

View file

@ -134,6 +134,7 @@ public class UserFederationProvidersResource {
@Produces(MediaType.APPLICATION_JSON)
public List<UserFederationProviderFactoryRepresentation> getProviders() {
auth.requireView();
List<UserFederationProviderFactoryRepresentation> providers = new LinkedList<UserFederationProviderFactoryRepresentation>();
for (ProviderFactory factory : session.getKeycloakSessionFactory().getProviderFactories(UserFederationProvider.class)) {
UserFederationProviderFactoryRepresentation rep = new UserFederationProviderFactoryRepresentation();
@ -155,6 +156,7 @@ public class UserFederationProvidersResource {
@Produces(MediaType.APPLICATION_JSON)
public UserFederationProviderFactoryRepresentation getProvider(@PathParam("id") String id) {
auth.requireView();
for (ProviderFactory factory : session.getKeycloakSessionFactory().getProviderFactories(UserFederationProvider.class)) {
if (!factory.getId().equals(id)) {
continue;
@ -192,6 +194,7 @@ public class UserFederationProvidersResource {
@Consumes(MediaType.APPLICATION_JSON)
public Response createProviderInstance(UserFederationProviderRepresentation rep) {
auth.requireManage();
String displayName = rep.getDisplayName();
if (displayName != null && displayName.trim().equals("")) {
displayName = null;
@ -225,6 +228,7 @@ public class UserFederationProvidersResource {
@NoCache
public List<UserFederationProviderRepresentation> getUserFederationInstances() {
auth.requireManage();
List<UserFederationProviderRepresentation> reps = new LinkedList<UserFederationProviderRepresentation>();
for (UserFederationProviderModel model : realm.getUserFederationProviders()) {
UserFederationProviderRepresentation rep = ModelToRepresentation.toRepresentation(model);

View file

@ -313,6 +313,7 @@ public class UsersResource {
public Map<String, Object> impersonate(final @PathParam("id") String id) {
auth.init(RealmAuth.Resource.IMPERSONATION);
auth.requireManage();
UserModel user = session.users().getUserById(id, realm);
if (user == null) {
throw new NotFoundException("User not found");
@ -357,6 +358,7 @@ public class UsersResource {
@Produces(MediaType.APPLICATION_JSON)
public List<UserSessionRepresentation> getSessions(final @PathParam("id") String id) {
auth.requireView();
UserModel user = session.users().getUserById(id, realm);
if (user == null) {
throw new NotFoundException("User not found");
@ -382,6 +384,7 @@ public class UsersResource {
@Produces(MediaType.APPLICATION_JSON)
public List<UserSessionRepresentation> getSessions(final @PathParam("id") String id, final @PathParam("clientId") String clientId) {
auth.requireView();
UserModel user = session.users().getUserById(id, realm);
if (user == null) {
throw new NotFoundException("User not found");
@ -420,6 +423,7 @@ public class UsersResource {
@Produces(MediaType.APPLICATION_JSON)
public List<FederatedIdentityRepresentation> getFederatedIdentity(final @PathParam("id") String id) {
auth.requireView();
UserModel user = session.users().getUserById(id, realm);
if (user == null) {
throw new NotFoundException("User not found");
@ -456,6 +460,7 @@ public class UsersResource {
@NoCache
public Response addFederatedIdentity(final @PathParam("id") String id, final @PathParam("provider") String provider, FederatedIdentityRepresentation rep) {
auth.requireManage();
UserModel user = session.users().getUserById(id, realm);
if (user == null) {
throw new NotFoundException("User not found");
@ -481,6 +486,7 @@ public class UsersResource {
@NoCache
public void removeFederatedIdentity(final @PathParam("id") String id, final @PathParam("provider") String provider) {
auth.requireManage();
UserModel user = session.users().getUserById(id, realm);
if (user == null) {
throw new NotFoundException("User not found");
@ -503,6 +509,7 @@ public class UsersResource {
@Produces(MediaType.APPLICATION_JSON)
public List<Map<String, Object>> getConsents(final @PathParam("id") String id) {
auth.requireView();
UserModel user = session.users().getUserById(id, realm);
if (user == null) {
throw new NotFoundException("User not found");
@ -555,6 +562,7 @@ public class UsersResource {
@NoCache
public void revokeConsent(final @PathParam("id") String id, final @PathParam("client") String clientId) {
auth.requireManage();
UserModel user = session.users().getUserById(id, realm);
if (user == null) {
throw new NotFoundException("User not found");
@ -586,6 +594,7 @@ public class UsersResource {
@POST
public void logout(final @PathParam("id") String id) {
auth.requireManage();
UserModel user = session.users().getUserById(id, realm);
if (user == null) {
throw new NotFoundException("User not found");

View file

@ -72,6 +72,9 @@ public class ImpersonationTest {
UserModel masterImpersonator = manager.getSession().users().addUser(adminstrationRealm, "master-impersonator");
masterImpersonator.setEnabled(true);
ClientModel adminRealmClient = adminstrationRealm.getClientByClientId(KeycloakModelUtils.getMasterRealmAdminApplicationClientId(appRealm.getName()));
RoleModel masterManageUsersRole = adminRealmClient.getRole(AdminRoles.MANAGE_USERS);
masterImpersonator.grantRole(masterManageUsersRole);
RoleModel masterImpersonatorRole = adminRealmClient.getRole(ImpersonationConstants.IMPERSONATION_ROLE);
masterImpersonator.grantRole(masterImpersonatorRole);
}
@ -84,6 +87,10 @@ public class ImpersonationTest {
UserModel impersonator = manager.getSession().users().addUser(appRealm, "impersonator");
impersonator.setEnabled(true);
ClientModel appRealmClient = appRealm.getClientByClientId(Constants.REALM_MANAGEMENT_CLIENT_ID);
RoleModel masterManageUsersRole = appRealmClient.getRole(AdminRoles.MANAGE_USERS);
impersonator.grantRole(masterManageUsersRole);
RoleModel realmImpersonatorRole = appRealmClient.getRole(ImpersonationConstants.IMPERSONATION_ROLE);
impersonator.grantRole(realmImpersonatorRole);
}

View file

@ -40,6 +40,10 @@ module.controller('GlobalCtrl', function($scope, $http, Auth, Current, $location
return getAccess('view-events') || getAccess('manage-events') || this.manageClients;
},
get viewIdentityProviders() {
return getAccess('view-identity-providers') || getAccess('manage-identity-providers') || this.manageIdentityProviders;
},
get manageRealm() {
return getAccess('manage-realm');
},
@ -55,6 +59,11 @@ module.controller('GlobalCtrl', function($scope, $http, Auth, Current, $location
get manageEvents() {
return getAccess('manage-events');
},
get manageIdentityProviders() {
return getAccess('manage-identity-providers');
},
get impersonation() {
return getAccess('impersonation');
}

View file

@ -15,7 +15,7 @@
</div>
</div>
<div class="pull-right" data-ng-show="access.manageRealm">
<div class="pull-right" data-ng-show="access.manageClients">
<a id="createClient" class="btn btn-default" href="#/realms/{{realm.realm}}/client-initial-access/create">{{:: 'create' | translate}}</a>
</div>
</div>

View file

@ -42,7 +42,7 @@
</td>
<td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/clients/{{client.id}}">{{:: 'edit' | translate}}</td>
<td class="kc-action-cell" data-ng-click="exportClient(client)">{{:: 'export' | translate}}</td>
<td class="kc-action-cell" data-ng-click="removeClient(client)">{{:: 'delete' | translate}}</td>
<td class="kc-action-cell" data-ng-show="access.manageClients" data-ng-click="removeClient(client)">{{:: 'delete' | translate}}</td>
</tr>
<tr data-ng-show="(clients | filter:search).length == 0">
<td class="text-muted" colspan="3" data-ng-show="search.clientId">{{:: 'no-results' | translate}}</td>

View file

@ -55,7 +55,7 @@
<td>{{mapperTypes[mapper.protocolMapper].category}}</td>
<td>{{mapperTypes[mapper.protocolMapper].name}}</td>
<td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/clients/{{client.id}}/mappers/{{mapper.id}}">{{:: 'edit' | translate}}</td>
<td class="kc-action-cell" data-ng-click="removeMapper(mapper)">{{:: 'delete' | translate}}</td>
<td class="kc-action-cell" data-ng-show="access.manageClients" data-ng-click="removeMapper(mapper)">{{:: 'delete' | translate}}</td>
</tr>
<tr data-ng-show="mappers.length == 0">
<td>{{:: 'no-mappers-available' | translate}}</td>

View file

@ -7,7 +7,7 @@
<kc-tabs-client></kc-tabs-client>
<form class="form-horizontal" name="credentialForm" novalidate kc-read-only="!access.manageRealm">
<form class="form-horizontal" name="credentialForm" novalidate kc-read-only="!access.manageClients">
<fieldset class="border-top">
<div class="form-group">
<label class="col-md-2 control-label" for="notBefore">{{:: 'not-before' | translate}}</label>

View file

@ -29,7 +29,7 @@
<td translate="{{role.composite}}"></td>
<td>{{role.description}}</td>
<td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/clients/{{client.id}}/roles/{{role.id}}">{{:: 'edit' | translate}}</td>
<td class="kc-action-cell" data-ng-click="removeRole(role)">{{:: 'delete' | translate}}</td>
<td class="kc-action-cell" data-ng-show="access.manageClients" data-ng-click="removeRole(role)">{{:: 'delete' | translate}}</td>
</tr>
<tr data-ng-show="!roles || roles.length == 0">
<td>{{:: 'no-client-roles-available' | translate}}</td>

View file

@ -7,11 +7,11 @@
<li class="active" data-ng-hide="create">{{mapper.name|capitalize}}</li>
</ol>
<h1 data-ng-hide="create">{{mapper.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-show="!create && access.manageRealm"
<h1 data-ng-hide="create">{{mapper.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-show="!create && access.manageIdentityProviders"
data-ng-hide="changed" data-ng-click="remove()"></i></h1>
<h1 data-ng-show="create">{{:: 'add-identity-provider-mapper' | translate}}</h1>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageIdentityProviders">
<fieldset>
<div class="form-group clearfix" data-ng-show="!create">
<label class="col-md-2 control-label" for="mapperId">{{:: 'id' | translate}} </label>
@ -48,14 +48,14 @@
<kc-provider-config config="mapper.config" properties="mapperType.properties" realm="realm"></kc-provider-config>
</fieldset>
<div class="form-group" data-ng-show="create && access.manageRealm">
<div class="form-group" data-ng-show="create && access.manageIdentityProviders">
<div class="col-md-10 col-md-offset-2">
<button kc-save>{{:: 'save' | translate}}</button>
<button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button>
</div>
</div>
<div class="form-group" data-ng-show="!create && access.manageRealm">
<div class="form-group" data-ng-show="!create && access.manageIdentityProviders">
<div class="col-md-10 col-md-offset-2">
<button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button>
<button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button>

View file

@ -19,7 +19,7 @@
</div>
</div>
</div>
<div class="pull-right">
<div class="pull-right" data-ng-show="access.manageIdentityProviders">
<a class="btn btn-primary" href="#/create/identity-provider-mappers/{{realm.realm}}/{{identityProvider.alias}}">{{:: 'create' | translate}}</a>
</div>
</div>

View file

@ -1,8 +1,8 @@
<h1 data-ng-show="model.create">{{:: 'create-protocol-mapper' | translate}}</h1>
<h1 data-ng-hide="model.create">{{model.mapper.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-show="!model.create && access.manageRealm"
<h1 data-ng-hide="model.create">{{model.mapper.name|capitalize}}<i class="pficon pficon-delete clickable" data-ng-show="!model.create && access.manageClients"
data-ng-hide="model.changed" data-ng-click="remove()"></i></h1>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageClients">
<fieldset>
<div class="form-group clearfix">
@ -64,14 +64,14 @@
</fieldset>
<div class="form-group">
<div class="col-md-10 col-md-offset-2" data-ng-show="model.create && access.manageRealm">
<div class="col-md-10 col-md-offset-2" data-ng-show="model.create && access.manageClients">
<button kc-save>{{:: 'save' | translate}}</button>
<button kc-cancel data-ng-click="cancel()">{{:: 'cancel' | translate}}</button>
</div>
</div>
<div class="form-group">
<div class="col-md-10 col-md-offset-2" data-ng-show="!model.create && access.manageRealm">
<div class="col-md-10 col-md-offset-2" data-ng-show="!model.create && access.manageClients">
<button kc-save data-ng-disabled="!model.changed">{{:: 'save' | translate}}</button>
<button kc-reset data-ng-disabled="!model.changed">{{:: 'cancel' | translate}}</button>
</div>

View file

@ -6,7 +6,7 @@
<kc-tabs-identity-provider></kc-tabs-identity-provider>
<form class="form-horizontal" name="realmForm" novalidate>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageIdentityProviders">
<input type="text" readonly value="this is not a login form" style="display: none;">
<input type="password" readonly value="this is not a login form" style="display: none;">

View file

@ -6,7 +6,7 @@
<kc-tabs-identity-provider></kc-tabs-identity-provider>
<form class="form-horizontal" name="realmForm" novalidate>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageIdentityProviders">
<fieldset>
<div class="form-group clearfix">
<label class="col-md-2 control-label" for="redirectUri">{{:: 'redirect-uri' | translate}}</label>

View file

@ -6,7 +6,7 @@
<kc-tabs-identity-provider></kc-tabs-identity-provider>
<form class="form-horizontal" name="realmForm" novalidate>
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageIdentityProviders">
<input type="text" readonly value="this is not a login form" style="display: none;">
<input type="password" readonly value="this is not a login form" style="display: none;">

View file

@ -9,7 +9,7 @@
<thead>
<tr>
<th colspan="6" class="kc-table-actions">
<div class="dropdown pull-right">
<div class="dropdown pull-right" data-ng-show="access.manageIdentityProviders">
<select class="form-control" ng-model="provider"
ng-options="p.name group by p.groupName for p in allProviders track by p.id"
data-ng-change="addProvider(provider); provider = null">
@ -35,7 +35,7 @@
<td translate="{{identityProvider.enabled}}"></td>
<td>{{identityProvider.config.guiOrder}}</td>
<td class="kc-action-cell" kc-open="/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{:: 'edit' | translate}}</td>
<td class="kc-action-cell" data-ng-click="removeIdentityProvider(identityProvider)">{{:: 'delete' | translate}}</td>
<td class="kc-action-cell" data-ng-show="access.manageIdentityProviders" data-ng-click="removeIdentityProvider(identityProvider)">{{:: 'delete' | translate}}</td>
</tr>
</tbody>
</table>

View file

@ -113,7 +113,7 @@
</div>
</div>
<div class="form-group clearfix" data-ng-hide="create">
<div class="form-group clearfix" data-ng-hide="create || !access.impersonation">
<label class="col-md-2 control-label" for="impersonate">{{:: 'impersonate-user' | translate}}</label>
<div class="col-md-6">

View file

@ -32,8 +32,8 @@
<li data-ng-show="access.viewClients" data-ng-class="(path[2] == 'clients' || path[1] == 'client' || path[3] == 'clients') && 'active'"><a href="#/realms/{{realm.realm}}/clients"><i class="fa fa-cube"></i> {{:: 'clients' | translate}}</a></li>
<li data-ng-show="access.viewClients" data-ng-class="(path[2] == 'client-templates' || path[1] == 'client-template' || path[3] == 'client-templates') && 'active'"><a href="#/realms/{{realm.realm}}/client-templates"><i class="fa fa-cubes"></i> {{:: 'client-templates' | translate}}</a></li>
<li data-ng-show="access.viewRealm" data-ng-class="(path[2] == 'roles' || path[2] == 'default-roles' || (path[1] == 'role' && path[3] != 'clients')) && 'active'"><a href="#/realms/{{realm.realm}}/roles"><i class="fa fa-tasks"></i> {{:: 'roles' | translate}}</a></li>
<li data-ng-show="access.viewRealm" data-ng-class="(path[2] == 'identity-provider-settings' || path[2] == 'identity-provider-mappers') && 'active'"><a href="#/realms/{{realm.realm}}/identity-provider-settings"><i class="fa fa-exchange"></i> {{:: 'identity-providers' | translate}}</a></li>
<li data-ng-show="access.viewRealm" data-ng-class="(path[1] == 'user-federation' || path[2] == 'user-federation') && 'active'"><a href="#/realms/{{realm.realm}}/user-federation"><i class="fa fa-database"></i> {{:: 'user-federation' | translate}}</a></li>
<li data-ng-show="access.viewIdentityProviders" data-ng-class="(path[2] == 'identity-provider-settings' || path[2] == 'identity-provider-mappers') && 'active'"><a href="#/realms/{{realm.realm}}/identity-provider-settings"><i class="fa fa-exchange"></i> {{:: 'identity-providers' | translate}}</a></li>
<li data-ng-show="access.viewUsers" data-ng-class="(path[1] == 'user-federation' || path[2] == 'user-federation') && 'active'"><a href="#/realms/{{realm.realm}}/user-federation"><i class="fa fa-database"></i> {{:: 'user-federation' | translate}}</a></li>
<li data-ng-show="access.viewRealm" data-ng-class="(path[1] == 'authentication' || path[2] == 'authentication') && 'active'"><a href="#/realms/{{realm.realm}}/authentication/flows"><i class="fa fa-lock"></i> {{:: 'authentication' | translate}}</a></li>
</ul>
</div>

View file

@ -5,7 +5,7 @@
<ul class="nav nav-tabs">
<li ng-class="{active: path[2] == 'groups'}"><a href="#/realms/{{realm.realm}}/groups">{{:: 'groups' | translate}}</a></li>
<li ng-class="{active: path[2] == 'default-groups'}"><a href="#/realms/{{realm.realm}}/default-groups">{{:: 'default-groups' | translate}}</a><kc-tooltip>{{:: 'groups.default-groups.tooltip' | translate}}</kc-tooltip>
<li data-ng-show="access.viewRealm" ng-class="{active: path[2] == 'default-groups'}"><a href="#/realms/{{realm.realm}}/default-groups">{{:: 'default-groups' | translate}}</a><kc-tooltip>{{:: 'groups.default-groups.tooltip' | translate}}</kc-tooltip>
</li>
</ul>
</div>

View file

@ -13,7 +13,7 @@
<li ng-class="{active: path[2] == 'theme-settings'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/theme-settings">{{:: 'realm-tab-themes' | translate}}</a></li>
<li ng-class="{active: path[2] == 'cache-settings'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/cache-settings">{{:: 'realm-tab-cache' | translate}}</a></li>
<li ng-class="{active: path[2] == 'token-settings'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/token-settings">{{:: 'realm-tab-tokens' | translate}}</a></li>
<li ng-class="{active: path[2] == 'client-initial-access'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/client-initial-access">{{:: 'realm-tab-client-initial-access' | translate}}</a></li>
<li ng-class="{active: path[2] == 'client-initial-access'}" data-ng-show="access.viewClients"><a href="#/realms/{{realm.realm}}/client-initial-access">{{:: 'realm-tab-client-initial-access' | translate}}</a></li>
<li ng-class="{active: path[2] == 'defense'}" data-ng-show="access.viewRealm"><a href="#/realms/{{realm.realm}}/defense/headers">{{:: 'realm-tab-security-defenses' | translate}}</a></li>
</ul>
</div>