Java tutorial
/** * Copyright 2012-2013 Trento RISE * * 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 it.smartcommunitylab.aac.controller; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.security.access.AccessDeniedException; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.servlet.ModelAndView; import it.smartcommunitylab.aac.Config; import it.smartcommunitylab.aac.apikey.APIKeyManager; import it.smartcommunitylab.aac.dto.APIKey; import it.smartcommunitylab.aac.manager.ClientDetailsManager; import it.smartcommunitylab.aac.manager.UserManager; import it.smartcommunitylab.aac.model.ClientAppBasic; import it.smartcommunitylab.aac.model.Response; import it.smartcommunitylab.aac.model.Role; import springfox.documentation.annotations.ApiIgnore; /** * Controller for performing the basic operations over the * client apps. * @author raman * */ @ApiIgnore @Controller public class AppController { private Log logger = LogFactory.getLog(getClass()); @Autowired private ClientDetailsManager clientDetailsAdapter; @Autowired private UserManager userManager; @Autowired private APIKeyManager keyManager; /** * Retrieve the with the user data: currently on the username is added. * @return */ @RequestMapping("/") public ModelAndView home() { return new ModelAndView("redirect:/dev"); } /** * Retrieve the with the user data: currently on the username is added. * @return */ @RequestMapping("/dev") public ModelAndView developer() { Map<String, Object> model = new HashMap<String, Object>(); String username = userManager.getUserFullName(); model.put("username", username); Set<String> userRoles = userManager.getUserRoles(); model.put("roles", userRoles); model.put("contexts", userManager.getUser().getRoles().stream().filter(r -> r.getRole().equals(Config.R_PROVIDER)) .map(Role::canonicalSpace).collect(Collectors.toSet())); String check = ":" + Config.R_PROVIDER; model.put("apiProvider", userRoles.stream().anyMatch(s -> s.endsWith(check))); return new ModelAndView("index", model); } /** * Read the * @return {@link Response} entity containing the list of client app {@link ClientAppBasic} descriptors */ @RequestMapping("/dev/apps") public @ResponseBody Response getAppList() { Response response = new Response(); // read all the apps associated to the signed user List<ClientAppBasic> list = clientDetailsAdapter.getByDeveloperId(userManager.getUserId()); response.setData(list); return response; } /** * Read the * @return {@link Response} entity containing the list of client app {@link ClientAppBasic} descriptors */ @RequestMapping("/dev/apps/{clientId}") public @ResponseBody Response getApp(@PathVariable String clientId) { Response response = new Response(); // read the app associated to the client ClientAppBasic app = clientDetailsAdapter.getByClientId(clientId); if (!app.getUserName().equals(userManager.getUserId().toString())) { throw new AccessDeniedException("Unauthorized"); } else { response.setData(app); } return response; } /** * create a new client app given a container with the name only * @param appData * @return {@link Response} entity containing the stored app {@link ClientAppBasic} descriptor * @throws Exception */ @RequestMapping(method = RequestMethod.POST, value = "/dev/apps") public @ResponseBody Response saveEmpty(@RequestBody ClientAppBasic appData) throws Exception { Response response = new Response(); response.setData(clientDetailsAdapter.create(appData, userManager.getUserId())); return response; } @RequestMapping(method = RequestMethod.POST, value = "/dev/apps/{clientId}") public @ResponseBody Response resetClientData(@PathVariable String clientId, @RequestParam String reset) { return reset(clientId, "clientSecretMobile".equals(reset)); } /** * Reset clientId or client secret * @param clientId * @param resetClientSecretMobile true to reset clientSecretMobile, false to reset clientSecret * @return {@link Response} entity containing the stored app {@link ClientAppBasic} descriptor */ protected Response reset(String clientId, boolean resetClientSecretMobile) { Response response = new Response(); userManager.checkClientIdOwnership(clientId); if (resetClientSecretMobile) { response.setData(clientDetailsAdapter.resetClientSecretMobile(clientId)); } else { response.setData(clientDetailsAdapter.resetClientSecret(clientId)); } return response; } /** * Delete the specified app * @param clientId * @return {@link Response} entity containing the deleted app {@link ClientAppBasic} descriptor */ @RequestMapping(method = RequestMethod.DELETE, value = "/dev/apps/{clientId}") public @ResponseBody Response delete(@PathVariable String clientId) { Response response = new Response(); userManager.checkClientIdOwnership(clientId); response.setData(clientDetailsAdapter.delete(clientId)); return response; } /** * Update the client app * @param data * @param clientId * @return {@link Response} entity containing the updated app {@link ClientAppBasic} descriptor */ @RequestMapping(method = RequestMethod.PUT, value = "/dev/apps/{clientId}") public @ResponseBody Response update(@RequestBody ClientAppBasic data, @PathVariable String clientId) { Response response = new Response(); userManager.checkClientIdOwnership(clientId); response.setData(clientDetailsAdapter.update(clientId, data)); return response; } /** * Delete a specified API key * @param apiKey * @return */ @DeleteMapping(value = "/dev/apikey/{clientId}/{apiKey:.*}") public @ResponseBody Response deleteKey(@PathVariable String clientId, @PathVariable String apiKey) { APIKey key = keyManager.findKey(apiKey); if (key != null) { userManager.checkClientIdOwnership(clientId); keyManager.deleteKey(apiKey); } return Response.ok(null); } /** * Delete a specified API key * @param apiKey * @return */ @PutMapping(value = "/dev/apikey/{clientId}/{apiKey:.*}") public @ResponseBody Response updateKey(@RequestBody APIKey body, @PathVariable String clientId, @PathVariable String apiKey) { APIKey key = keyManager.findKey(apiKey); if (key != null) { userManager.checkClientIdOwnership(clientId); if (body.getValidity() != null && body.getValidity() > 0) { key = keyManager.updateKeyValidity(apiKey, body.getValidity()); } if (body.getAdditionalInformation() != null) { key = keyManager.updateKeyData(apiKey, body.getAdditionalInformation()); } if (body.getScope() != null) { key = keyManager.updateKeyScopes(apiKey, body.getScope()); } return Response.ok(key); } return Response.error("Key not found"); } /** * Create an API key with the specified properties (validity and additional info) * @param apiKey * @return created entity */ @PostMapping(value = "/dev/apikey/{clientId}") public @ResponseBody Response createKey(@RequestBody APIKey body, @PathVariable String clientId) { APIKey keyObj = keyManager.createKey(clientId, body.getValidity(), body.getAdditionalInformation(), body.getScope()); return Response.ok(keyObj); } @GetMapping(value = "/dev/apikey/{clientId}") public @ResponseBody Response getClientKeys(@PathVariable String clientId) { return Response.ok(keyManager.getClientKeys(clientId)); } @ExceptionHandler(AccessDeniedException.class) @ResponseStatus(HttpStatus.UNAUTHORIZED) @ResponseBody public Response processAccessError(AccessDeniedException ex) { return Response.error(ex.getMessage()); } @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseBody public Response processValidationError(MethodArgumentNotValidException ex) { BindingResult br = ex.getBindingResult(); List<FieldError> fieldErrors = br.getFieldErrors(); StringBuilder builder = new StringBuilder(); fieldErrors.forEach(fe -> builder.append(fe.getDefaultMessage()).append("\n")); return Response.error(builder.toString()); } @ExceptionHandler(Exception.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseBody public Response processGenericError(Exception ex) { logger.error(ex.getMessage(), ex); return Response.error(ex.getMessage()); } }