Compare commits
	
		
			No commits in common. "c3dd337c7d9fd262fdc91293965edf5cfb8968e2" and "189245ef42c2cd7c6339e8a1054c45f0f2881479" have entirely different histories.
		
	
	
		
			c3dd337c7d
			...
			189245ef42
		
	
		
							
								
								
									
										30
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								pom.xml
									
									
									
									
									
								
							| @ -30,6 +30,10 @@ | |||||||
| 		<java.version>21</java.version> | 		<java.version>21</java.version> | ||||||
| 	</properties> | 	</properties> | ||||||
| 	<dependencies> | 	<dependencies> | ||||||
|  | 		<dependency> | ||||||
|  | 			<groupId>org.springframework.boot</groupId> | ||||||
|  | 			<artifactId>spring-boot-starter-data-jpa</artifactId> | ||||||
|  | 		</dependency> | ||||||
| 		<dependency> | 		<dependency> | ||||||
| 			<groupId>org.springframework.boot</groupId> | 			<groupId>org.springframework.boot</groupId> | ||||||
| 			<artifactId>spring-boot-starter-data-rest</artifactId> | 			<artifactId>spring-boot-starter-data-rest</artifactId> | ||||||
| @ -54,32 +58,6 @@ | |||||||
| 			<artifactId>spring-boot-starter-test</artifactId> | 			<artifactId>spring-boot-starter-test</artifactId> | ||||||
| 			<scope>test</scope> | 			<scope>test</scope> | ||||||
| 		</dependency> | 		</dependency> | ||||||
| 		<dependency> |  | ||||||
| 			<groupId>org.springframework.boot</groupId> |  | ||||||
| 			<artifactId>spring-boot-starter-data-jdbc</artifactId> |  | ||||||
| 		</dependency> |  | ||||||
| 		<dependency> |  | ||||||
| 			<groupId>org.springframework.boot</groupId> |  | ||||||
| 			<artifactId>spring-boot-starter-oauth2-authorization-server</artifactId> |  | ||||||
| 		</dependency> |  | ||||||
| 		<dependency> |  | ||||||
| 			<groupId>org.springframework.boot</groupId> |  | ||||||
| 			<artifactId>spring-boot-starter-security</artifactId> |  | ||||||
| 		</dependency> |  | ||||||
| 		<dependency> |  | ||||||
| 			<groupId>org.springframework.security</groupId> |  | ||||||
| 			<artifactId>spring-security-test</artifactId> |  | ||||||
| 			<scope>test</scope> |  | ||||||
| 		</dependency> |  | ||||||
| 		<dependency> |  | ||||||
| 			<groupId>org.springframework.boot</groupId> |  | ||||||
| 			<artifactId>spring-boot-devtools</artifactId> |  | ||||||
| 			<scope>runtime</scope> |  | ||||||
| 		</dependency> |  | ||||||
| 		<dependency> |  | ||||||
| 			<groupId>org.springframework.boot</groupId> |  | ||||||
| 			<artifactId>spring-boot-starter-actuator</artifactId> |  | ||||||
| 		</dependency> |  | ||||||
| 	</dependencies> | 	</dependencies> | ||||||
| 
 | 
 | ||||||
| 	<build> | 	<build> | ||||||
|  | |||||||
| @ -1,5 +1,7 @@ | |||||||
| package com.guams.review; | package com.guams.review; | ||||||
| 
 | 
 | ||||||
|  | import com.guams.review.modele.Post; | ||||||
|  | import com.guams.review.modele.User; | ||||||
| import org.springframework.boot.SpringApplication; | import org.springframework.boot.SpringApplication; | ||||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,34 +0,0 @@ | |||||||
| package com.guams.review.configuration; |  | ||||||
| 
 |  | ||||||
| import com.guams.review.exception.AlreadyExistsException; |  | ||||||
| import com.guams.review.exception.InvalidNameOrPasswordException; |  | ||||||
| import com.guams.review.exception.NotFoundException; |  | ||||||
| import com.guams.review.exception.ForbiddenExecption; |  | ||||||
| import org.springframework.http.HttpStatus; |  | ||||||
| import org.springframework.http.ResponseEntity; |  | ||||||
| import org.springframework.web.bind.annotation.ControllerAdvice; |  | ||||||
| import org.springframework.web.bind.annotation.ExceptionHandler; |  | ||||||
| 
 |  | ||||||
