resource rest api
This commit is contained in:
parent
4e61981b69
commit
d11876f58e
14 changed files with 146 additions and 16 deletions
|
@ -11,6 +11,7 @@ import java.util.Set;
|
||||||
*/
|
*/
|
||||||
public class ResourceRepresentation {
|
public class ResourceRepresentation {
|
||||||
protected String self; // link
|
protected String self; // link
|
||||||
|
protected String id;
|
||||||
protected String name;
|
protected String name;
|
||||||
protected String adminUrl;
|
protected String adminUrl;
|
||||||
protected boolean surrogateAuthRequired;
|
protected boolean surrogateAuthRequired;
|
||||||
|
@ -29,6 +30,14 @@ public class ResourceRepresentation {
|
||||||
this.self = self;
|
this.self = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@
|
||||||
"resources" : [
|
"resources" : [
|
||||||
{
|
{
|
||||||
"name" : "customer-portal",
|
"name" : "customer-portal",
|
||||||
|
"enabled" : true,
|
||||||
"adminUrl" : "http://localhost:8080/customer-portal/j_admin_request",
|
"adminUrl" : "http://localhost:8080/customer-portal/j_admin_request",
|
||||||
"useRealmMappings" : true,
|
"useRealmMappings" : true,
|
||||||
"credentials" : [
|
"credentials" : [
|
||||||
|
@ -81,6 +82,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name" : "product-portal",
|
"name" : "product-portal",
|
||||||
|
"enabled" : true,
|
||||||
"adminUrl" : "http://localhost:8080/product-portal/j_admin_request",
|
"adminUrl" : "http://localhost:8080/product-portal/j_admin_request",
|
||||||
"useRealmMappings" : true,
|
"useRealmMappings" : true,
|
||||||
"credentials" : [
|
"credentials" : [
|
||||||
|
|
|
@ -67,7 +67,7 @@
|
||||||
</section>
|
</section>
|
||||||
<section class="info-area">
|
<section class="info-area">
|
||||||
<h3>Info area</h3>
|
<h3>Info area</h3>
|
||||||
<p>Does not have an account? <a href="<%=application.getContextPath()%>/saas/saas-register.html">Register</a>.</p>
|
<p>Does not have an account? <a href="<%=application.getContextPath()%>/saas/saas-register.jsp">Register</a>.</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>Domain:</strong> 10.0.0.1</li>
|
<li><strong>Domain:</strong> 10.0.0.1</li>
|
||||||
<li><strong>Zone:</strong> Live</li>
|
<li><strong>Zone:</strong> Live</li>
|
||||||
|
|
|
@ -27,6 +27,7 @@ public class ResourceManager {
|
||||||
|
|
||||||
public ResourceModel createResource(RealmModel realm, RoleModel loginRole, ResourceRepresentation resourceRep) {
|
public ResourceModel createResource(RealmModel realm, RoleModel loginRole, ResourceRepresentation resourceRep) {
|
||||||
ResourceModel resource = realm.addResource(resourceRep.getName());
|
ResourceModel resource = realm.addResource(resourceRep.getName());
|
||||||
|
resource.setEnabled(resourceRep.isEnabled());
|
||||||
resource.setManagementUrl(resourceRep.getAdminUrl());
|
resource.setManagementUrl(resourceRep.getAdminUrl());
|
||||||
resource.setSurrogateAuthRequired(resourceRep.isSurrogateAuthRequired());
|
resource.setSurrogateAuthRequired(resourceRep.isSurrogateAuthRequired());
|
||||||
resource.updateResource();
|
resource.updateResource();
|
||||||
|
@ -82,16 +83,22 @@ public class ResourceManager {
|
||||||
return createResource(realm, loginRole, resourceRep);
|
return createResource(realm, loginRole, resourceRep);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceRepresentation getResource(ResourceModel resourceModel, boolean bulk) {
|
public void updateResource(ResourceRepresentation rep, ResourceModel resource) {
|
||||||
|
resource.setName(rep.getName());
|
||||||
|
resource.setEnabled(rep.isEnabled());
|
||||||
|
resource.setManagementUrl(rep.getAdminUrl());
|
||||||
|
resource.setSurrogateAuthRequired(rep.isSurrogateAuthRequired());
|
||||||
|
resource.updateResource();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceRepresentation toRepresentation(ResourceModel resourceModel) {
|
||||||
ResourceRepresentation rep = new ResourceRepresentation();
|
ResourceRepresentation rep = new ResourceRepresentation();
|
||||||
|
rep.setId(resourceModel.getId());
|
||||||
rep.setName(resourceModel.getName());
|
rep.setName(resourceModel.getName());
|
||||||
rep.setEnabled(resourceModel.isEnabled());
|
rep.setEnabled(resourceModel.isEnabled());
|
||||||
rep.setAdminUrl(resourceModel.getManagementUrl());
|
rep.setAdminUrl(resourceModel.getManagementUrl());
|
||||||
rep.setSurrogateAuthRequired(resourceModel.isSurrogateAuthRequired());
|
rep.setSurrogateAuthRequired(resourceModel.isSurrogateAuthRequired());
|
||||||
List<RoleModel> roles = resourceModel.getRoles();
|
|
||||||
for (RoleModel role : roles) {
|
|
||||||
rep.role(realmManager.toRepresentation(role));
|
|
||||||
}
|
|
||||||
return rep;
|
return rep;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,14 +9,10 @@ import org.keycloak.services.models.RealmModel;
|
||||||
import org.keycloak.services.models.ResourceModel;
|
import org.keycloak.services.models.ResourceModel;
|
||||||
import org.keycloak.services.models.RoleModel;
|
import org.keycloak.services.models.RoleModel;
|
||||||
import org.keycloak.services.models.UserModel;
|
import org.keycloak.services.models.UserModel;
|
||||||
import org.keycloak.services.resources.RealmsResource;
|
|
||||||
|
|
||||||
import javax.ws.rs.core.MultivaluedMap;
|
import javax.ws.rs.core.MultivaluedMap;
|
||||||
import javax.ws.rs.core.NewCookie;
|
|
||||||
import javax.ws.rs.core.UriInfo;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URI;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -135,7 +131,7 @@ public class TokenManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (accessCodeEntry.getResourceRolesRequested().size() > 0) {
|
if (accessCodeEntry.getResourceRolesRequested().size() > 0) {
|
||||||
Map<String, ResourceModel> resourceMap = realm.getResourceMap();
|
Map<String, ResourceModel> resourceMap = realm.getResourceNameMap();
|
||||||
for (String resourceName : accessCodeEntry.getResourceRolesRequested().keySet()) {
|
for (String resourceName : accessCodeEntry.getResourceRolesRequested().keySet()) {
|
||||||
ResourceModel resource = resourceMap.get(resourceName);
|
ResourceModel resource = resourceMap.get(resourceName);
|
||||||
SkeletonKeyToken.Access access = token.addAccess(resourceName).verifyCaller(resource.isSurrogateAuthRequired());
|
SkeletonKeyToken.Access access = token.addAccess(resourceName).verifyCaller(resource.isSurrogateAuthRequired());
|
||||||
|
|
|
@ -79,7 +79,7 @@ public interface RealmModel {
|
||||||
|
|
||||||
List<RoleModel> getRoles();
|
List<RoleModel> getRoles();
|
||||||
|
|
||||||
Map<String, ResourceModel> getResourceMap();
|
Map<String, ResourceModel> getResourceNameMap();
|
||||||
|
|
||||||
List<ResourceModel> getResources();
|
List<ResourceModel> getResources();
|
||||||
|
|
||||||
|
@ -110,4 +110,6 @@ public interface RealmModel {
|
||||||
List<RequiredCredentialModel> getOAuthClientRequiredCredentials();
|
List<RequiredCredentialModel> getOAuthClientRequiredCredentials();
|
||||||
|
|
||||||
boolean hasRole(UserModel user, String role);
|
boolean hasRole(UserModel user, String role);
|
||||||
|
|
||||||
|
ResourceModel getResourceById(String id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -416,7 +416,7 @@ public class RealmAdapter implements RealmModel {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<String, ResourceModel> getResourceMap() {
|
public Map<String, ResourceModel> getResourceNameMap() {
|
||||||
Map<String, ResourceModel> resourceMap = new HashMap<String, ResourceModel>();
|
Map<String, ResourceModel> resourceMap = new HashMap<String, ResourceModel>();
|
||||||
for (ResourceModel resource : getResources()) {
|
for (ResourceModel resource : getResources()) {
|
||||||
resourceMap.put(resource.getName(), resource);
|
resourceMap.put(resource.getName(), resource);
|
||||||
|
@ -424,6 +424,24 @@ public class RealmAdapter implements RealmModel {
|
||||||
return resourceMap;
|
return resourceMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes sure that the resource returned is owned by the realm
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ResourceModel getResourceById(String id) {
|
||||||
|
RelationshipQuery<ResourceRelationship> query = getRelationshipManager().createRelationshipQuery(ResourceRelationship.class);
|
||||||
|
query.setParameter(ResourceRelationship.REALM, realm.getName());
|
||||||
|
query.setParameter(ResourceRelationship.RESOURCE, id);
|
||||||
|
List<ResourceRelationship> results = query.getResultList();
|
||||||
|
if (results.size() == 0) return null;
|
||||||
|
ResourceData resource = partitionManager.getPartition(ResourceData.class, id);
|
||||||
|
ResourceModel model = new ResourceAdapter(resource, this, partitionManager);
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ResourceModel> getResources() {
|
public List<ResourceModel> getResources() {
|
||||||
RelationshipQuery<ResourceRelationship> query = getRelationshipManager().createRelationshipQuery(ResourceRelationship.class);
|
RelationshipQuery<ResourceRelationship> query = getRelationshipManager().createRelationshipQuery(ResourceRelationship.class);
|
||||||
|
|
|
@ -14,6 +14,7 @@ public class ResourceRelationship extends AbstractAttributedType implements Rela
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public static final AttributeParameter REALM = new AttributeParameter("realm");
|
public static final AttributeParameter REALM = new AttributeParameter("realm");
|
||||||
|
public static final AttributeParameter RESOURCE = new AttributeParameter("resource");
|
||||||
|
|
||||||
public ResourceRelationship() {
|
public ResourceRelationship() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.keycloak.services.resources;
|
package org.keycloak.services.resources;
|
||||||
|
|
||||||
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
import org.jboss.resteasy.logging.Logger;
|
import org.jboss.resteasy.logging.Logger;
|
||||||
import org.keycloak.representations.idm.PublishedRealmRepresentation;
|
import org.keycloak.representations.idm.PublishedRealmRepresentation;
|
||||||
import org.keycloak.services.models.KeycloakSession;
|
import org.keycloak.services.models.KeycloakSession;
|
||||||
|
@ -37,6 +38,7 @@ public class PublicRealmResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
@NoCache
|
||||||
@Produces("application/json")
|
@Produces("application/json")
|
||||||
public PublishedRealmRepresentation getRealm(@PathParam("realm") String id) {
|
public PublishedRealmRepresentation getRealm(@PathParam("realm") String id) {
|
||||||
return new Transaction() {
|
return new Transaction() {
|
||||||
|
@ -47,6 +49,7 @@ public class PublicRealmResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
@NoCache
|
||||||
@Path("html")
|
@Path("html")
|
||||||
@Produces("text/html")
|
@Produces("text/html")
|
||||||
public String getRealmHtml(@PathParam("realm") String id) {
|
public String getRealmHtml(@PathParam("realm") String id) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.keycloak.services.resources;
|
package org.keycloak.services.resources;
|
||||||
|
|
||||||
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
import org.jboss.resteasy.jose.jws.JWSBuilder;
|
import org.jboss.resteasy.jose.jws.JWSBuilder;
|
||||||
import org.jboss.resteasy.jose.jws.JWSInput;
|
import org.jboss.resteasy.jose.jws.JWSInput;
|
||||||
import org.jboss.resteasy.jose.jws.crypto.RSAProvider;
|
import org.jboss.resteasy.jose.jws.crypto.RSAProvider;
|
||||||
|
@ -381,6 +382,7 @@ public class TokenService extends AbstractLoginService {
|
||||||
|
|
||||||
@Path("logout")
|
@Path("logout")
|
||||||
@GET
|
@GET
|
||||||
|
@NoCache
|
||||||
public Response logout(final @QueryParam("redirect_uri") String redirectUri) {
|
public Response logout(final @QueryParam("redirect_uri") String redirectUri) {
|
||||||
return new Transaction() {
|
return new Transaction() {
|
||||||
protected Response callImpl() {
|
protected Response callImpl() {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.keycloak.services.resources.admin;
|
package org.keycloak.services.resources.admin;
|
||||||
|
|
||||||
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
import org.jboss.resteasy.logging.Logger;
|
import org.jboss.resteasy.logging.Logger;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.representations.idm.RoleRepresentation;
|
import org.keycloak.representations.idm.RoleRepresentation;
|
||||||
|
@ -47,7 +48,13 @@ public class RealmAdminResource {
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Path("resources")
|
||||||
|
public RealmResourcesResource getResources() {
|
||||||
|
return new RealmResourcesResource(admin, realm);
|
||||||
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
@NoCache
|
||||||
@Produces("application/json")
|
@Produces("application/json")
|
||||||
public RealmRepresentation getRealm() {
|
public RealmRepresentation getRealm() {
|
||||||
return new Transaction() {
|
return new Transaction() {
|
||||||
|
@ -70,6 +77,7 @@ public class RealmAdminResource {
|
||||||
|
|
||||||
@Path("roles")
|
@Path("roles")
|
||||||
@GET
|
@GET
|
||||||
|
@NoCache
|
||||||
@Produces("application/json")
|
@Produces("application/json")
|
||||||
public List<RoleRepresentation> getRoles() {
|
public List<RoleRepresentation> getRoles() {
|
||||||
return new Transaction() {
|
return new Transaction() {
|
||||||
|
@ -88,6 +96,7 @@ public class RealmAdminResource {
|
||||||
|
|
||||||
@Path("roles/{id}")
|
@Path("roles/{id}")
|
||||||
@GET
|
@GET
|
||||||
|
@NoCache
|
||||||
@Produces("application/json")
|
@Produces("application/json")
|
||||||
public RoleRepresentation getRole(final @PathParam("id") String id) {
|
public RoleRepresentation getRole(final @PathParam("id") String id) {
|
||||||
return new Transaction() {
|
return new Transaction() {
|
||||||
|
@ -147,6 +156,7 @@ public class RealmAdminResource {
|
||||||
|
|
||||||
@Path("users")
|
@Path("users")
|
||||||
@GET
|
@GET
|
||||||
|
@NoCache
|
||||||
@Produces("application/json")
|
@Produces("application/json")
|
||||||
public List<UserRepresentation> getUsers() {
|
public List<UserRepresentation> getUsers() {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -1,13 +1,28 @@
|
||||||
package org.keycloak.services.resources.admin;
|
package org.keycloak.services.resources.admin;
|
||||||
|
|
||||||
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
import org.jboss.resteasy.logging.Logger;
|
import org.jboss.resteasy.logging.Logger;
|
||||||
import org.keycloak.representations.idm.ResourceRepresentation;
|
import org.keycloak.representations.idm.ResourceRepresentation;
|
||||||
|
import org.keycloak.services.managers.RealmManager;
|
||||||
|
import org.keycloak.services.managers.ResourceManager;
|
||||||
import org.keycloak.services.models.RealmModel;
|
import org.keycloak.services.models.RealmModel;
|
||||||
|
import org.keycloak.services.models.ResourceModel;
|
||||||
import org.keycloak.services.models.UserModel;
|
import org.keycloak.services.models.UserModel;
|
||||||
|
import org.keycloak.services.resources.Transaction;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.NotFoundException;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,7 +41,68 @@ public class RealmResourcesResource {
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
List<ResourceRepresentation> getResources() {
|
@NoCache
|
||||||
return null;
|
public List<ResourceRepresentation> getResources() {
|
||||||
|
return new Transaction() {
|
||||||
|
@Override
|
||||||
|
protected List<ResourceRepresentation> callImpl() {
|
||||||
|
List<ResourceRepresentation> rep = new ArrayList<ResourceRepresentation>();
|
||||||
|
List<ResourceModel> resourceModels = realm.getResources();
|
||||||
|
ResourceManager resourceManager = new ResourceManager(new RealmManager(session));
|
||||||
|
for (ResourceModel resourceModel : resourceModels) {
|
||||||
|
rep.add(resourceManager.toRepresentation(resourceModel));
|
||||||
|
}
|
||||||
|
return rep;
|
||||||
|
}
|
||||||
|
}.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public Response createResource(final @Context UriInfo uriInfo, final ResourceRepresentation rep) {
|
||||||
|
return new Transaction() {
|
||||||
|
@Override
|
||||||
|
protected Response callImpl() {
|
||||||
|
ResourceManager resourceManager = new ResourceManager(new RealmManager(session));
|
||||||
|
ResourceModel resourceModel = resourceManager.createResource(realm, rep);
|
||||||
|
return Response.created(uriInfo.getAbsolutePathBuilder().path(resourceModel.getId()).build()).build();
|
||||||
|
}
|
||||||
|
}.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Path("{id}")
|
||||||
|
@PUT
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public void update(final @PathParam("id") String id, final ResourceRepresentation rep) {
|
||||||
|
new Transaction() {
|
||||||
|
@Override
|
||||||
|
protected void runImpl() {
|
||||||
|
ResourceModel resourceModel = realm.getResourceById(id);
|
||||||
|
if (resourceModel == null) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
ResourceManager resourceManager = new ResourceManager(new RealmManager(session));
|
||||||
|
resourceManager.updateResource(rep, resourceModel);
|
||||||
|
}
|
||||||
|
}.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Path("{id}")
|
||||||
|
@GET
|
||||||
|
@NoCache
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public ResourceRepresentation getResource(final @PathParam("id") String id) {
|
||||||
|
return new Transaction() {
|
||||||
|
@Override
|
||||||
|
protected ResourceRepresentation callImpl() {
|
||||||
|
ResourceModel resourceModel = realm.getResourceById(id);
|
||||||
|
if (resourceModel == null) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
ResourceManager resourceManager = new ResourceManager(new RealmManager(session));
|
||||||
|
return resourceManager.toRepresentation(resourceModel);
|
||||||
|
}
|
||||||
|
}.call();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.keycloak.services.resources.admin;
|
package org.keycloak.services.resources.admin;
|
||||||
|
|
||||||
|
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||||
import org.jboss.resteasy.logging.Logger;
|
import org.jboss.resteasy.logging.Logger;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.services.managers.RealmManager;
|
import org.keycloak.services.managers.RealmManager;
|
||||||
|
@ -49,6 +50,7 @@ public class RealmsAdminResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
@NoCache
|
||||||
@Produces("application/json")
|
@Produces("application/json")
|
||||||
public Response getRealms() {
|
public Response getRealms() {
|
||||||
return new Transaction() {
|
return new Transaction() {
|
||||||
|
|
|
@ -76,6 +76,7 @@
|
||||||
"resources" : [
|
"resources" : [
|
||||||
{
|
{
|
||||||
"name" : "Application",
|
"name" : "Application",
|
||||||
|
"enabled" : true,
|
||||||
"roles" : [
|
"roles" : [
|
||||||
{ "name" : "admin" },
|
{ "name" : "admin" },
|
||||||
{ "name" : "user" }
|
{ "name" : "user" }
|
||||||
|
@ -97,8 +98,9 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name" : "OtherApp",
|
"name" : "OtherApp",
|
||||||
|
"enabled" : true,
|
||||||
"roles" : [
|
"roles" : [
|
||||||
{ "name" : "admin" },
|
{ "name" : "admin" },
|
||||||
{ "name" : "user" }
|
{ "name" : "user" }
|
||||||
|
|
Loading…
Reference in a new issue