@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;
      }
    }
  }
  /**
   * 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(
      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;
  }