| @ControllerAdvice |  | ||||||
| public class Advice { |  | ||||||
| 
 |  | ||||||
|     @ExceptionHandler(value = NotFoundException.class) |  | ||||||
|     public ResponseEntity<Object> handleNotFound(NotFoundException exception) { |  | ||||||
|         return new ResponseEntity<>(exception.getMessage(), HttpStatus.NOT_FOUND); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @ExceptionHandler(value = AlreadyExistsException.class) |  | ||||||
|     public ResponseEntity<Object> handleAlreadyExists(AlreadyExistsException exception) { |  | ||||||
|         return new ResponseEntity<>(exception.getMessage(), HttpStatus.BAD_REQUEST); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @ExceptionHandler(value = InvalidNameOrPasswordException.class) |  | ||||||
|     public ResponseEntity<Object> handleInvalidNameOrPassword(InvalidNameOrPasswordException exception) { |  | ||||||
|         return new ResponseEntity<>(exception.getMessage(), HttpStatus.FORBIDDEN); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @ExceptionHandler(value = ForbiddenExecption.class) |  | ||||||
|     public ResponseEntity<Object> handleUnauthorizedExecption(ForbiddenExecption exception) { |  | ||||||
|         return new ResponseEntity<>(exception.getMessage(), HttpStatus.FORBIDDEN); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,55 +0,0 @@ | |||||||
| package com.guams.review.configuration; |  | ||||||
| import com.guams.review.service.AuthorService; |  | ||||||
| import io.jsonwebtoken.JwtException; |  | ||||||
| import jakarta.servlet.FilterChain; |  | ||||||
| import jakarta.servlet.ServletException; |  | ||||||
| import jakarta.servlet.http.HttpServletRequest; |  | ||||||
| import jakarta.servlet.http.HttpServletResponse; |  | ||||||
| import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |  | ||||||
| import org.springframework.security.core.context.SecurityContextHolder; |  | ||||||
| import org.springframework.security.core.userdetails.UserDetails; |  | ||||||
| import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; |  | ||||||
| import org.springframework.stereotype.Component; |  | ||||||
| import org.springframework.web.filter.OncePerRequestFilter; |  | ||||||
| import java.io.IOException; |  | ||||||
| 
 |  | ||||||
| @Component |  | ||||||
| public class JwtAuthenticationFilter extends OncePerRequestFilter { |  | ||||||
| 
 |  | ||||||
|     private final JwtTokenUtil jwtTokenUtil; |  | ||||||
|     private final AuthorService authorService; |  | ||||||
| 
 |  | ||||||
|     public JwtAuthenticationFilter(JwtTokenUtil jwtTokenUtil, AuthorService authorService) { |  | ||||||
|         this.jwtTokenUtil = jwtTokenUtil; |  | ||||||
|         this.authorService = authorService; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) |  | ||||||
|             throws ServletException, IOException { |  | ||||||
|         final String authHeader = request.getHeader("Authorization"); |  | ||||||
| 
 |  | ||||||
|         if (authHeader != null && authHeader.startsWith("Bearer ")) { |  | ||||||
|             String token = authHeader.substring(7); // Retire le préfixe "Bearer " |  | ||||||
|             try { |  | ||||||
|                 String username = jwtTokenUtil.extractUsername(token); // Récupère l'utilisateur du token |  | ||||||
| 
 |  | ||||||
|                 if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { |  | ||||||
|                     UserDetails userDetails = authorService.loadUserByUsername(username); |  | ||||||
| 
 |  | ||||||
|                     if (jwtTokenUtil.validateToken(token, userDetails)) { |  | ||||||
|                         UsernamePasswordAuthenticationToken authentication = |  | ||||||
|                                 new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); |  | ||||||
|                         authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); |  | ||||||
|                         SecurityContextHolder.getContext().setAuthentication(authentication); // Met à jour le contexte |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } catch (JwtException e) { |  | ||||||
|                 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         filterChain.doFilter(request, response); // Continue le traitement |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,50 +0,0 @@ | |||||||
| package com.guams.review.configuration; |  | ||||||
| 
 |  | ||||||
| import io.jsonwebtoken.Jwts; |  | ||||||
| import io.jsonwebtoken.SignatureAlgorithm; |  | ||||||
| import org.springframework.security.core.userdetails.UserDetails; |  | ||||||
| import org.springframework.stereotype.Component; |  | ||||||
| 
 |  | ||||||
| import java.util.Date; |  | ||||||
| 
 |  | ||||||
| @Component |  | ||||||
| public class JwtTokenUtil { |  | ||||||
| 
 |  | ||||||
|     private final String SECRET_KEY = "9f87d7a0eb7dea860b98adf6bb94feefe4a33698022733bb012d662d92db8081"; |  | ||||||
|     private final long EXPIRATION_TIME = 1000 * 60 * 60 * 10; // 10 heures |  | ||||||
| 
 |  | ||||||
|     public String generateToken(String username) { |  | ||||||
|         return Jwts.builder() |  | ||||||
|                 .setSubject(username) |  | ||||||
|                 .setIssuedAt(new Date()) |  | ||||||
|                 .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) |  | ||||||
|                 .signWith(SignatureAlgorithm.HS256, SECRET_KEY) |  | ||||||
|                 .compact(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public String extractUsername(String token) { |  | ||||||
|         return Jwts.parser() |  | ||||||
|                 .setSigningKey(SECRET_KEY) |  | ||||||
|                 .parseClaimsJws(token) |  | ||||||
|                 .getBody() |  | ||||||
|                 .getSubject(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public boolean validateToken(String token, UserDetails userDetails) { |  | ||||||
|         String username = extractUsername(token); |  | ||||||
|         return username.equals(userDetails.getUsername()) && !isTokenExpired(token); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private boolean isTokenExpired(String token) { |  | ||||||
|         return extractExpiration(token).before(new Date()); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private Date extractExpiration(String token) { |  | ||||||
|         return Jwts.parser() |  | ||||||
|                 .setSigningKey(SECRET_KEY) |  | ||||||
|                 .parseClaimsJws(token) |  | ||||||
|                 .getBody() |  | ||||||
|                 .getExpiration(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -1,76 +0,0 @@ | |||||||
| package com.guams.review.configuration; |  | ||||||
| import com.guams.review.service.AuthorService; |  | ||||||
| import lombok.RequiredArgsConstructor; |  | ||||||
| import org.springframework.context.annotation.Bean; |  | ||||||
| import org.springframework.context.annotation.Configuration; |  | ||||||
| import org.springframework.http.HttpMethod; |  | ||||||
| import org.springframework.security.authentication.AuthenticationManager; |  | ||||||
| import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; |  | ||||||
| import org.springframework.security.config.annotation.web.builders.HttpSecurity; |  | ||||||
| import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; |  | ||||||
| import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; |  | ||||||
| import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |  | ||||||
| import org.springframework.security.crypto.password.PasswordEncoder; |  | ||||||
| import org.springframework.security.web.SecurityFilterChain; |  | ||||||
| import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; |  | ||||||
| import org.springframework.web.cors.CorsConfiguration; |  | ||||||
| import org.springframework.web.cors.CorsConfigurationSource; |  | ||||||
| import org.springframework.web.cors.UrlBasedCorsConfigurationSource; |  | ||||||
| 
 |  | ||||||
| import java.util.List; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @Configuration |  | ||||||
| @EnableWebSecurity |  | ||||||
| @RequiredArgsConstructor |  | ||||||
| public class SpringSecurityConfig { |  | ||||||
| 
 |  | ||||||
|     private final AuthorService authorService; |  | ||||||
| 
 |  | ||||||
|     @Bean |  | ||||||
|     public SecurityFilterChain securityFilterChain(HttpSecurity http, JwtAuthenticationFilter jwtAuthenticationFilter) throws Exception { |  | ||||||
|         return http |  | ||||||
|                 .csrf(AbstractHttpConfigurer::disable) |  | ||||||
|                 .cors(cors -> cors.configurationSource(corsConfigurationSource())) // Ajout de la configuration CORS |  | ||||||
|                 .authorizeHttpRequests(auth -> auth |  | ||||||
|                         .requestMatchers(HttpMethod.GET, |  | ||||||
|                                 "/api/authors", |  | ||||||
|                                 "/api/authors/{id}", |  | ||||||
|                                 "/api/authors/{id}/posts", |  | ||||||
|                                 "/api/posts", |  | ||||||
|                                 "/api/posts/{id}").permitAll() // Autorise les GET sur ces routes |  | ||||||
|                         .requestMatchers("/api/authors/login", "/api/authors/register").permitAll() // Autorise sans authentification |  | ||||||
|                         .requestMatchers("/api/authors/me").authenticated() // Requiert authentification |  | ||||||
|                         .anyRequest().authenticated() // Toutes les autres routes nécessitent une authentification |  | ||||||
|                 ) |  | ||||||
|                 .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class) // Ajoute le filtre JWT |  | ||||||
|                 .build(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Bean |  | ||||||
|     public CorsConfigurationSource corsConfigurationSource() { |  | ||||||
|         CorsConfiguration configuration = new CorsConfiguration(); |  | ||||||
|         configuration.setAllowedOrigins(List.of("http://localhost:4200")); // N'autorise que localhost:4200 |  | ||||||
|         configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE")); // Spécifie les méthodes autorisées |  | ||||||
|         configuration.setAllowedHeaders(List.of("Authorization", "Content-Type")); // Limite les en-têtes autorisés |  | ||||||
|         configuration.setAllowCredentials(true); // Autorise l'utilisation des cookies ou des tokens |  | ||||||
|         configuration.setMaxAge(3600L); // Cache la configuration CORS pendant 1 heure |  | ||||||
| 
 |  | ||||||
|         UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); |  | ||||||
|         source.registerCorsConfiguration("/**", configuration); // Applique les règles à toutes les routes |  | ||||||
|         return source; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Bean |  | ||||||
|     public PasswordEncoder passwordEncoder() { |  | ||||||
|         return new BCryptPasswordEncoder(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Bean |  | ||||||
|     public AuthenticationManager authenticationManager(HttpSecurity http, PasswordEncoder passwordEncoder) throws Exception { |  | ||||||
|         AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class); |  | ||||||
|         authenticationManagerBuilder.userDetailsService(authorService).passwordEncoder(passwordEncoder); |  | ||||||
|         return authenticationManagerBuilder.build(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -1,124 +0,0 @@ | |||||||
| package com.guams.review.controller; |  | ||||||
| 
 |  | ||||||
| import com.guams.review.configuration.JwtTokenUtil; |  | ||||||
| import com.guams.review.exception.AlreadyExistsException; |  | ||||||
| import com.guams.review.exception.InvalidNameOrPasswordException; |  | ||||||
| import com.guams.review.exception.NotFoundException; |  | ||||||
| import com.guams.review.exception.ForbiddenExecption; |  | ||||||
| import com.guams.review.model.AuthorRepository; |  | ||||||
| import com.guams.review.model.dao.Author; |  | ||||||
| import com.guams.review.model.dao.AuthorToken; |  | ||||||
| import com.guams.review.model.dao.Post; |  | ||||||
| import com.guams.review.service.AuthorService; |  | ||||||
| import com.guams.review.service.mapper.Mapper; |  | ||||||
| import com.guams.review.service.mapper.ReturnableAuthor; |  | ||||||
| import lombok.RequiredArgsConstructor; |  | ||||||
| import org.springframework.http.HttpStatus; |  | ||||||
| import org.springframework.http.MediaType; |  | ||||||
| import org.springframework.http.ResponseEntity; |  | ||||||
| import org.springframework.security.authentication.AuthenticationManager; |  | ||||||
| import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |  | ||||||
| import org.springframework.security.core.Authentication; |  | ||||||
| import org.springframework.security.crypto.password.PasswordEncoder; |  | ||||||
| import org.springframework.util.Assert; |  | ||||||
| import org.springframework.web.bind.annotation.*; |  | ||||||
| import org.springframework.web.multipart.MultipartFile; |  | ||||||
| 
 |  | ||||||
| import java.io.IOException; |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.UUID; |  | ||||||
| 
 |  | ||||||
| @RestController |  | ||||||
| @RequestMapping(path = "api/authors") |  | ||||||
| @RequiredArgsConstructor |  | ||||||
| public class AuthorController { |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     private final PasswordEncoder passwordEncoder; |  | ||||||
|     private final AuthenticationManager authenticationManager; |  | ||||||
|     private final AuthorService authorService; |  | ||||||
|     private final JwtTokenUtil jwtTokenUtil; |  | ||||||
|     private final AuthorRepository authorRepository; |  | ||||||
|     private final Mapper mapper; |  | ||||||
| 
 |  | ||||||
|     @GetMapping |  | ||||||
|     public List<ReturnableAuthor> getUsers() { |  | ||||||
|         return authorService.list(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @GetMapping("/{id}") |  | ||||||
|     public ReturnableAuthor findUser(@PathVariable UUID id) { |  | ||||||
|         Author author = authorService.findById(id).orElseThrow(() -> new NotFoundException("Author not found")); |  | ||||||
|         return mapper.mapAuthor(author); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @PutMapping("/{id}") |  | ||||||
|     public void updateUser(@PathVariable UUID id, @RequestBody Author updatedAuthor, Authentication authentication) { |  | ||||||
|         Author authorToUpdate = authorService.verifyIfUserIsAuthorized(authentication, id); |  | ||||||
|         authorService.insert(updatedAuthor.setId(authorToUpdate.getId())); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @PutMapping(value = "{id}/avatar", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) |  | ||||||
|     public void updateUserAvatar(@PathVariable UUID id, @RequestPart MultipartFile avatar, Authentication authentication) throws IOException { |  | ||||||
|         Author authorToUpdate = authorService.verifyIfUserIsAuthorized(authentication, id); |  | ||||||
|         authorService.insert(authorToUpdate.setProfilePicture(avatar.getBytes())); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @DeleteMapping("/{id}") |  | ||||||
|     public void deleteUser(@PathVariable UUID id, Authentication authentication) { |  | ||||||
|         Author authorToDelete = authorService.verifyIfUserIsAuthorized(authentication, id); |  | ||||||
|         authorService.delete(authorToDelete); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @PutMapping("/{id}/posts") |  | ||||||
|     public void updateUserPosts(@PathVariable("id") UUID authorId, @RequestBody List<Long> postIds, Authentication authentication) { |  | ||||||
|         Author author = authorService.verifyIfUserIsAuthorized(authentication, authorId); |  | ||||||
|         authorService.insertPublications(author.getId(), postIds); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @GetMapping("/{id}/posts") |  | ||||||
|     public List<Post> getUserPosts(@PathVariable UUID id) { |  | ||||||
|         Author author = authorService.findById(id).orElseThrow(() -> new NotFoundException("Author not found")); |  | ||||||
|         return authorService.listPublicationOfAuthor(author.getId()); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @PostMapping("/login") |  | ||||||
|     public AuthorToken authorLogin(@RequestBody Author author) { |  | ||||||
|         try { |  | ||||||
|             authenticationManager.authenticate( |  | ||||||
|                     new UsernamePasswordAuthenticationToken(author.getName(), author.getPassword()) |  | ||||||
|             ); |  | ||||||
| 
 |  | ||||||
|             String token = jwtTokenUtil.generateToken(author.getName()); |  | ||||||
|             return new AuthorToken().setToken(token); |  | ||||||
|         } catch (Exception e) { |  | ||||||
|             throw new InvalidNameOrPasswordException(e.getMessage()); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @PostMapping("/register") |  | ||||||
|     public ResponseEntity<Author> authorRegister(@RequestBody Author author) { |  | ||||||
|         Assert.isNull(author.getId(), "Author id must be null"); |  | ||||||
|         if (authorRepository.findByName(author.getName()) != null) { |  | ||||||
|             throw new AlreadyExistsException("Author already exists"); |  | ||||||
|         } |  | ||||||
|         author.setPassword(passwordEncoder.encode(author.getPassword())); |  | ||||||
|         return new ResponseEntity<>(authorRepository.save(author.setRole("USER")).setPassword(""), HttpStatus.CREATED); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @GetMapping(value = "/me", produces = "application/json") |  | ||||||
|     public Author getAuthenticatedUser(Authentication authentication) { |  | ||||||
|         if (authentication == null || !authentication.isAuthenticated()) { |  | ||||||
|             throw new ForbiddenExecption("You are not authorized to access this resource"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         String username = authentication.getName(); |  | ||||||
|         Author author = authorRepository.findByName(username); |  | ||||||
| 
 |  | ||||||
|         if (author == null) { |  | ||||||
|             throw new NotFoundException("Author not found"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return author.setPassword(""); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,98 +0,0 @@ | |||||||
| package com.guams.review.controller; |  | ||||||
| 
 |  | ||||||
| import com.guams.review.exception.NotFoundException; |  | ||||||
| import com.guams.review.exception.ForbiddenExecption; |  | ||||||
| import com.guams.review.model.AuthorRepository; |  | ||||||
| import com.guams.review.model.dao.Author; |  | ||||||
| import com.guams.review.model.dao.Post; |  | ||||||
| import com.guams.review.service.AuthorService; |  | ||||||
| import com.guams.review.service.PostService; |  | ||||||
| import lombok.RequiredArgsConstructor; |  | ||||||
| import org.springframework.http.HttpStatus; |  | ||||||
| import org.springframework.http.MediaType; |  | ||||||
| import org.springframework.http.ResponseEntity; |  | ||||||
| import org.springframework.security.core.Authentication; |  | ||||||
| import org.springframework.util.Assert; |  | ||||||
| import org.springframework.web.bind.annotation.*; |  | ||||||
| import org.springframework.web.multipart.MultipartFile; |  | ||||||
| 
 |  | ||||||
| import java.io.IOException; |  | ||||||
| import java.time.LocalDate; |  | ||||||
| import java.util.List; |  | ||||||
| 
 |  | ||||||
| @RequiredArgsConstructor |  | ||||||
| @RestController |  | ||||||
| @RequestMapping("/api/posts") |  | ||||||
| public class PostController { |  | ||||||
| 
 |  | ||||||
|     private final PostService postService; |  | ||||||
|     private final AuthorService authorService; |  | ||||||
|     private final AuthorRepository authorRepository; |  | ||||||
| 
 |  | ||||||
|     @GetMapping |  | ||||||
|     public List<Post> listPosts() { |  | ||||||
|         return postService.list(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @GetMapping("/{id}") |  | ||||||
|     public Post findPost(@PathVariable Long id) { |  | ||||||
|         return postService.findById(id).orElseThrow(() -> new NotFoundException("Post not found")); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @PutMapping("/{id}") |  | ||||||
|     public void updatePost(@PathVariable Long id, @RequestBody Post updatedPost, Authentication authentication) { |  | ||||||
|         if (authentication == null) { |  | ||||||
|             throw new ForbiddenExecption("You have to login to do that"); |  | ||||||
|         } |  | ||||||
|         Author authenticatedAuthor = authorRepository.findByName(authentication.getName()); |  | ||||||
|         //Si l'user authent possède ce post |  | ||||||
|         if (authorService.listPublicationOfAuthor(authenticatedAuthor.getId()).stream().map(Post::getId).toList().contains(id)) { |  | ||||||
|             Post postToUpdate = postService.findById(id).orElseThrow(() -> new NotFoundException("Post not found")); |  | ||||||
|             postService.insert(updatedPost |  | ||||||
|                     .setId(postToUpdate.getId()) |  | ||||||
|                     .setIllustration(postToUpdate.getIllustration()) |  | ||||||
|                     .setPublicationDate(postToUpdate.getPublicationDate())); |  | ||||||
|         } else { |  | ||||||
|             throw new ForbiddenExecption("You do not have permission to update this post"); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @PutMapping(value = "{id}/illustration", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) |  | ||||||
|     public void updateIllustration(@PathVariable Long id, @RequestPart MultipartFile illustration, Authentication authentication) throws IOException { |  | ||||||
|         if (authentication == null) { |  | ||||||
|             throw new ForbiddenExecption("You have to login to do that"); |  | ||||||
|         } |  | ||||||
|         Author authenticatedAuthor = authorRepository.findByName(authentication.getName()); |  | ||||||
|         if (authorService.listPublicationOfAuthor(authenticatedAuthor.getId()).stream().map(Post::getId).toList().contains(id)) { |  | ||||||
|             Post postToUpdate = postService.findById(id).orElseThrow(() -> new NotFoundException("Post not found")); |  | ||||||
|             postService.insert(postToUpdate.setIllustration(illustration.getBytes())); |  | ||||||
|         } else { |  | ||||||
|             throw new ForbiddenExecption("You do not have permission to update this post"); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @PostMapping |  | ||||||
|     public ResponseEntity<Post> addPost(@RequestBody Post postToCreate, Authentication authentication) { |  | ||||||
|         Assert.isNull(postToCreate.getId(), "Post id must be null"); |  | ||||||
|         if (authentication == null) { |  | ||||||
|             throw new ForbiddenExecption("You have to login to do that"); |  | ||||||
|         } |  | ||||||
|         return new ResponseEntity<>(postService.insert(postToCreate.setPublicationDate(LocalDate.now())), HttpStatus.CREATED); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @DeleteMapping("{id}") |  | ||||||
|     public void deletePost(@PathVariable Long id, Authentication authentication) { |  | ||||||
|         if (authentication == null) { |  | ||||||
|             throw new ForbiddenExecption("You have to login to do that"); |  | ||||||
|         } |  | ||||||
|         Author authenticatedAuthor = authorRepository.findByName(authentication.getName()); |  | ||||||
|         if (authorService.listPublicationOfAuthor(authenticatedAuthor.getId()).stream().map(Post::getId).toList().contains(id)) { |  | ||||||
|             Post postToDelete = postService.findById(id).orElseThrow(() -> new NotFoundException("Post not found")); |  | ||||||
|             postService.delete(postToDelete.getId()); |  | ||||||
|         } else { |  | ||||||
|             throw new ForbiddenExecption("You do not have permission to delete this post"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -0,0 +1,44 @@ | |||||||
|  | package com.guams.review.controller; | ||||||
|  | 
 | ||||||
|  | import com.guams.review.modele.User; | ||||||
|  | import com.guams.review.service.UserService; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.http.HttpEntity; | ||||||
|  | import org.springframework.http.HttpHeaders; | ||||||
|  | import org.springframework.http.HttpStatus; | ||||||
|  | import org.springframework.http.ResponseEntity; | ||||||
|  | import org.springframework.web.bind.annotation.*; | ||||||
|  | 
 | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Optional; | ||||||
|  | 
 | ||||||
|  | @RestController | ||||||
|  | @RequestMapping(path = "api/users") | ||||||
|  | public class UserController | ||||||
|  | { | ||||||
|  |     private final UserService userService; | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     public UserController(UserService userService) { | ||||||
|  |         this.userService = userService; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @GetMapping | ||||||
|  |     public ResponseEntity<List<User>> getUsers() | ||||||
|  |     { | ||||||
|  |         List<User> users = userService.getUsers(); | ||||||
|  |         return new ResponseEntity<>(users, new HttpHeaders(),HttpStatus.OK); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     @PostMapping | ||||||
|  |     public ResponseEntity<String> saveUser(@RequestParam User user) | ||||||
|  |     { | ||||||
|  |         userService.saveUser(user); | ||||||
|  |         Optional<User> exists = userService.findById(user.getId()); | ||||||
|  |         if (exists.isPresent()) | ||||||
|  |         { | ||||||
|  |             return new ResponseEntity<>("Created", new HttpHeaders(), HttpStatus.CREATED); | ||||||
|  |         } | ||||||
|  |         return new ResponseEntity<>("Error", new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,7 +0,0 @@ | |||||||
| package com.guams.review.exception; |  | ||||||
| 
 |  | ||||||
| public class AlreadyExistsException extends RuntimeException { |  | ||||||
|     public AlreadyExistsException(String message) { |  | ||||||
|         super(message); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,7 +0,0 @@ | |||||||
| package com.guams.review.exception; |  | ||||||
| 
 |  | ||||||
| public class ForbiddenExecption extends RuntimeException { |  | ||||||
|     public ForbiddenExecption(String message) { |  | ||||||
|         super(message); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,7 +0,0 @@ | |||||||
| package com.guams.review.exception; |  | ||||||
| 
 |  | ||||||
| public class InvalidNameOrPasswordException extends RuntimeException { |  | ||||||
|     public InvalidNameOrPasswordException(String message) { |  | ||||||
|         super(message); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,7 +0,0 @@ | |||||||
| package com.guams.review.exception; |  | ||||||
| 
 |  | ||||||
| public class NotFoundException extends RuntimeException { |  | ||||||
|   public NotFoundException(String message) { |  | ||||||
|     super(message); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @ -1,26 +0,0 @@ | |||||||
| package com.guams.review.model; |  | ||||||
| 
 |  | ||||||
| import com.guams.review.model.dao.Author; |  | ||||||
| import org.springframework.data.jdbc.repository.query.Modifying; |  | ||||||
| import org.springframework.data.jdbc.repository.query.Query; |  | ||||||
| import org.springframework.data.repository.CrudRepository; |  | ||||||
| import org.springframework.stereotype.Repository; |  | ||||||
| 
 |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.UUID; |  | ||||||
| 
 |  | ||||||
| @Repository |  | ||||||
| public interface AuthorRepository extends CrudRepository<Author, UUID> { |  | ||||||
| 
 |  | ||||||
|     @Modifying |  | ||||||
|     @Query("insert into publication (author_fk, post_fk) values (:authorId, :postId)") |  | ||||||
|     void insertPublication(UUID authorId, Long postId); |  | ||||||
| 
 |  | ||||||
|     @Modifying |  | ||||||
|     @Query("delete from publication where author_fk=:authorId and post_fk=:postId") |  | ||||||
|     void deletePublication(UUID authorId, Long postId); |  | ||||||
| 
 |  | ||||||
|     List<Author> findAll(); |  | ||||||
| 
 |  | ||||||
|     Author findByName(String name); |  | ||||||
| } |  | ||||||
| @ -1,19 +0,0 @@ | |||||||
| package com.guams.review.model; |  | ||||||
| 
 |  | ||||||
| import com.guams.review.model.dao.Post; |  | ||||||
| import org.springframework.data.jdbc.repository.query.Query; |  | ||||||
| import org.springframework.data.repository.CrudRepository; |  | ||||||
| import org.springframework.stereotype.Repository; |  | ||||||
| 
 |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.UUID; |  | ||||||
| 
 |  | ||||||
| @Repository |  | ||||||
| public interface PostRepository extends CrudRepository<Post, Long> { |  | ||||||
| 
 |  | ||||||
|     @Query("select id, description, illustration, title, body, category, publication_date " + |  | ||||||
|             "from post join publication on post.id=publication.post_fk where publication.author_fk=:authorId") |  | ||||||
|     List<Post> findPostsOfAuthor(UUID authorId); |  | ||||||
| 
 |  | ||||||
|     List<Post> findAll(); |  | ||||||
| } |  | ||||||
| @ -1,39 +0,0 @@ | |||||||
| package com.guams.review.model.dao; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| import lombok.Getter; |  | ||||||
| import lombok.Setter; |  | ||||||
| import lombok.experimental.Accessors; |  | ||||||
| import org.springframework.data.annotation.Id; |  | ||||||
| import org.springframework.data.relational.core.mapping.Column; |  | ||||||
| import org.springframework.data.relational.core.mapping.Table; |  | ||||||
| import org.springframework.security.core.GrantedAuthority; |  | ||||||
| import org.springframework.security.core.userdetails.UserDetails; |  | ||||||
| 
 |  | ||||||
| import java.util.Collection; |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.UUID; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @Getter |  | ||||||
| @Setter |  | ||||||
| @Accessors(chain = true) |  | ||||||
| @Table(name = "author") |  | ||||||
| public class Author { |  | ||||||
| 
 |  | ||||||
|     @Id |  | ||||||
|     UUID id; |  | ||||||
| 
 |  | ||||||
|     @Column("name") |  | ||||||
|     String name; |  | ||||||
| 
 |  | ||||||
|     @Column("password") |  | ||||||
|     String password; |  | ||||||
| 
 |  | ||||||
|     @Column("profile_picture") |  | ||||||
|     byte[] profilePicture; |  | ||||||
| 
 |  | ||||||
|     @Column("role") |  | ||||||
|     String role; |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -1,12 +0,0 @@ | |||||||
| package com.guams.review.model.dao; |  | ||||||
| 
 |  | ||||||
| import lombok.Getter; |  | ||||||
| import lombok.Setter; |  | ||||||
| import lombok.experimental.Accessors; |  | ||||||
| 
 |  | ||||||
| @Getter |  | ||||||
| @Setter |  | ||||||
| @Accessors(chain = true) |  | ||||||
| public class AuthorToken { |  | ||||||
|     String token; |  | ||||||
| } |  | ||||||
| @ -1,32 +0,0 @@ | |||||||
| package com.guams.review.model.dao; |  | ||||||
| 
 |  | ||||||
| import lombok.Getter; |  | ||||||
| import lombok.Setter; |  | ||||||
| import lombok.experimental.Accessors; |  | ||||||
| import org.springframework.data.annotation.Id; |  | ||||||
| import org.springframework.data.relational.core.mapping.Column; |  | ||||||
| import org.springframework.data.relational.core.mapping.Table; |  | ||||||
| 
 |  | ||||||
| import java.time.LocalDate; |  | ||||||
| 
 |  | ||||||
| @Getter |  | ||||||
| @Setter |  | ||||||
| @Accessors(chain = true) |  | ||||||
| @Table(name = "post") |  | ||||||
| public class Post { |  | ||||||
|     @Id |  | ||||||
|     Long id; |  | ||||||
|     @Column("description") |  | ||||||
|     String description; |  | ||||||
|     @Column("illustration") |  | ||||||
|     byte[] illustration; |  | ||||||
|     @Column("title") |  | ||||||
|     String title; |  | ||||||
|     @Column("body") |  | ||||||
|     String body; |  | ||||||
|     @Column("category") |  | ||||||
|     String category; |  | ||||||
|     @Column("publication_date") |  | ||||||
|     LocalDate publicationDate; |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
							
								
								
									
										54
									
								
								src/main/java/com/guams/review/modele/Post.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/main/java/com/guams/review/modele/Post.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | |||||||
|  | package com.guams.review.modele; | ||||||
|  | 
 | ||||||
|  | import jakarta.persistence.*; | ||||||
|  | import lombok.Builder; | ||||||
|  | import lombok.Getter; | ||||||
|  | import lombok.Setter; | ||||||
|  | 
 | ||||||
|  | @Entity | ||||||
|  | @Getter | ||||||
|  | @Table(name = "POST") | ||||||
|  | public class Post | ||||||
|  | { | ||||||
|  |     @Id | ||||||
|  |     @GeneratedValue | ||||||
|  |     private Long id; | ||||||
|  |     @Column(name = "TITLE", nullable = false) | ||||||
|  |     private String title; | ||||||
|  |     @Column(name = "BODY", nullable = false) | ||||||
|  |     private String body; | ||||||
|  |     @Column(name = "IMAGE") | ||||||
|  |     private String image; | ||||||
|  |     @ManyToOne | ||||||
|  |     @JoinColumn(name = "USER_ID", nullable = false) | ||||||
|  |     private User user; | ||||||
|  | 
 | ||||||
|  |     public Post() | ||||||
|  |     {} | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     public Post setId(Long id) { | ||||||
|  |         this.id = id; | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Post setTitle(String title) { | ||||||
|  |         this.title = title; | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Post setBody(String body) { | ||||||
|  |         this.body = body; | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Post setImage(String image) { | ||||||
|  |         this.image = image; | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Post setUser(User user) { | ||||||
|  |         this.user = user; | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										51
									
								
								src/main/java/com/guams/review/modele/User.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/main/java/com/guams/review/modele/User.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | |||||||
|  | package com.guams.review.modele; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | import jakarta.persistence.*; | ||||||
|  | import lombok.Builder; | ||||||
|  | import lombok.Getter; | ||||||
|  | import lombok.NoArgsConstructor; | ||||||
|  | import lombok.Setter; | ||||||
|  | 
 | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @Entity | ||||||
|  | @Getter | ||||||
|  | @Table(name = "USERS") | ||||||
|  | public class User { | ||||||
|  | 
 | ||||||
|  |     @Id | ||||||
|  |     @GeneratedValue | ||||||
|  |     private Long id; | ||||||
|  | 
 | ||||||
|  |     @Column(name = "LOGIN", nullable = false, unique = true) | ||||||
|  |     private String login; | ||||||
|  | 
 | ||||||
|  |     @Column(name = "PASSWORD", nullable = false) | ||||||
|  |     private String password; | ||||||
|  | 
 | ||||||
|  |     @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) | ||||||
|  |     private List<Post> posts; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     public User setId(Long id) { | ||||||
|  |         this.id = id; | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public User setLogin(String login) { | ||||||
|  |         this.login = login; | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public User setPassword(String password) { | ||||||
|  |         this.password = password; | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public User setPosts(List<Post> posts) { | ||||||
|  |         this.posts = posts; | ||||||
|  |         return this; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,12 @@ | |||||||
|  | package com.guams.review.repository; | ||||||
|  | 
 | ||||||
|  | import com.guams.review.modele.User; | ||||||
|  | import org.springframework.data.jpa.repository.JpaRepository; | ||||||
|  | import org.springframework.stereotype.Repository; | ||||||
|  | 
 | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
|  | @Repository | ||||||
|  | public interface UserRepository extends JpaRepository<User, Long> | ||||||
|  | { | ||||||
|  | } | ||||||
| @ -1,84 +0,0 @@ | |||||||
| package com.guams.review.service; |  | ||||||
| 
 |  | ||||||
| import com.guams.review.exception.NotFoundException; |  | ||||||
| import com.guams.review.exception.ForbiddenExecption; |  | ||||||
| import com.guams.review.model.AuthorRepository; |  | ||||||
| import com.guams.review.model.PostRepository; |  | ||||||
| import com.guams.review.model.dao.Author; |  | ||||||
| import com.guams.review.model.dao.Post; |  | ||||||
| import com.guams.review.service.mapper.Mapper; |  | ||||||
| import com.guams.review.service.mapper.ReturnableAuthor; |  | ||||||
| import lombok.RequiredArgsConstructor; |  | ||||||
| import org.springframework.security.core.Authentication; |  | ||||||
| import org.springframework.security.core.authority.SimpleGrantedAuthority; |  | ||||||
| import org.springframework.security.core.userdetails.User; |  | ||||||
| import org.springframework.security.core.userdetails.UserDetails; |  | ||||||
| import org.springframework.security.core.userdetails.UserDetailsService; |  | ||||||
| import org.springframework.security.core.userdetails.UsernameNotFoundException; |  | ||||||
| import org.springframework.stereotype.Service; |  | ||||||
| import org.springframework.transaction.annotation.Transactional; |  | ||||||
| 
 |  | ||||||
| import java.util.*; |  | ||||||
| 
 |  | ||||||
| @Service |  | ||||||
| @RequiredArgsConstructor |  | ||||||
| public class AuthorService implements UserDetailsService |  | ||||||
| { |  | ||||||
|     private final Mapper mapper; |  | ||||||
|     private final AuthorRepository authorRepository; |  | ||||||
|     private final PostRepository postRepository; |  | ||||||
| 
 |  | ||||||
|     public List<ReturnableAuthor> list() { |  | ||||||
|         return authorRepository.findAll().stream() |  | ||||||
|                 .map(mapper::mapAuthor) |  | ||||||
|                 .toList(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public List<Post> listPublicationOfAuthor(UUID authorId) { |  | ||||||
|         return postRepository.findPostsOfAuthor(authorId); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Optional<Author> findById(UUID id) { |  | ||||||
|         return authorRepository.findById(id); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public ReturnableAuthor insert(Author author) { |  | ||||||
|         return mapper.mapAuthor(authorRepository.save(author)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Transactional |  | ||||||
|     public void insertPublications(UUID authorId, List<Long> postIds) { |  | ||||||
|         for (Long postId : postIds) { |  | ||||||
|             authorRepository.deletePublication(authorId, postId); |  | ||||||
|             if (postRepository.findById(postId).isPresent()) { |  | ||||||
|                 authorRepository.insertPublication(authorId, postId); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Author verifyIfUserIsAuthorized(Authentication authentication, UUID id) { |  | ||||||
|         if (authentication == null || !authentication.isAuthenticated()) { |  | ||||||
|             throw new ForbiddenExecption("You have to login first"); |  | ||||||
|         } |  | ||||||
|         Author author = findById(id).orElseThrow(() -> new NotFoundException("Author not found")); |  | ||||||
|         String username = authentication.getName(); |  | ||||||
|         Author authorAuthenticated = authorRepository.findByName(username); |  | ||||||
|         if (authorAuthenticated.getId().compareTo(author.getId()) != 0 && !authorAuthenticated.getRole().equals("ADMIN")) { |  | ||||||
|             throw new ForbiddenExecption("Specified Author is not authorized to do that"); |  | ||||||
|         } |  | ||||||
|         return author; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void delete(Author author) { |  | ||||||
|         authorRepository.delete(author); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { |  | ||||||
|         Author author = authorRepository.findByName(username); |  | ||||||
|         if (author == null) { |  | ||||||
|             throw new UsernameNotFoundException(username); |  | ||||||
|         } |  | ||||||
|         return new User(author.getName(), author.getPassword(), Collections.singletonList(new SimpleGrantedAuthority(author.getRole()))); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,34 +0,0 @@ | |||||||
| package com.guams.review.service; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| import com.guams.review.model.dao.Post; |  | ||||||
| import com.guams.review.model.PostRepository; |  | ||||||
| import lombok.RequiredArgsConstructor; |  | ||||||
| import org.springframework.stereotype.Service; |  | ||||||
| 
 |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.Optional; |  | ||||||
| 
 |  | ||||||
| @Service |  | ||||||
| @RequiredArgsConstructor |  | ||||||
| public class PostService |  | ||||||
| { |  | ||||||
|     private final PostRepository postRepository; |  | ||||||
| 
 |  | ||||||
|     public List<Post> list() { |  | ||||||
|         return postRepository.findAll(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Optional<Post> findById(Long id) { |  | ||||||
|         return postRepository.findById(id); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Post insert(Post post) { |  | ||||||
|         return postRepository.save(post); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void delete(Long id) { |  | ||||||
|         postRepository.deleteById(id); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
							
								
								
									
										36
									
								
								src/main/java/com/guams/review/service/UserService.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/main/java/com/guams/review/service/UserService.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | package com.guams.review.service; | ||||||
|  | 
 | ||||||
|  | import com.guams.review.modele.Post; | ||||||
|  | import com.guams.review.modele.User; | ||||||
|  | import com.guams.review.repository.UserRepository; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | 
 | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Optional; | ||||||
|  | 
 | ||||||
|  | @Service | ||||||
|  | public class UserService | ||||||
|  | { | ||||||
|  |     private final UserRepository userRepository; | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     public UserService(UserRepository userRepository) { | ||||||
|  |         this.userRepository = userRepository; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public List<User> getUsers() | ||||||
|  |     { | ||||||
|  |         return userRepository.findAll(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void saveUser(User user) | ||||||
|  |     { | ||||||
|  |         userRepository.save(user); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Optional<User> findById(Long id) | ||||||
|  |     { | ||||||
|  |         return userRepository.findById(id); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,18 +0,0 @@ | |||||||
| package com.guams.review.service.mapper; |  | ||||||
| 
 |  | ||||||
| import com.guams.review.model.dao.Author; |  | ||||||
| import org.springframework.stereotype.Component; |  | ||||||
| 
 |  | ||||||
| @Component |  | ||||||
| public class Mapper { |  | ||||||
| 
 |  | ||||||
|     public Mapper() {} |  | ||||||
| 
 |  | ||||||
|     public ReturnableAuthor mapAuthor(Author author) { |  | ||||||
|         return new ReturnableAuthor() |  | ||||||
|                 .setId(author.getId()) |  | ||||||
|                 .setName(author.getName()) |  | ||||||
|                 .setRole(author.getRole()) |  | ||||||
|                 .setProfilePicture(author.getProfilePicture()); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,17 +0,0 @@ | |||||||
| package com.guams.review.service.mapper; |  | ||||||
| 
 |  | ||||||
| import lombok.Getter; |  | ||||||
| import lombok.Setter; |  | ||||||
| import lombok.experimental.Accessors; |  | ||||||
| 
 |  | ||||||
| import java.util.UUID; |  | ||||||
| 
 |  | ||||||
| @Getter |  | ||||||
| @Setter |  | ||||||
| @Accessors(chain = true) |  | ||||||
| public class ReturnableAuthor { |  | ||||||
|     private UUID id; |  | ||||||
|     private String name; |  | ||||||
|     private byte[] profilePicture; |  | ||||||
|     private String role; |  | ||||||
| } |  | ||||||
| @ -1,6 +1,6 @@ | |||||||
| spring.security.oauth2.client.registration.github.client-id=Ov23ligoCzKHHyyIzIbS |  | ||||||
| spring.security.oauth2.client.registration.github.client-secret=c660f476763404f41da43e7a3f7e9648f94b107d |  | ||||||
| spring.application.name=reView | spring.application.name=reView | ||||||
| spring.datasource.url=jdbc:postgresql://localhost:5432/reviewDB | spring.datasource.url=jdbc:postgresql://localhost:5432/review | ||||||
| spring.datasource.username=postgres | spring.datasource.username=postgres | ||||||
| spring.datasource.password=Azerty1234 | spring.datasource.password=Azerty1234 | ||||||
|  | spring.jpa.hibernate.ddl-auto=create-drop | ||||||
|  | spring.jpa.show-sql=true | ||||||
| @ -1,31 +0,0 @@ | |||||||
| drop table if exists publication; |  | ||||||
| drop table if exists post; |  | ||||||
| drop table if exists author; |  | ||||||
| 
 |  | ||||||
| create table author |  | ||||||
| ( |  | ||||||
|     id              uuid        default gen_random_uuid() primary key, |  | ||||||
|     name            varchar(255) unique        not null, |  | ||||||
|     password        text                       not null, |  | ||||||
|     profile_picture bytea, |  | ||||||
|     role            varchar(50) default 'USER' not null |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| create table post |  | ||||||
| ( |  | ||||||
|     id               serial primary key, |  | ||||||
|     description      varchar(512) not null, |  | ||||||
|     illustration     bytea, |  | ||||||
|     title            varchar(50)  not null, |  | ||||||
|     body             text         not null, |  | ||||||
|     category         varchar(50)  not null, |  | ||||||
|     publication_date date         not null |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| create table publication |  | ||||||
| ( |  | ||||||
|     author_fk uuid, |  | ||||||
|     post_fk   serial, |  | ||||||
|     foreign key (author_fk) references author (id), |  | ||||||
|     foreign key (post_fk) references post (id) |  | ||||||
| ); |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user