001/******************************************************************************* 002 * Copyright 2017 The MIT Internet Trust Consortium 003 * 004 * Portions copyright 2011-2013 The MITRE Corporation 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 *******************************************************************************/ 018/** 019 * 020 */ 021package org.mitre.oauth2.web; 022 023import java.util.Set; 024 025import org.mitre.oauth2.model.SystemScope; 026import org.mitre.oauth2.service.SystemScopeService; 027import org.mitre.openid.connect.view.HttpCodeView; 028import org.mitre.openid.connect.view.JsonEntityView; 029import org.mitre.openid.connect.view.JsonErrorView; 030import org.mitre.openid.connect.web.RootController; 031import org.slf4j.Logger; 032import org.slf4j.LoggerFactory; 033import org.springframework.beans.factory.annotation.Autowired; 034import org.springframework.http.HttpStatus; 035import org.springframework.http.MediaType; 036import org.springframework.security.access.prepost.PreAuthorize; 037import org.springframework.stereotype.Controller; 038import org.springframework.ui.ModelMap; 039import org.springframework.web.bind.annotation.PathVariable; 040import org.springframework.web.bind.annotation.RequestBody; 041import org.springframework.web.bind.annotation.RequestMapping; 042import org.springframework.web.bind.annotation.RequestMethod; 043 044import com.google.gson.Gson; 045 046/** 047 * @author jricher 048 * 049 */ 050@Controller 051@RequestMapping("/" + ScopeAPI.URL) 052@PreAuthorize("hasRole('ROLE_USER')") 053public class ScopeAPI { 054 055 public static final String URL = RootController.API_URL + "/scopes"; 056 057 @Autowired 058 private SystemScopeService scopeService; 059 060 /** 061 * Logger for this class 062 */ 063 private static final Logger logger = LoggerFactory.getLogger(ScopeAPI.class); 064 065 private Gson gson = new Gson(); 066 067 @RequestMapping(value = "", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) 068 public String getAll(ModelMap m) { 069 070 Set<SystemScope> allScopes = scopeService.getAll(); 071 072 m.put(JsonEntityView.ENTITY, allScopes); 073 074 return JsonEntityView.VIEWNAME; 075 } 076 077 @RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) 078 public String getScope(@PathVariable("id") Long id, ModelMap m) { 079 080 SystemScope scope = scopeService.getById(id); 081 082 if (scope != null) { 083 084 m.put(JsonEntityView.ENTITY, scope); 085 086 return JsonEntityView.VIEWNAME; 087 } else { 088 089 logger.error("getScope failed; scope not found: " + id); 090 091 m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND); 092 m.put(JsonErrorView.ERROR_MESSAGE, "The requested scope with id " + id + " could not be found."); 093 return JsonErrorView.VIEWNAME; 094 } 095 } 096 097 @PreAuthorize("hasRole('ROLE_ADMIN')") 098 @RequestMapping(value = "/{id}", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) 099 public String updateScope(@PathVariable("id") Long id, @RequestBody String json, ModelMap m) { 100 101 SystemScope existing = scopeService.getById(id); 102 103 SystemScope scope = gson.fromJson(json, SystemScope.class); 104 105 if (existing != null && scope != null) { 106 107 if (existing.getId().equals(scope.getId())) { 108 // sanity check 109 110 scope = scopeService.save(scope); 111 112 m.put(JsonEntityView.ENTITY, scope); 113 114 return JsonEntityView.VIEWNAME; 115 } else { 116 117 logger.error("updateScope failed; scope ids to not match: got " 118 + existing.getId() + " and " + scope.getId()); 119 120 m.put(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); 121 m.put(JsonErrorView.ERROR_MESSAGE, "Could not update scope. Scope ids to not match: got " 122 + existing.getId() + " and " + scope.getId()); 123 return JsonErrorView.VIEWNAME; 124 } 125 126 } else { 127 128 logger.error("updateScope failed; scope with id " + id + " not found."); 129 m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND); 130 m.put(JsonErrorView.ERROR_MESSAGE, "Could not update scope. The scope with id " + id + " could not be found."); 131 return JsonErrorView.VIEWNAME; 132 } 133 } 134 135 @PreAuthorize("hasRole('ROLE_ADMIN')") 136 @RequestMapping(value = "", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE) 137 public String createScope(@RequestBody String json, ModelMap m) { 138 SystemScope scope = gson.fromJson(json, SystemScope.class); 139 140 SystemScope alreadyExists = scopeService.getByValue(scope.getValue()); 141 if (alreadyExists != null) { 142 //Error, cannot save a scope with the same value as an existing one 143 logger.error("Error: attempting to save a scope with a value that already exists: " + scope.getValue()); 144 m.put(HttpCodeView.CODE, HttpStatus.CONFLICT); 145 m.put(JsonErrorView.ERROR_MESSAGE, "A scope with value " + scope.getValue() + " already exists, please choose a different value."); 146 return JsonErrorView.VIEWNAME; 147 } 148 149 scope = scopeService.save(scope); 150 151 if (scope != null && scope.getId() != null) { 152 153 m.put(JsonEntityView.ENTITY, scope); 154 155 return JsonEntityView.VIEWNAME; 156 } else { 157 158 logger.error("createScope failed; JSON was invalid: " + json); 159 m.put(HttpCodeView.CODE, HttpStatus.BAD_REQUEST); 160 m.put(JsonErrorView.ERROR_MESSAGE, "Could not save new scope " + scope + ". The scope service failed to return a saved entity."); 161 return JsonErrorView.VIEWNAME; 162 163 } 164 } 165 166 @PreAuthorize("hasRole('ROLE_ADMIN')") 167 @RequestMapping(value = "/{id}", method = RequestMethod.DELETE) 168 public String deleteScope(@PathVariable("id") Long id, ModelMap m) { 169 SystemScope existing = scopeService.getById(id); 170 171 if (existing != null) { 172 173 scopeService.remove(existing); 174 175 return HttpCodeView.VIEWNAME; 176 } else { 177 178 logger.error("deleteScope failed; scope with id " + id + " not found."); 179 m.put(HttpCodeView.CODE, HttpStatus.NOT_FOUND); 180 m.put(JsonErrorView.ERROR_MESSAGE, "Could not delete scope. The requested scope with id " + id + " could not be found."); 181 return JsonErrorView.VIEWNAME; 182 } 183 } 184}