made Policy API fit the new data model (used to be Claims API)
parent
d7af4b2cf9
commit
f0d628bf27
|
@ -1,162 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2015 The MITRE Corporation
|
||||
* and the MIT Kerberos and Internet Trust Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
|
||||
package org.mitre.uma.web;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mitre.oauth2.service.SystemScopeService;
|
||||
import org.mitre.openid.connect.view.HttpCodeView;
|
||||
import org.mitre.openid.connect.view.JsonEntityView;
|
||||
import org.mitre.openid.connect.view.JsonErrorView;
|
||||
import org.mitre.openid.connect.web.RootController;
|
||||
import org.mitre.uma.model.Claim;
|
||||
import org.mitre.uma.model.Policy;
|
||||
import org.mitre.uma.model.ResourceSet;
|
||||
import org.mitre.uma.service.ResourceSetService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import static org.mitre.oauth2.web.AuthenticationUtilities.ensureOAuthScope;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
*
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/" + ClaimsAPI.URL)
|
||||
@PreAuthorize("hasRole('ROLE_USER')")
|
||||
public class ClaimsAPI {
|
||||
|
||||
//
|
||||
//
|
||||
// FIXME
|
||||
//
|
||||
//
|
||||
|
||||
// Logger for this class
|
||||
private static final Logger logger = LoggerFactory.getLogger(ClaimsAPI.class);
|
||||
|
||||
public static final String URL = RootController.API_URL + "/claims";
|
||||
|
||||
@Autowired
|
||||
private ResourceSetService resourceSetService;
|
||||
|
||||
@RequestMapping(value = "", method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
|
||||
public String getResourceSetsForCurrentUser(Model m, Authentication auth) {
|
||||
|
||||
Collection<ResourceSet> resourceSets = resourceSetService.getAllForOwner(auth.getName());
|
||||
|
||||
m.addAttribute(JsonEntityView.ENTITY, resourceSets);
|
||||
|
||||
return JsonEntityView.VIEWNAME;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/{rsid}", method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
|
||||
public String getClaimsForResourceSet(@PathVariable (value = "rsid") Long rsid, Model m, Authentication auth) {
|
||||
|
||||
ResourceSet rs = resourceSetService.getById(rsid);
|
||||
|
||||
if (rs == null) {
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
if (!rs.getOwner().equals(auth.getName())) {
|
||||
// authenticated user didn't match the owner of the resource set
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
m.addAttribute(JsonEntityView.ENTITY, rs.getPolicies());
|
||||
|
||||
return JsonEntityView.VIEWNAME;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/{rsid}", method = RequestMethod.PUT, consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
|
||||
public String setClaimsForResourceSet(@PathVariable (value = "rsid") Long rsid, @RequestBody String jsonString, Model m, Authentication auth) {
|
||||
|
||||
ResourceSet rs = resourceSetService.getById(rsid);
|
||||
|
||||
if (rs == null) {
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
if (!rs.getOwner().equals(auth.getName())) {
|
||||
// authenticated user didn't match the owner of the resource set
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
Set<Claim> claims = (new Gson()).fromJson(jsonString, new TypeToken<Set<Claim>>() {}.getType());
|
||||
|
||||
//rs.setClaimsRequired(claims);
|
||||
|
||||
resourceSetService.update(rs, rs);
|
||||
|
||||
m.addAttribute(JsonEntityView.ENTITY, rs.getPolicies());
|
||||
|
||||
return JsonEntityView.VIEWNAME;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/{rsid}", method = RequestMethod.DELETE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
|
||||
public String deleteResourceSet(@PathVariable ("rsid") Long id, Model m, Authentication auth) {
|
||||
|
||||
ResourceSet rs = resourceSetService.getById(id);
|
||||
|
||||
if (rs == null) {
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.addAttribute(JsonErrorView.ERROR, "not_found");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else {
|
||||
if (!auth.getName().equals(rs.getOwner())) {
|
||||
|
||||
logger.warn("Unauthorized resource set request from bad user; expected " + rs.getOwner() + " got " + auth.getName());
|
||||
|
||||
// it wasn't issued to this user
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
|
||||
return JsonErrorView.VIEWNAME;
|
||||
} else {
|
||||
|
||||
resourceSetService.remove(rs);
|
||||
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.NO_CONTENT);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,330 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2015 The MITRE Corporation
|
||||
* and the MIT Kerberos and Internet Trust Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
|
||||
package org.mitre.uma.web;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mitre.openid.connect.view.HttpCodeView;
|
||||
import org.mitre.openid.connect.view.JsonEntityView;
|
||||
import org.mitre.openid.connect.view.JsonErrorView;
|
||||
import org.mitre.openid.connect.web.RootController;
|
||||
import org.mitre.uma.model.Claim;
|
||||
import org.mitre.uma.model.Policy;
|
||||
import org.mitre.uma.model.ResourceSet;
|
||||
import org.mitre.uma.service.ResourceSetService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
/**
|
||||
* API for managing policies on resource sets.
|
||||
*
|
||||
* @author jricher
|
||||
*
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/" + PolicyAPI.URL)
|
||||
@PreAuthorize("hasRole('ROLE_USER')")
|
||||
public class PolicyAPI {
|
||||
|
||||
// Logger for this class
|
||||
private static final Logger logger = LoggerFactory.getLogger(PolicyAPI.class);
|
||||
|
||||
public static final String URL = RootController.API_URL + "/policy";
|
||||
|
||||
private Gson gson = new Gson();
|
||||
|
||||
@Autowired
|
||||
private ResourceSetService resourceSetService;
|
||||
|
||||
/**
|
||||
* List all resource sets for the current user
|
||||
* @param m
|
||||
* @param auth
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "", method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
|
||||
public String getResourceSetsForCurrentUser(Model m, Authentication auth) {
|
||||
|
||||
Collection<ResourceSet> resourceSets = resourceSetService.getAllForOwner(auth.getName());
|
||||
|
||||
m.addAttribute(JsonEntityView.ENTITY, resourceSets);
|
||||
|
||||
return JsonEntityView.VIEWNAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* List all the policies for the given resource set
|
||||
* @param rsid
|
||||
* @param m
|
||||
* @param auth
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/{rsid}", method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
|
||||
public String getPoliciesForResourceSet(@PathVariable (value = "rsid") Long rsid, Model m, Authentication auth) {
|
||||
|
||||
ResourceSet rs = resourceSetService.getById(rsid);
|
||||
|
||||
if (rs == null) {
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
if (!rs.getOwner().equals(auth.getName())) {
|
||||
logger.warn("Unauthorized resource set request from bad user; expected " + rs.getOwner() + " got " + auth.getName());
|
||||
|
||||
// authenticated user didn't match the owner of the resource set
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
m.addAttribute(JsonEntityView.ENTITY, rs.getPolicies());
|
||||
|
||||
return JsonEntityView.VIEWNAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new policy on the given resource set
|
||||
* @param rsid
|
||||
* @param m
|
||||
* @param auth
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/{rsid}", method = RequestMethod.POST, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
|
||||
public String createNewPolicyForResourceSet(@PathVariable (value = "rsid") Long rsid, @RequestBody String jsonString, Model m, Authentication auth) {
|
||||
ResourceSet rs = resourceSetService.getById(rsid);
|
||||
|
||||
if (rs == null) {
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
if (!rs.getOwner().equals(auth.getName())) {
|
||||
logger.warn("Unauthorized resource set request from bad user; expected " + rs.getOwner() + " got " + auth.getName());
|
||||
|
||||
// authenticated user didn't match the owner of the resource set
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
Policy p = gson.fromJson(jsonString, Policy.class);
|
||||
|
||||
if (p.getId() != null) {
|
||||
logger.warn("Tried to add a policy with a non-null ID: " + p.getId());
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
for (Claim claim : p.getClaimsRequired()) {
|
||||
if (claim.getId() != null) {
|
||||
logger.warn("Tried to add a policy with a non-null claim ID: " + claim.getId());
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
}
|
||||
|
||||
rs.getPolicies().add(p);
|
||||
ResourceSet saved = resourceSetService.update(rs, rs);
|
||||
|
||||
// find the new policy object
|
||||
Collection<Policy> newPolicies = Sets.difference(new HashSet<>(saved.getPolicies()), new HashSet<>(rs.getPolicies()));
|
||||
|
||||
if (newPolicies.size() == 1) {
|
||||
Policy newPolicy = newPolicies.iterator().next();
|
||||
m.addAttribute(JsonEntityView.ENTITY, newPolicy);
|
||||
return JsonEntityView.VIEWNAME;
|
||||
} else {
|
||||
logger.warn("Unexpected result trying to add a new policy object: " + newPolicies);
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific policy
|
||||
* @param rsid
|
||||
* @param pid
|
||||
* @param m
|
||||
* @param auth
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/{rsid}/{pid}", method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
|
||||
public String getPolicy(@PathVariable (value = "rsid") Long rsid, @PathVariable (value = "pid") Long pid, Model m, Authentication auth) {
|
||||
|
||||
ResourceSet rs = resourceSetService.getById(rsid);
|
||||
|
||||
if (rs == null) {
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
if (!rs.getOwner().equals(auth.getName())) {
|
||||
logger.warn("Unauthorized resource set request from bad user; expected " + rs.getOwner() + " got " + auth.getName());
|
||||
|
||||
// authenticated user didn't match the owner of the resource set
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
for (Policy policy : rs.getPolicies()) {
|
||||
if (policy.getId().equals(pid)) {
|
||||
// found it!
|
||||
m.addAttribute(JsonEntityView.ENTITY, policy);
|
||||
return JsonEntityView.VIEWNAME;
|
||||
}
|
||||
}
|
||||
|
||||
// if we made it this far, we haven't found it
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a specific policy
|
||||
* @param rsid
|
||||
* @param pid
|
||||
* @param jsonString
|
||||
* @param m
|
||||
* @param auth
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/{rsid}/{pid}", method = RequestMethod.PUT, consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
|
||||
public String setClaimsForResourceSet(@PathVariable (value = "rsid") Long rsid, @PathVariable (value = "pid") Long pid, @RequestBody String jsonString, Model m, Authentication auth) {
|
||||
|
||||
ResourceSet rs = resourceSetService.getById(rsid);
|
||||
|
||||
if (rs == null) {
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
if (!rs.getOwner().equals(auth.getName())) {
|
||||
logger.warn("Unauthorized resource set request from bad user; expected " + rs.getOwner() + " got " + auth.getName());
|
||||
|
||||
// authenticated user didn't match the owner of the resource set
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
Policy p = gson.fromJson(jsonString, Policy.class);
|
||||
|
||||
if (!pid.equals(p.getId())) {
|
||||
logger.warn("Policy ID mismatch, expected " + pid + " got " + p.getId());
|
||||
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
for (Policy policy : rs.getPolicies()) {
|
||||
if (policy.getId().equals(pid)) {
|
||||
// found it!
|
||||
|
||||
// find the existing claim IDs, make sure we're not overwriting anything from another policy
|
||||
Set<Long> claimIds = new HashSet<>();
|
||||
for (Claim claim : policy.getClaimsRequired()) {
|
||||
claimIds.add(claim.getId());
|
||||
}
|
||||
|
||||
for (Claim claim : p.getClaimsRequired()) {
|
||||
if (claim.getId() != null && !claimIds.contains(claim.getId())) {
|
||||
logger.warn("Tried to add a policy with a an unmatched claim ID: got " + claim.getId() + " expected " + claimIds);
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
}
|
||||
|
||||
// update the existing object with the new values
|
||||
policy.setClaimsRequired(p.getClaimsRequired());
|
||||
policy.setName(p.getName());
|
||||
policy.setScopes(p.getScopes());
|
||||
|
||||
resourceSetService.update(rs, rs);
|
||||
|
||||
m.addAttribute(JsonEntityView.ENTITY, policy);
|
||||
return JsonEntityView.VIEWNAME;
|
||||
}
|
||||
}
|
||||
|
||||
// if we made it this far, we haven't found it
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a specific policy
|
||||
* @param rsid
|
||||
* @param pid
|
||||
* @param m
|
||||
* @param auth
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value = "/{rsid}/{pid}", method = RequestMethod.DELETE, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
|
||||
public String deleteResourceSet(@PathVariable ("rsid") Long rsid, @PathVariable (value = "pid") Long pid, Model m, Authentication auth) {
|
||||
|
||||
ResourceSet rs = resourceSetService.getById(rsid);
|
||||
|
||||
if (rs == null) {
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
m.addAttribute(JsonErrorView.ERROR, "not_found");
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
||||
if (!auth.getName().equals(rs.getOwner())) {
|
||||
|
||||
logger.warn("Unauthorized resource set request from bad user; expected " + rs.getOwner() + " got " + auth.getName());
|
||||
|
||||
// it wasn't issued to this user
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
|
||||
return JsonErrorView.VIEWNAME;
|
||||
}
|
||||
|
||||
|
||||
for (Policy policy : rs.getPolicies()) {
|
||||
if (policy.getId().equals(pid)) {
|
||||
// found it!
|
||||
rs.getPolicies().remove(policy);
|
||||
resourceSetService.update(rs, rs);
|
||||
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.NO_CONTENT);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
}
|
||||
}
|
||||
|
||||
// if we made it this far, we haven't found it
|
||||
m.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
|
||||
return HttpCodeView.VIEWNAME;
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue