resource rest api

This commit is contained in:
Bill Burke 2013-08-04 12:57:12 -04:00
parent 4e61981b69
commit d11876f58e
14 changed files with 146 additions and 16 deletions

View file

@ -11,6 +11,7 @@ import java.util.Set;
*/
public class ResourceRepresentation {
protected String self; // link
protected String id;
protected String name;
protected String adminUrl;
protected boolean surrogateAuthRequired;
@ -29,6 +30,14 @@ public class ResourceRepresentation {
this.self = self;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}

View file

@ -72,6 +72,7 @@
"resources" : [
{
"name" : "customer-portal",
"enabled" : true,
"adminUrl" : "http://localhost:8080/customer-portal/j_admin_request",
"useRealmMappings" : true,
"credentials" : [
@ -81,6 +82,7 @@
},
{
"name" : "product-portal",
"enabled" : true,
"adminUrl" : "http://localhost:8080/product-portal/j_admin_request",
"useRealmMappings" : true,
"credentials" : [

View file

@ -67,7 +67,7 @@
</section>
<section class="info-area">
<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>
<li><strong>Domain:</strong> 10.0.0.1</li>
<li><strong>Zone:</strong> Live</li>

View file

@ -27,6 +27,7 @@ public class ResourceManager {
public ResourceModel createResource(RealmModel realm, RoleModel loginRole, ResourceRepresentation resourceRep) {
ResourceModel resource = realm.addResource(resourceRep.getName());
resource.setEnabled(resourceRep.isEnabled());
resource.setManagementUrl(resourceRep.getAdminUrl());
resource.setSurrogateAuthRequired(resourceRep.isSurrogateAuthRequired());
resource.updateResource();
@ -82,16 +83,22 @@ public class ResourceManager {
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();
rep.setId(resourceModel.getId());
rep.setName(resourceModel.getName());
rep.setEnabled(resourceModel.isEnabled());
rep.setAdminUrl(resourceModel.getManagementUrl());
rep.setSurrogateAuthRequired(resourceModel.isSurrogateAuthRequired());
List<RoleModel> roles = resourceModel.getRoles();
for (RoleModel role : roles) {
rep.role(realmManager.toRepresentation(role));
}
return rep;
}

View file

@ -9,14 +9,10 @@ import org.keycloak.services.models.RealmModel;
import org.keycloak.services.models.ResourceModel;
import org.keycloak.services.models.RoleModel;
import org.keycloak.services.models.UserModel;
import org.keycloak.services.resources.RealmsResource;
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.UnsupportedEncodingException;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -135,7 +131,7 @@ public class TokenManager {
}
if (accessCodeEntry.getResourceRolesRequested().size() > 0) {
Map<String, ResourceModel> resourceMap = realm.getResourceMap();
Map<String, ResourceModel> resourceMap = realm.getResourceNameMap();
for (String resourceName : accessCodeEntry.getResourceRolesRequested().keySet()) {
ResourceModel resource = resourceMap.get(resourceName);
SkeletonKeyToken.Access access = token.addAccess(resourceName).verifyCaller(resource.isSurrogateAuthRequired());

View file

@ -79,7 +79,7 @@ public interface RealmModel {
List<RoleModel> getRoles();
Map<String, ResourceModel> getResourceMap();
Map<String, ResourceModel> getResourceNameMap();
List<ResourceModel> getResources();
@ -110,4 +110,6 @@ public interface RealmModel {
List<RequiredCredentialModel> getOAuthClientRequiredCredentials();
boolean hasRole(UserModel user, String role);
ResourceModel getResourceById(String id);
}

View file

@ -416,7 +416,7 @@ public class RealmAdapter implements RealmModel {
* @return
*/
@Override
public Map<String, ResourceModel> getResourceMap() {
public Map<String, ResourceModel> getResourceNameMap() {
Map<String, ResourceModel> resourceMap = new HashMap<String, ResourceModel>();
for (ResourceModel resource : getResources()) {
resourceMap.put(resource.getName(), resource);
@ -424,6 +424,24 @@ public class RealmAdapter implements RealmModel {
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
public List<ResourceModel> getResources() {
RelationshipQuery<ResourceRelationship> query = getRelationshipManager().createRelationshipQuery(ResourceRelationship.class);

View file

@ -14,6 +14,7 @@ public class ResourceRelationship extends AbstractAttributedType implements Rela
private static final long serialVersionUID = 1L;
public static final AttributeParameter REALM = new AttributeParameter("realm");
public static final AttributeParameter RESOURCE = new AttributeParameter("resource");
public ResourceRelationship() {
}

View file

@ -1,5 +1,6 @@
package org.keycloak.services.resources;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.logging.Logger;
import org.keycloak.representations.idm.PublishedRealmRepresentation;
import org.keycloak.services.models.KeycloakSession;
@ -37,6 +38,7 @@ public class PublicRealmResource {
}
@GET
@NoCache
@Produces("application/json")
public PublishedRealmRepresentation getRealm(@PathParam("realm") String id) {
return new Transaction() {
@ -47,6 +49,7 @@ public class PublicRealmResource {
}
@GET
@NoCache
@Path("html")
@Produces("text/html")
public String getRealmHtml(@PathParam("realm") String id) {

View file

@ -1,5 +1,6 @@
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.JWSInput;
import org.jboss.resteasy.jose.jws.crypto.RSAProvider;
@ -381,6 +382,7 @@ public class TokenService extends AbstractLoginService {
@Path("logout")
@GET
@NoCache
public Response logout(final @QueryParam("redirect_uri") String redirectUri) {
return new Transaction() {
protected Response callImpl() {

View file

@ -1,5 +1,6 @@
package org.keycloak.services.resources.admin;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.logging.Logger;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RoleRepresentation;
@ -47,7 +48,13 @@ public class RealmAdminResource {
this.realm = realm;
}
@Path("resources")
public RealmResourcesResource getResources() {
return new RealmResourcesResource(admin, realm);
}
@GET
@NoCache
@Produces("application/json")
public RealmRepresentation getRealm() {
return new Transaction() {
@ -70,6 +77,7 @@ public class RealmAdminResource {
@Path("roles")
@GET
@NoCache
@Produces("application/json")
public List<RoleRepresentation> getRoles() {
return new Transaction() {
@ -88,6 +96,7 @@ public class RealmAdminResource {
@Path("roles/{id}")
@GET
@NoCache
@Produces("application/json")
public RoleRepresentation getRole(final @PathParam("id") String id) {
return new Transaction() {
@ -147,6 +156,7 @@ public class RealmAdminResource {
@Path("users")
@GET
@NoCache
@Produces("application/json")
public List<UserRepresentation> getUsers() {
return null;

View file

@ -1,13 +1,28 @@
package org.keycloak.services.resources.admin;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.logging.Logger;
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.ResourceModel;
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.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.core.Context;
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;
/**
@ -26,7 +41,68 @@ public class RealmResourcesResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
List<ResourceRepresentation> getResources() {
return null;
@NoCache
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();
}
}

View file

@ -1,5 +1,6 @@
package org.keycloak.services.resources.admin;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.logging.Logger;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.services.managers.RealmManager;
@ -49,6 +50,7 @@ public class RealmsAdminResource {
}
@GET
@NoCache
@Produces("application/json")
public Response getRealms() {
return new Transaction() {

View file

@ -76,6 +76,7 @@
"resources" : [
{
"name" : "Application",
"enabled" : true,
"roles" : [
{ "name" : "admin" },
{ "name" : "user" }
@ -97,8 +98,9 @@
}
]
},
{
{
"name" : "OtherApp",
"enabled" : true,
"roles" : [
{ "name" : "admin" },
{ "name" : "user" }