Skip to content
Snippets Groups Projects
UserRestController.java 11.1 KiB
Newer Older
package com.mif13.authServer.controllers;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mif13.authServer.dao.UsersDao;
import com.mif13.authServer.exception.InvalidPasswordException;
import com.mif13.authServer.exception.InvalidUsernameException;
import com.mif13.authServer.exception.UserCreationException;
import com.mif13.authServer.model.User;
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;
import java.util.Optional;
import java.util.regex.PatternSyntaxException;
import org.springframework.beans.factory.annotation.Autowired;
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.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.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.servlet.ModelAndView;

@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 = {
    @GetMapping(value = "/{id}", produces = {MediaType.APPLICATION_JSON_VALUE,
        MediaType.APPLICATION_XML_VALUE})
Wilalde's avatar
Wilalde committed
    //@CrossOrigin(origins = {"http://localhost", "http://192.168.75.68", "https://192.168.75.68"})
    public ResponseEntity<User> getUserAsJsonOrXml(@PathVariable String id) {

        Optional<User> optionalUser = usersRepo.get(id);
        if (optionalUser.isPresent()) {
            User user = optionalUser.get();
            return new ResponseEntity<>(user, HttpStatus.OK);
            throw new ResponseStatusException(HttpStatus.NOT_FOUND, "User not found");
    @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> createUserResponse(String login, String password) {
            User user = new User(login, password);

            try {
                HttpStatus statusCode;
                Optional<User> optionalUser = usersRepo.get(user.getLogin());
                if (optionalUser.isEmpty()) {
                    usersRepo.save(user);
                    statusCode = HttpStatus.CREATED;
                } else {
                    statusCode = HttpStatus.FORBIDDEN;
                }
                return new ResponseEntity<>(statusCode);

            } catch (PatternSyntaxException e) {
                // Si les patterns RegEx de validation sont pas valides
                e.printStackTrace();
                throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR);

        } catch (UserCreationException e) {
            e.printStackTrace();

            String errMsg;
            if (e instanceof InvalidUsernameException) {
                errMsg = "Login does not match the requirements";
            } else if (e instanceof InvalidPasswordException) {
                errMsg = "Password does not match the requirements";
            } else {
                errMsg = "Failed to create a user";
            }

            // Par defaut, pour des raisons de securite,
            // le message d'erreur n'est pas affiche a l'utilisateur
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, errMsg, e);
        }

    }

    @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) {
        return createUserResponse(login, password);
    }

    /**
     * Cree un User a partir d'un JSON.
     *
     * @param json JSON contenant un login et un password
     * @return contenu vide
    @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Void> createUserFromJson(@RequestBody String json) {

        try {
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode jsonTree = objectMapper.readTree(json);
            String login = jsonTree.get("login").asText();
            String password = jsonTree.get("password").asText();
            return createUserResponse(login, password);

        } catch (JsonProcessingException e) {
            e.printStackTrace();
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Failed to process JSON", e);
        }
    @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(value = "/{id}", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public ResponseEntity<Void> modifyUserPasswordFromUrlEncoded(@PathVariable String id,
        @RequestParam("newPassword") String newPassword) {
        return modifyUserPassword(id, newPassword);
    }

    @PutMapping(value = "/{id}", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Void> modifyUserPasswordFromJson(@PathVariable String id,
        @RequestBody String json) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode jsonTree = objectMapper.readTree(json);
            String newPassword = jsonTree.get("newPassword").asText();
            return modifyUserPassword(id, newPassword);

        } catch (JsonProcessingException e) {
            e.printStackTrace();
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Failed to process JSON", e);
        }
    }

    private ResponseEntity<Void> modifyUserPassword(String id, String newPassword) {
        Optional<User> optionalUser = usersRepo.get(id);
        if (optionalUser.isPresent()) {
            User user = optionalUser.get();
            try {
                if (User.verifyPassword(newPassword)) {
                    user.setPassword(newPassword);
                    return new ResponseEntity<>(HttpStatus.NO_CONTENT);
                } else {
                    throw new InvalidPasswordException("Password does not match the requirements");
                }
            } catch (InvalidPasswordException e) {
                e.printStackTrace();
                throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.getMessage(), e);
        } else {
            throw new ResponseStatusException(HttpStatus.NOT_FOUND, "User not found");
    @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()
            }
        )
    public ResponseEntity<Void> deleteUser(@PathVariable String id) {
        Optional<User> optionalUser = usersRepo.get(id);
        if (optionalUser.isPresent()) {
            User user = optionalUser.get();
            usersRepo.delete(user);
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        } else {
            throw new ResponseStatusException(HttpStatus.NOT_FOUND, "User not found");