package com.ufund.api.ufundapi.controller; import java.io.IOException; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; 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.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.ufund.api.ufundapi.DuplicateKeyException; import com.ufund.api.ufundapi.model.User; import com.ufund.api.ufundapi.service.AuthService; import com.ufund.api.ufundapi.service.UserService; import static java.util.List.of; @RestController @RequestMapping("users") public class UserController { private static final Logger LOG = Logger.getLogger(UserController.class.getName()); private final UserService userService; private final AuthService authService; public UserController(UserService userService, AuthService authService) { this.userService = userService; this.authService = authService; } /** * Creates a User with the provided object * @param params A map consisting of the parameters for a user * @return OK response and the user if it was successful, INTERNAL_SERVER_ERROR * otherwise */ @PostMapping("") public ResponseEntity createUser(@RequestBody Map params) { LOG.log(Level.INFO, "POST /users body={0}", params); String username = params.get("username"); String password = params.get("password"); try { User user = userService.createUser(username, password); if (user != null) { return new ResponseEntity<>(user, HttpStatus.CREATED); } else { return new ResponseEntity<>(HttpStatus.CONFLICT); } } catch (DuplicateKeyException ex) { LOG.log(Level.WARNING, ex.getLocalizedMessage()); return new ResponseEntity<>(HttpStatus.CONFLICT); } catch (IOException ex) { LOG.log(Level.SEVERE, ex.getLocalizedMessage()); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } } /** * Responds to the GET request for a {@linkplain User user} for the given id * * @param username The name of the user * @param key The authentication key of the user * @return ResponseEntity with {@link User user} object and HTTP status of OK if * found
* ResponseEntity with HTTP status of NOT_FOUND if not found
* ResponseEntity with HTTP status of INTERNAL_SERVER_ERROR otherwise */ @GetMapping("/{username}") public ResponseEntity getUser(@PathVariable String username, @RequestHeader("jelly-api-key") String key) { LOG.log(Level.INFO, "GET /user/{0} key={1}", of(username, key)); try { authService.authenticate(username, key); User user = userService.getUser(username); if (user != null) { return new ResponseEntity<>(user.withoutPasswordHash(), HttpStatus.OK); } else { return new ResponseEntity<>(HttpStatus.NOT_FOUND); } } catch (IllegalAccessException ex) { LOG.log(Level.WARNING, ex.getLocalizedMessage()); return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); } catch (IOException ex) { LOG.log(Level.SEVERE, ex.getLocalizedMessage()); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } } /** * Updates a User with the provided one * * @param user The user to update * @param username The name of the user * @param key The authentication key of the user * @return OK response and the user if it was successful, or * INTERNAL_SERVER_ERROR if there was an issue */ @PutMapping("/{username}") public ResponseEntity updateUser(@RequestBody User user, @PathVariable String username, @RequestHeader("jelly-api-key") String key) { LOG.log(Level.INFO,"PUT /users/{0} body={1} key={2}", of(username, user, key)); try { authService.authenticate(username, key); user = userService.updateUser(user, username); if (user != null) { return new ResponseEntity<>(user, HttpStatus.OK); } else { return new ResponseEntity<>(HttpStatus.NOT_FOUND); } } catch (IllegalArgumentException ex) { LOG.log(Level.WARNING, ex.getLocalizedMessage()); return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } catch (IllegalAccessException ex) { LOG.log(Level.WARNING, ex.getLocalizedMessage()); return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); } catch (IOException ex) { LOG.log(Level.SEVERE, ex.getLocalizedMessage()); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } } /** * Deletes a user with the desired name * * @param username The name of the user * @param key The authentication key of the user * @return OK if the user was deleted, NOT_FOUND if the user was not found, or * INTERNAL_SERVER_ERROR if an error occurred */ @DeleteMapping("/{username}") public ResponseEntity deleteUser(@PathVariable String username, @RequestHeader("jelly-api-key") String key) { LOG.log(Level.INFO, "DELETE /users/{0} id={1}", of(username, key)); try { authService.authenticate(username, key); if (userService.deleteUser(username)) { return new ResponseEntity<>(HttpStatus.OK); } else { return new ResponseEntity<>(HttpStatus.NOT_FOUND); } } catch (IllegalAccessException ex) { LOG.log(Level.WARNING, ex.getLocalizedMessage()); return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); } catch (IOException ex) { LOG.log(Level.SEVERE, ex.getLocalizedMessage()); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } } }