KEYCLOAK-2491 Fix permissions in admin console to match permissions in admin endpoints
This commit is contained in:
parent
b3d40c6f85
commit
04d76b0052
32 changed files with 206 additions and 75 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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.");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;">
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;">
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
Loading…
Reference in a new issue