package com.mif13.authServer.controllers; import com.mif13.authServer.dao.UsersDao; import com.mif13.authServer.exception.InvalidPasswordException; import com.mif13.authServer.exception.UserCreationException; import com.mif13.authServer.model.User; import java.util.Optional; import java.util.regex.PatternSyntaxException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.ModelAndView; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; @RestController @RequestMapping(value = "users") public class UserRestController { private final UsersDao usersRepo; @Autowired public UserRestController(UsersDao usersRepo) { this.usersRepo = usersRepo; } @Operation(summary = "Get user informations by id") @ApiResponses(value = { @ApiResponse( responseCode = "200", description = "Found the user", content = { @Content( mediaType = "application/json", schema = @Schema(implementation = User.class) ), @Content( mediaType = "application/xml", schema = @Schema(implementation = User.class) ), @Content( mediaType = "text/html" ) }), @ApiResponse( responseCode = "404", description = "User not found", content = { @Content() } )} ) @GetMapping(value = "/{id}", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}) @CrossOrigin(origins = {"http://localhost", "http://192.168.75.68", "https://192.168.75.68"}) public ResponseEntity<User> getUserAsJsonOrXml(@PathVariable String id) { ResponseEntity<User> response; Optional<User> optionalUser = usersRepo.get(id); if (optionalUser.isPresent()) { User user = optionalUser.get(); response = new ResponseEntity<>(user, HttpStatus.OK); response.getHeaders().add("Access-Control-Allow-Methods","GET"); response.getHeaders().add("Access-Control-Allow-Headers", "Authorization"); response.getHeaders().add("Access-Control-Max-Age", "1728000"); return response; } else { response = new ResponseEntity<>(HttpStatus.NOT_FOUND); } return response; } @GetMapping(value = "/{id}", produces = MediaType.TEXT_HTML_VALUE) public ModelAndView getUserAsHtml(@PathVariable String id, Model model) { // "user" nom du template HTML (sans extension) ModelAndView modelAndView = new ModelAndView("user"); Optional<User> optionalUser = usersRepo.get(id); if (optionalUser.isPresent()) { User user = optionalUser.get(); // on initialise les variables du template model.addAttribute("user", user); modelAndView.setStatus(HttpStatus.OK); } else { model.addAttribute("id", id); modelAndView.setStatus(HttpStatus.NOT_FOUND); } return modelAndView; } private ResponseEntity<Void> createUser(User user) { ResponseEntity<Void> response; try { Optional<User> optionalUser = usersRepo.get(user.getLogin()); if (optionalUser.isEmpty()) { usersRepo.save(user); response = new ResponseEntity<>(HttpStatus.CREATED); } else { response = new ResponseEntity<>(HttpStatus.FORBIDDEN); } } catch (PatternSyntaxException e) { e.printStackTrace(); response = new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } return response; } @Operation(summary = "Create a new user") @ApiResponses(value = { @ApiResponse( responseCode = "201 Created", description = "User is correctely created", content = { @Content( mediaType = "application/json", schema = @Schema(implementation = User.class) ), @Content( mediaType = "application/xml", schema = @Schema(implementation = User.class) ), @Content( mediaType = "text/html" ) }), @ApiResponse( responseCode = "403 Forbidden", description = "User not created", content = { @Content() } ), @ApiResponse( responseCode = "500 Internal Server Error", description = "", content = { @Content() } ) }) @PostMapping(consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) public ResponseEntity<Void> createUserFromUrlEncoded(@RequestParam("login") String login, @RequestParam("password") String password) { ResponseEntity<Void> response; try { User user = new User(login, password); response = createUser(user); } catch (UserCreationException e) { e.printStackTrace(); response = new ResponseEntity<>(HttpStatus.BAD_REQUEST); } return response; } /** * Cree un User a partir d'un JSON. * * /!\ Attention /!\ * Renvoie 400 BAD_REQUEST si le login ou le password sont invalides * (et produit une HttpMessageNotReadableException) * * @param user JSON converti en User (converter de Spring) * @return contenu vide **/ @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<Void> createUserFromJson(@RequestBody User user) { return createUser(user); } @Operation(summary = "Modify password of a user by its id") @ApiResponses(value = { @ApiResponse( responseCode = "204 No Content", description = "Password is correctly modified", content = { @Content() } ), @ApiResponse( responseCode = "404 Not Found", description = "", content = { @Content() } ), @ApiResponse( responseCode = "500 Internal Server Error", description = "", content = { @Content() } ) }) @PutMapping("/{id}") public ResponseEntity<Void> modifyUserPassword(@PathVariable String id, @RequestParam("new_password") String newPassword) { ResponseEntity<Void> response; Optional<User> optionalUser = usersRepo.get(id); if (optionalUser.isPresent()) { User user = optionalUser.get(); try { if (User.verifyPassword(newPassword)) { user.setPassword(newPassword); response = new ResponseEntity<>(HttpStatus.NO_CONTENT); } else { throw new InvalidPasswordException("Password is too weak"); } } catch (InvalidPasswordException e) { e.printStackTrace(); response = new ResponseEntity<>(HttpStatus.BAD_REQUEST); } } else { response = new ResponseEntity<>(HttpStatus.NOT_FOUND); } return response; } @Operation(summary = "Delete a user on the database, by its id") @ApiResponses(value = { @ApiResponse( responseCode = "204 No Content", description = "User deleted with success", content = { @Content() } ), @ApiResponse( responseCode = "404 Not Found", description = "", content = { @Content() } ), @ApiResponse( responseCode = "500 Internal Server Error", description = "", content = { @Content() } ) }) @DeleteMapping("/{id}") public ResponseEntity<Void> deleteUser(@PathVariable String id) { ResponseEntity<Void> response; Optional<User> optionalUser = usersRepo.get(id); if (optionalUser.isPresent()) { User user = optionalUser.get(); usersRepo.delete(user); response = new ResponseEntity<>(HttpStatus.NO_CONTENT); } else { response = new ResponseEntity<>(HttpStatus.NOT_FOUND); } return response; } }