package com.mif13.authServer.controllers; import com.mif13.authServer.dao.UsersDao; import com.mif13.authServer.model.User; import com.mif13.authServer.utils.JwtHelper; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import javax.naming.AuthenticationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMapAdapter; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestParam; @Controller public class UserOperations { private final UsersDao usersRepo; @Autowired public UserOperations(UsersDao usersRepo) { this.usersRepo = usersRepo; } /** * Procédure de login utilisée par un utilisateur * * @param login Le login de l'utilisateur. L'utilisateur doit avoir été créé préalablement et * son login doit être présent dans le DAO. * @param password Le password à vérifier. * @return Une ResponseEntity avec le JWT dans le header "Authorization" si le login s'est bien * passé, et le code de statut approprié (204, 401 ou 404). */ @Operation(summary = "login utilisée par un utilisateur") @ApiResponses(value = { @ApiResponse( responseCode = "204 No Content", description = "User succesfully logged in", content = { @Content() } ), @ApiResponse( responseCode = "401 Unauthorized", description = "Login failed", content = { @Content() } ) }) @PostMapping("/login") public ResponseEntity<Void> login(@RequestParam("login") String login, @RequestParam("password") String password, @RequestHeader("Origin") String origin) { ResponseEntity<Void> response; response = new ResponseEntity<>(HttpStatus.NO_CONTENT); /*response.getHeaders().add("Access-Control-Expose-Headers", "Authorization"); response.getHeaders().add("Access-Control-Allow-Origin", origin);*/ String jwt; Map<String, List<String>> headers = new HashMap<>(); MultiValueMap<String, String> headersSpring; Optional<User> optionalUser = usersRepo.get(login); if (optionalUser.isPresent()) { User user = optionalUser.get(); try { jwt = JwtHelper.generateToken(login, origin); if (!jwt.isEmpty()) { // on ajoute un header Authorization avec comme valeur JWT headers.put("Authorization", List.of(jwt)); } else { throw new Exception("JWT is empty !"); } } catch (Exception e) { // on ajoute un header Authorization avec comme valeur LOGIN headers.put("Authorization", List.of(login)); } try { // Authentification de l'utilisateur user.authenticate(password); // Creation de la reponse HTTP headersSpring = new MultiValueMapAdapter<>(headers); response = new ResponseEntity<>(headersSpring, HttpStatus.NO_CONTENT); } catch (AuthenticationException e) { e.printStackTrace(); response = new ResponseEntity<>(HttpStatus.UNAUTHORIZED); } } else { // on ajoute un header Authentication avec comme valeur LOGIN headers.put("Authorization", List.of(login)); headersSpring = new MultiValueMapAdapter<>(headers); response = new ResponseEntity<>(headersSpring, HttpStatus.NOT_FOUND); } return response; } @Operation(summary = "Réalise la déconnexion.") @ApiResponses(value = { @ApiResponse( responseCode = "204 No Content", description = "User succesfully logged out", content = { @Content() } ), @ApiResponse( responseCode = "401 Unauthorized", description = "", content = { @Content() } ) }) @PostMapping("/logout") public ResponseEntity<Void> logout(@RequestParam("login") String login) { ResponseEntity<Void> response; Optional<User> optionalUser = usersRepo.get(login); try { if (optionalUser.isPresent()) { User user = optionalUser.get(); if (user.isConnected()) { user.disconnect(); response = new ResponseEntity<>(HttpStatus.NO_CONTENT); } else { throw new Exception("User is not connected !"); } } else { throw new Exception("User does not exist !"); } } catch (Exception e) { e.printStackTrace(); response = new ResponseEntity<>(HttpStatus.UNAUTHORIZED); } return response; } /** * . * * @param jwt Le token JWT qui se trouve dans le header "Authorization" de la requête * @param origin L'origine de la requête (pour la comparer avec celle du client, stockée dans le * token JWT) * @return Une réponse vide avec un code de statut approprié (204, 400, 401). */ @Operation(summary = "Méthode destinée au serveur Node pour valider l'authentification d'un utilisateur.") @ApiResponses(value = { @ApiResponse( responseCode = "204 No Content", description = "", content = { @Content() } ) }) @GetMapping("/authenticate") public ResponseEntity<Void> authenticate(@RequestParam("jwt") String jwt, @RequestParam("origin") String origin) { ResponseEntity<Void> response = new ResponseEntity<>(HttpStatus.NO_CONTENT); return response; } }