@RequestMapping(method = RequestMethod.GET, produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
  public String listResourceSets(Model m, Authentication auth) {
    ensureOAuthScope(auth, SystemScopeService.UMA_PROTECTION_SCOPE);

    String owner = auth.getName();

    Collection<ResourceSet> resourceSets = Collections.emptySet();
    if (auth instanceof OAuth2Authentication) {
      // if it's an OAuth mediated call, it's on behalf of a client, so look that up too
      OAuth2Authentication o2a = (OAuth2Authentication) auth;
      resourceSets =
          resourceSetService.getAllForOwnerAndClient(owner, o2a.getOAuth2Request().getClientId());
    } else {
      // otherwise get everything for the current user
      resourceSets = resourceSetService.getAllForOwner(owner);
    }

    // build the entity here and send to the display

    Set<String> ids = new HashSet<>();
    for (ResourceSet resourceSet : resourceSets) {
      ids.add(
          resourceSet
              .getId()
              .toString()); // add them all as strings so that gson renders them properly
    }

    m.addAttribute(JsonEntityView.ENTITY, ids);
    return JsonEntityView.VIEWNAME;
  }
  @RequestMapping(
      value = "/{id}",
      method = RequestMethod.GET,
      produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
  public String readResourceSet(@PathVariable("id") Long id, Model m, Authentication auth) {
    ensureOAuthScope(auth, SystemScopeService.UMA_PROTECTION_SCOPE);

    ResourceSet rs = resourceSetService.getById(id);

    if (rs == null) {
      m.addAttribute("code", HttpStatus.NOT_FOUND);
      m.addAttribute("error", "not_found");
      return JsonErrorView.VIEWNAME;
    } else {

      rs = validateScopes(rs);

      if (!auth.getName().equals(rs.getOwner())) {

        logger.warn(
            "Unauthorized resource set request from wrong user; expected "
                + rs.getOwner()
                + " got "
                + auth.getName());

        // it wasn't issued to this user
        m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
        return JsonErrorView.VIEWNAME;
      } else {
        m.addAttribute(JsonEntityView.ENTITY, rs);
        return ResourceSetEntityView.VIEWNAME;
      }
    }
  }
  /**
   * Make sure the resource set doesn't have any restricted or reserved scopes.
   *
   * @param rs
   */
  private ResourceSet validateScopes(ResourceSet rs) {
    // scopes that the client is asking for
    Set<SystemScope> requestedScopes = scopeService.fromStrings(rs.getScopes());

    // the scopes that the resource set can have must be a subset of the dynamically allowed scopes
    Set<SystemScope> allowedScopes =
        scopeService.removeRestrictedAndReservedScopes(requestedScopes);

    rs.setScopes(scopeService.toStrings(allowedScopes));

    return rs;
  }
  @RequestMapping(
      value = "/{id}",
      method = RequestMethod.DELETE,
      produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
  public String deleteResourceSet(@PathVariable("id") Long id, Model m, Authentication auth) {
    ensureOAuthScope(auth, SystemScopeService.UMA_PROTECTION_SCOPE);

    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 if (auth instanceof OAuth2Authentication
          && !((OAuth2Authentication) auth)
              .getOAuth2Request()
              .getClientId()
              .equals(rs.getClientId())) {

        logger.warn(
            "Unauthorized resource set request from bad client; expected "
                + rs.getClientId()
                + " got "
                + ((OAuth2Authentication) auth).getOAuth2Request().getClientId());

        // it wasn't issued to this client
        m.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
        return JsonErrorView.VIEWNAME;
      } else {

        // user and client matched
        resourceSetService.remove(rs);

        m.addAttribute(HttpCodeView.CODE, HttpStatus.NO_CONTENT);
        return HttpCodeView.VIEWNAME;
      }
    }
  }
 /* (non-Javadoc)
  * @see org.mitre.uma.repository.PermissionRepository#getPermissionTicketsForResourceSet(org.mitre.uma.model.ResourceSet)
  */
 @Override
 public Collection<PermissionTicket> getPermissionTicketsForResourceSet(ResourceSet rs) {
   TypedQuery<PermissionTicket> query =
       em.createNamedQuery(PermissionTicket.QUERY_BY_RESOURCE_SET, PermissionTicket.class);
   query.setParameter(PermissionTicket.PARAM_RESOURCE_SET_ID, rs.getId());
   return query.getResultList();
 }
  private ResourceSet parseResourceSet(String jsonString) {

    try {
      JsonElement el = parser.parse(jsonString);

      if (el.isJsonObject()) {
        JsonObject o = el.getAsJsonObject();

        ResourceSet rs = new ResourceSet();
        rs.setId(getAsLong(o, "_id"));
        rs.setName(getAsString(o, "name"));
        rs.setIconUri(getAsString(o, "icon_uri"));
        rs.setType(getAsString(o, "type"));
        rs.setScopes(getAsStringSet(o, "scopes"));
        rs.setUri(getAsString(o, "uri"));

        return rs;
      }

      return null;

    } catch (JsonParseException e) {
      return null;
    }
  }
  @RequestMapping(
      value = "/{id}",
      method = RequestMethod.PUT,
      consumes = MimeTypeUtils.APPLICATION_JSON_VALUE,
      produces = MimeTypeUtils.APPLICATION_JSON_VALUE)
  public String updateResourceSet(
      @PathVariable("id") Long id, @RequestBody String jsonString, Model m, Authentication auth) {
    ensureOAuthScope(auth, SystemScopeService.UMA_PROTECTION_SCOPE);

    ResourceSet newRs = parseResourceSet(jsonString);

    if (newRs == null // there was no resource set in the body
        || Strings.isNullOrEmpty(newRs.getName()) // there was no name (required)
        || newRs.getScopes() == null // there were no scopes (required)
        || newRs.getId() == null
        || !newRs.getId().equals(id) // the IDs didn't match
    ) {

      logger.warn("Resource set registration missing one or more required fields.");

      m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
      m.addAttribute(
          JsonErrorView.ERROR_MESSAGE, "Resource request was missing one or more required fields.");
      return JsonErrorView.VIEWNAME;
    }

    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 {

        ResourceSet saved = resourceSetService.update(rs, newRs);

        m.addAttribute(JsonEntityView.ENTITY, saved);
        m.addAttribute(
            ResourceSetEntityAbbreviatedView.LOCATION, config.getIssuer() + URL + "/" + rs.getId());
        return ResourceSetEntityAbbreviatedView.VIEWNAME;
      }
    }
  }
  @RequestMapping(
      method = RequestMethod.POST,
      produces = MimeTypeUtils.APPLICATION_JSON_VALUE,
      consumes = MimeTypeUtils.APPLICATION_JSON_VALUE)
  public String createResourceSet(@RequestBody String jsonString, Model m, Authentication auth) {
    ensureOAuthScope(auth, SystemScopeService.UMA_PROTECTION_SCOPE);

    ResourceSet rs = parseResourceSet(jsonString);

    if (rs == null) { // there was no resource set in the body
      logger.warn("Resource set registration missing body.");

      m.addAttribute("code", HttpStatus.BAD_REQUEST);
      m.addAttribute("error_description", "Resource request was missing body.");
      return JsonErrorView.VIEWNAME;
    }

    if (auth instanceof OAuth2Authentication) {
      // if it's an OAuth mediated call, it's on behalf of a client, so store that
      OAuth2Authentication o2a = (OAuth2Authentication) auth;
      rs.setClientId(o2a.getOAuth2Request().getClientId());
      rs.setOwner(auth.getName()); // the username is going to be in the auth object
    } else {
      // this one shouldn't be called if it's not OAuth
      m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
      m.addAttribute(JsonErrorView.ERROR_MESSAGE, "This call must be made with an OAuth token");
      return JsonErrorView.VIEWNAME;
    }

    rs = validateScopes(rs);

    if (Strings.isNullOrEmpty(rs.getName()) // there was no name (required)
        || rs.getScopes() == null // there were no scopes (required)
    ) {

      logger.warn("Resource set registration missing one or more required fields.");

      m.addAttribute(HttpCodeView.CODE, HttpStatus.BAD_REQUEST);
      m.addAttribute(
          JsonErrorView.ERROR_MESSAGE, "Resource request was missing one or more required fields.");
      return JsonErrorView.VIEWNAME;
    }

    ResourceSet saved = resourceSetService.saveNew(rs);

    m.addAttribute(HttpCodeView.CODE, HttpStatus.CREATED);
    m.addAttribute(JsonEntityView.ENTITY, saved);
    m.addAttribute(
        ResourceSetEntityAbbreviatedView.LOCATION, config.getIssuer() + URL + "/" + saved.getId());

    return ResourceSetEntityAbbreviatedView.VIEWNAME;
  }