Author SHA1 Message Date
marc ce03399f5a docker-compose 2022-05-30 16:07:25 +02:00
efaviere 5408afa708 all 2022-05-30 05:56:58 +02:00
Crakleurs cec5a8dd3d auth 2022-05-26 17:07:42 +02:00
Etienne Faviere d117162874 Merge pull request #1 from Crakleurs/master
Master
2022-05-16 14:50:24 +02:00
45 changed files with 650 additions and 168 deletions
+3 -4
View File
@@ -1,13 +1,12 @@
version: '3.1'
version: "3.9"
services:
db:
image: postgres
restart: always
restart: unless-stopped
environment:
POSTGRES_DB: music
POSTGRES_USER: admin
POSTGRES_PASSWORD: password
ports:
- "5432:5432"
- "5432:5432"
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

+11 -4
View File
@@ -29,10 +29,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-security</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
@@ -80,6 +80,13 @@
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.18.1</version>
</dependency>
</dependencies>
<build>
@@ -19,18 +19,23 @@ public class ArticlesController {
return this.articlesService.findOne(id);
}
@GetMapping()
@GetMapping("/items")
public Iterable<ArticleEntity> findAll() {
return this.articlesService.findAll();
}
@GetMapping("/djs")
public Iterable<ArticleEntity> findAllDjs() {
return this.articlesService.findAll();
}
@PostMapping()
public ArticleEntity createArticle(@RequestBody ArticleDto articleDto) {
return this.articlesService.createArticle(articleDto);
}
@PatchMapping("/{id}")
public ArticleEntity createArticle(@PathVariable Long id, @RequestBody ArticleDto articleDto) {
public ArticleEntity editArticle(@PathVariable Long id, @RequestBody ArticleDto articleDto) {
return this.articlesService.updateArticle(id, articleDto);
}
@@ -0,0 +1,22 @@
package com.music.projectmusicapi.controllers;
import com.music.projectmusicapi.entities.CategoryEntity;
import com.music.projectmusicapi.services.CategoriesService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@Validated
@RequestMapping("/category")
@RequiredArgsConstructor
public class CategoriesController {
private final CategoriesService categoriesService;
@GetMapping()
public List<CategoryEntity> findAll() {
return this.categoriesService.findAll();
}
}
@@ -6,9 +6,11 @@ import com.music.projectmusicapi.services.ImagesService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
import java.io.IOException;
import java.util.List;
@RestController
@Validated
@@ -22,13 +24,18 @@ public class ImagesController {
return this.imagesService.findImage(id);
}
@GetMapping("/list/{articleId}")
public List<ImageEntity> getImages(@PathVariable Long articleId) {
return this.imagesService.findImages(articleId);
}
@DeleteMapping("/{id}")
public void deleteImage(@PathVariable Long id) throws IOException {
this.imagesService.deleteImage(id);
}
@PostMapping("/{articleId}")
public Iterable<ImageEntity> createImages(@PathVariable Long articleId, @RequestBody ImageDto imageDto) {
return this.imagesService.createImages(articleId, imageDto);
@PostMapping(value = "/{articleId}")
public Iterable<ImageEntity> createImages(@PathVariable Long articleId, @RequestParam(value = "files",required = false) MultipartFile[] files) {
return this.imagesService.createImages(articleId, files);
}
}
@@ -0,0 +1,31 @@
package com.music.projectmusicapi.controllers;
import com.music.projectmusicapi.services.LikesService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@RestController
@Validated
@RequestMapping("/like")
@RequiredArgsConstructor
public class LikesController {
private final LikesService likesService;
@GetMapping("/{articleId}")
public int countLikes(@PathVariable Long articleId) {
return this.likesService.countLikes(articleId);
}
@GetMapping("/me/{articleId}")
public boolean isLiked(Authentication authentication, @PathVariable Long articleId) {
return likesService.isLiked(authentication, articleId);
}
@PostMapping("/{articleId}")
public void like(Authentication authentication, @PathVariable Long articleId) {
likesService.like(authentication, articleId);
}
}
@@ -0,0 +1,23 @@
package com.music.projectmusicapi.controllers;
import com.music.projectmusicapi.entities.ReservationEntity;
import com.music.projectmusicapi.services.ReservationService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Validated
@RequestMapping("reservation")
@RequiredArgsConstructor
public class ReservationController {
private ReservationService reservationService;
@GetMapping("/{id}")
public ReservationEntity getReservation(@PathVariable Long id) {
return this.reservationService.getReservation(id);
}
}
@@ -1,38 +0,0 @@
package com.music.projectmusicapi.controllers;
import com.music.projectmusicapi.dto.TagDto;
import com.music.projectmusicapi.entities.TagEntity;
import com.music.projectmusicapi.services.TagsService;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@Validated
@RequestMapping("tag")
@RequiredArgsConstructor
public class TagsController {
private final TagsService tagsService;
@GetMapping()
public List<TagEntity> getTags() {
return this.tagsService.getTags();
}
@PostMapping()
public TagEntity createTag(@RequestBody TagDto tagDto) {
return this.tagsService.createTag(tagDto);
}
@PatchMapping("/{id}")
public TagEntity updateTag(@PathVariable Long id, @RequestBody TagDto tagDto) {
return this.tagsService.updateTag(id, tagDto);
}
@DeleteMapping("/{id}")
public void deleteTag(@PathVariable Long id) {
this.tagsService.deleteTag(id);
}
}
@@ -1,9 +1,11 @@
package com.music.projectmusicapi.controllers;
import com.music.projectmusicapi.dto.LoginDto;
import com.music.projectmusicapi.dto.UserDto;
import com.music.projectmusicapi.entities.UserEntity;
import com.music.projectmusicapi.services.UsersService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@@ -33,4 +35,14 @@ public class UsersController {
public UserEntity findOne(@PathVariable Long id) {
return usersService.findOne(id);
}
@GetMapping("/me")
public UserEntity findMe(Authentication authentication) {
return usersService.findMe(authentication);
}
@GetMapping("/reset")
public void resetDatabase() {
usersService.resetDatabase();
}
}
@@ -0,0 +1,8 @@
package com.music.projectmusicapi.dao;
import com.music.projectmusicapi.entities.CategoryEntity;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface CategoryRepository extends CrudRepository<CategoryEntity, Long> {
}
@@ -0,0 +1,14 @@
package com.music.projectmusicapi.dao;
import com.music.projectmusicapi.entities.LikeEntity;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface LikeRepository extends CrudRepository<LikeEntity, Long> {
public int countAllByArticle_Id(Long articleId);
public int countAllByArticle_IdAndUser_Email(Long articleId, String name);
public void deleteAllByArticle_IdAndUser_Email(Long articleId, String name);
}
@@ -1,19 +1,42 @@
package com.music.projectmusicapi.dao.article;
import com.music.projectmusicapi.dao.CategoryRepository;
import com.music.projectmusicapi.dto.ArticleDto;
import com.music.projectmusicapi.entities.ArticleEntity;
import com.music.projectmusicapi.entities.CategoryEntity;
import com.music.projectmusicapi.exceptions.HttpNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.Optional;
@RequiredArgsConstructor
@Component
public class ArticleFactory {
public static ArticleEntity toEntity(ArticleDto articleDto) {
private final CategoryRepository categoryRepository;
public ArticleEntity toEntity(ArticleDto articleDto) {
Optional<CategoryEntity> categoryEntity = this.categoryRepository.findById(articleDto.getCategory());
if (!categoryEntity.isPresent())
throw new HttpNotFoundException("Pas de catégorie trouvée");
ArticleEntity articleEntity = new ArticleEntity();
articleEntity.setName(articleDto.getName());
articleEntity.setDescription(articleDto.getDescription());
articleEntity.setCategory(categoryEntity.get());
articleEntity.setPriceByDay(articleDto.getPriceByDay());
return articleEntity;
}
public static ArticleEntity updateToEntity(ArticleDto articleDto, ArticleEntity articleEntity) {
public ArticleEntity updateToEntity(ArticleDto articleDto, ArticleEntity articleEntity) {
Optional<CategoryEntity> categoryEntity = this.categoryRepository.findById(articleDto.getCategory());
if (!categoryEntity.isPresent())
throw new HttpNotFoundException("Pas de catégorie trouvée");
articleEntity.setName(articleDto.getName());
articleEntity.setDescription(articleDto.getDescription());
articleEntity.setCategory(categoryEntity.get());
return articleEntity;
}
}
@@ -4,4 +4,5 @@ import com.music.projectmusicapi.entities.ImageEntity;
import org.springframework.data.repository.CrudRepository;
public interface ImageRepository extends CrudRepository<ImageEntity, Long> {
public Iterable<ImageEntity> findImageEntitiesByArticle_Id(Long articleId);
}
@@ -1,18 +0,0 @@
package com.music.projectmusicapi.dao.tag;
import com.music.projectmusicapi.dto.TagDto;
import com.music.projectmusicapi.entities.TagEntity;
public class TagFactory {
public static TagEntity toEntity(TagDto tagDto) {
TagEntity tagEntity = new TagEntity();
tagEntity.setName(tagDto.getName());
return tagEntity;
}
public static TagEntity updateToEntity(TagDto tagDto, TagEntity tagEntity) {
tagEntity.setName(tagDto.getName());
return tagEntity;
}
}
@@ -1,9 +0,0 @@
package com.music.projectmusicapi.dao.tag;
import com.music.projectmusicapi.entities.TagEntity;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface TagRepository extends CrudRepository<TagEntity, Long> {
}
@@ -2,18 +2,27 @@ package com.music.projectmusicapi.dao.user;
import com.music.projectmusicapi.dto.UserDto;
import com.music.projectmusicapi.entities.UserEntity;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
@Component
public class UserFactory {
public static UserEntity toUser(UserDto userDto) {
private final PasswordEncoder passwordEncoder;
public UserFactory(@Lazy PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
public UserEntity toUser(UserDto userDto) {
UserEntity userEntity = new UserEntity();
userEntity.setCoins(100F);
userEntity.setEmail(userDto.getEmail());
userEntity.setFirstname(userDto.getFirstname());
userEntity.setName(userDto.getName());
userEntity.setFirstName(userDto.getFirstName());
userEntity.setLastName(userDto.getLastName());
userEntity.setIsAdmin(false);
userEntity.setIsBanned(false);
userEntity.setPassword(userDto.getPassword());
userEntity.setPassword(this.passwordEncoder.encode(userDto.getPassword()));
return userEntity;
}
}
@@ -2,6 +2,11 @@ package com.music.projectmusicapi.dao.user;
import com.music.projectmusicapi.entities.UserEntity;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface UserRepository extends CrudRepository<UserEntity, Long> {
Optional<UserEntity> findByEmail(String email);
}
@@ -4,6 +4,8 @@ import lombok.Getter;
import lombok.Setter;
import org.springframework.lang.NonNull;
import java.util.List;
@Getter
@Setter
public class ArticleDto {
@@ -12,4 +14,10 @@ public class ArticleDto {
@NonNull
String description;
@NonNull
Float priceByDay;
@NonNull
Long category;
}
@@ -0,0 +1,14 @@
package com.music.projectmusicapi.dto;
import lombok.Getter;
import lombok.Setter;
import org.springframework.lang.NonNull;
@Getter @Setter
public class LoginDto {
@NonNull
private String email;
@NonNull
private String password;
}
@@ -7,10 +7,10 @@ import org.springframework.lang.NonNull;
@Getter @Setter
public class UserDto {
@NonNull
private String firstname;
private String firstName;
@NonNull
private String name;
private String lastName;
@NonNull
private String email;
@@ -18,7 +18,4 @@ public class UserDto {
@NonNull
private String password;
@NonNull
private String confirmPassword;
}
@@ -3,6 +3,8 @@ package com.music.projectmusicapi.entities;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import javax.persistence.*;
import java.util.List;
@@ -17,13 +19,15 @@ public class ArticleEntity {
@Column(nullable = false)
private String name;
@OneToMany
@Column(nullable = false)
private Float priceByDay;
@OneToMany(fetch = FetchType.EAGER)
private List<ImageEntity> images;
@Column(columnDefinition = "TEXT")
private String description;
@ManyToMany
private List<TagEntity> tags;
@ManyToOne
private CategoryEntity category;
}
@@ -1,6 +1,5 @@
package com.music.projectmusicapi.entities;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@@ -9,10 +8,10 @@ import javax.persistence.*;
import java.util.List;
@Entity
@Getter @Setter
@Getter
@Setter
@NoArgsConstructor
public class TagEntity {
public class CategoryEntity {
@Id
@GeneratedValue
private Long id;
@@ -20,8 +19,6 @@ public class TagEntity {
@Column(nullable = false)
private String name;
@ManyToMany
private List<ArticleEntity> articles;
@OneToMany(fetch = FetchType.EAGER)
private List<ArticleEntity> article;
}
@@ -19,6 +19,6 @@ public class ImageEntity {
@Column(nullable = false)
private String path;
@ManyToOne
@ManyToOne()
private ArticleEntity article;
}
@@ -0,0 +1,26 @@
package com.music.projectmusicapi.entities;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
@Entity
@Getter
@Setter
@NoArgsConstructor
public class LikeEntity {
@Id
@GeneratedValue
private Long id;
@ManyToOne
private ArticleEntity article;
@ManyToOne
private UserEntity user;
}
@@ -18,10 +18,10 @@ public class UserEntity {
private Long id;
@Column()
private String firstname;
private String firstName;
@Column()
private String name;
private String lastName;
@Column(nullable = false)
private String email;
@@ -0,0 +1,43 @@
package com.music.projectmusicapi.filter;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
response.setHeader("Access-Control-Expose-Headers", "x-refresh-token, authorization");
if (request.getMethod().equalsIgnoreCase("OPTIONS")) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void destroy() {
}
}
@@ -0,0 +1,55 @@
package com.music.projectmusicapi.filter;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
@Slf4j
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private final AuthenticationManager authenticationManager;
public CustomAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
String username = request.getParameter("email");
String password = request.getParameter("password");
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
return authenticationManager.authenticate(authenticationToken);
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException, ServletException {
User user = (User) authentication.getPrincipal();
Algorithm algorithm = Algorithm.HMAC256("ohezrfnapdpo".getBytes());
String accessToken = JWT.create()
.withSubject(user.getUsername())
.withExpiresAt(new Date(System.currentTimeMillis() + 120 * 60 * 1000))
.withIssuer(request.getRequestURL().toString())
.withClaim("roles", user.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()))
.sign(algorithm);
Map<String, String> tokens = new HashMap<>();
response.setContentType("application/json");
tokens.put("accessToken", accessToken);
new ObjectMapper().writeValue(response.getOutputStream(), tokens);
}
}
@@ -0,0 +1,61 @@
package com.music.projectmusicapi.filter;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import static java.util.Arrays.stream;
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
if (request.getServletPath().equals("/login") || request.getServletPath().equals("/users") && request.getMethod().equals("POST") || request.getServletPath().equals("/users/reset") && request.getMethod().equals("GET") || request.getServletPath().equals("/category") && request.getMethod().equals("GET") || request.getServletPath().contains("/image") && request.getMethod().equals("GET")) {
filterChain.doFilter(request, response);
return;
}
String token = request.getHeader("Authorization");
if (token != null && token.startsWith("Bearer ")) {
try {
token = token.substring(7);
Algorithm algorithm = Algorithm.HMAC256("ohezrfnapdpo".getBytes());
JWTVerifier jwtVerifier = JWT.require(algorithm).build();
DecodedJWT decodedJWT = jwtVerifier.verify(token);
String username = decodedJWT.getSubject();
String[] roles = decodedJWT.getClaim("roles").asArray(String.class);
Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
stream(roles).forEach(role -> {
authorities.add(new SimpleGrantedAuthority(role));
});
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, null, authorities);
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
filterChain.doFilter(request, response);
} catch (Exception exception) {
System.out.println(exception.getMessage());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication schema not found");
}
} else {
filterChain.doFilter(request, response);
}
}
}
@@ -0,0 +1,53 @@
package com.music.projectmusicapi.security;
import com.music.projectmusicapi.filter.CustomAuthenticationFilter;
import com.music.projectmusicapi.filter.JwtAuthenticationFilter;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
CustomAuthenticationFilter customAuthenticationFilter = new CustomAuthenticationFilter(authenticationManagerBean());
customAuthenticationFilter.setFilterProcessesUrl("/login");
http.csrf().disable();
http.addFilter(customAuthenticationFilter);
http.addFilterBefore(new JwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.authorizeRequests().anyRequest().permitAll();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder()
{
return new BCryptPasswordEncoder();
}
}
@@ -17,10 +17,11 @@ import java.util.Optional;
public class ArticlesService {
private final ArticleRepository articleRepository;
private final ImagesService imagesService;
private final ArticleFactory articleFactory;
public ArticleEntity getArticle(Long id) {
Optional<ArticleEntity> articleEntity = this.articleRepository.findById(id);
if (articleEntity.isEmpty())
if (!articleEntity.isPresent())
throw new HttpNotFoundException("L'article avec l'id " + id +" n'a pas été trouvé");
return articleEntity.get();
}
@@ -34,8 +35,7 @@ public class ArticlesService {
}
public ArticleEntity createArticle(ArticleDto articleDto) {
ArticleEntity articleEntity = ArticleFactory.toEntity(articleDto);
ArticleEntity articleEntity = this.articleFactory.toEntity(articleDto);
return this.articleRepository.save(articleEntity);
}
@@ -44,13 +44,14 @@ public class ArticlesService {
List<ImageEntity> imageEntities = articleEntity.getImages();
this.imagesService.deleteImages(imageEntities);
this.articleRepository.deleteById(id);
}
public ArticleEntity updateArticle(Long id, ArticleDto articleDto) {
ArticleEntity articleEntity = getArticle(id);
ArticleFactory.updateToEntity(articleDto, articleEntity);
this.articleFactory.updateToEntity(articleDto, articleEntity);
return this.articleRepository.save(articleEntity);
}
}
@@ -0,0 +1,20 @@
package com.music.projectmusicapi.services;
import com.music.projectmusicapi.dao.CategoryRepository;
import com.music.projectmusicapi.entities.CategoryEntity;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class CategoriesService {
private final CategoryRepository categoryRepository;
public List<CategoryEntity> findAll() {
return (List<CategoryEntity>) this.categoryRepository.findAll();
}
}
@@ -1,8 +1,7 @@
package com.music.projectmusicapi.services;
import com.music.projectmusicapi.dao.image.ImageRepository;
import com.music.projectmusicapi.dao.article.ArticleRepository;
import com.music.projectmusicapi.dto.ImageDto;
import com.music.projectmusicapi.dao.image.ImageRepository;
import com.music.projectmusicapi.entities.ArticleEntity;
import com.music.projectmusicapi.entities.ImageEntity;
import com.music.projectmusicapi.exceptions.HttpNotFoundException;
@@ -21,13 +20,13 @@ import java.util.*;
@RequiredArgsConstructor
public class ImagesService {
private final ImageRepository imageRepository;
private final ArticlesService articlesService;
private final ArticleRepository articleRepository;
private final Path folder = Paths.get("files");
public ImageEntity getImage(Long id) {
Optional<ImageEntity> imageEntity = this.imageRepository.findById(id);
if (imageEntity.isEmpty())
if (!imageEntity.isPresent())
throw new HttpNotFoundException("L'image avec l'id " + id +" n'a pas été trouvée");
return imageEntity.get();
@@ -41,13 +40,15 @@ public class ImagesService {
}
public Iterable<ImageEntity> createImages(Long articleId, ImageDto imageDto) {
ArticleEntity articleEntity = this.articlesService.getArticle(articleId);
public Iterable<ImageEntity> createImages(Long articleId, MultipartFile[] files) {
Optional<ArticleEntity> articleEntity = this.articleRepository.findById(articleId);
if (!articleEntity.isPresent())
throw new HttpNotFoundException("L'article avec l'id " + articleId +" n'a pas été trouvé");
List<ImageEntity> list = new ArrayList<>();
Arrays.stream(imageDto.getFiles()).forEach((file) -> {
Arrays.stream(files).forEach((file) -> {
try {
ImageEntity imageEntity = storeImage(articleEntity, file);
ImageEntity imageEntity = storeImage(articleEntity.get(), file);
list.add(imageEntity);
} catch (IOException e) {
e.printStackTrace();
@@ -85,4 +86,8 @@ public class ImagesService {
});
this.imageRepository.deleteAll(imageEntities);
}
public List<ImageEntity> findImages(Long articleId) {
return (List<ImageEntity>) this.imageRepository.findImageEntitiesByArticle_Id(articleId);
}
}
@@ -0,0 +1,50 @@
package com.music.projectmusicapi.services;
import com.music.projectmusicapi.dao.LikeRepository;
import com.music.projectmusicapi.dao.article.ArticleRepository;
import com.music.projectmusicapi.dao.user.UserRepository;
import com.music.projectmusicapi.entities.ArticleEntity;
import com.music.projectmusicapi.entities.LikeEntity;
import com.music.projectmusicapi.entities.UserEntity;
import com.music.projectmusicapi.exceptions.HttpBadRequestException;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
public class LikesService {
private LikeRepository likeRepository;
private ArticleRepository articleRepository;
private UserRepository userRepository;
public LikesService(LikeRepository likeRepository, ArticleRepository articleRepository, UserRepository userRepository) {
this.likeRepository = likeRepository;
this.articleRepository = articleRepository;
this.userRepository = userRepository;
}
public int countLikes(long articleId) {
return this.likeRepository.countAllByArticle_Id(articleId);
}
public boolean isLiked(Authentication authentication, Long articleId) {
return this.likeRepository.countAllByArticle_IdAndUser_Email(articleId, authentication.getName()) == 1;
}
public void like(Authentication authentication, Long articleId) {
if (isLiked(authentication, articleId))
this.likeRepository.deleteAllByArticle_IdAndUser_Email(articleId, authentication.getName());
LikeEntity likeEntity = new LikeEntity();
Optional<UserEntity> user = this.userRepository.findByEmail(authentication.getName());
Optional<ArticleEntity> article = this.articleRepository.findById(articleId);
if (!user.isPresent() || !article.isPresent())
throw new HttpBadRequestException("Erreur");
likeEntity.setArticle(article.get());
likeEntity.setUser(user.get());
this.likeRepository.save(likeEntity);
}
}
@@ -0,0 +1,24 @@
package com.music.projectmusicapi.services;
import com.music.projectmusicapi.dao.ReservationRepository;
import com.music.projectmusicapi.entities.ReservationEntity;
import com.music.projectmusicapi.exceptions.HttpNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class ReservationService {
private ReservationRepository reservationRepository;
public ReservationEntity getReservation(Long id) {
Optional<ReservationEntity> reservationEntity = this.reservationRepository.findById(id);
if (!reservationEntity.isPresent())
throw new HttpNotFoundException("la reservation n'a pas étée trouvée");
return reservationEntity.get();
}
}
@@ -1,45 +0,0 @@
package com.music.projectmusicapi.services;
import com.music.projectmusicapi.dao.tag.TagFactory;
import com.music.projectmusicapi.dao.tag.TagRepository;
import com.music.projectmusicapi.dto.TagDto;
import com.music.projectmusicapi.entities.TagEntity;
import com.music.projectmusicapi.exceptions.HttpNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class TagsService {
private final TagRepository tagRepository;
public List<TagEntity> getTags() {
return (List<TagEntity>) this.tagRepository.findAll();
}
public TagEntity createTag(TagDto tagDto) {
TagEntity tagEntity = TagFactory.toEntity(tagDto);
return this.tagRepository.save(tagEntity);
}
public TagEntity updateTag(Long id, TagDto tagDto) {
TagEntity tag = getTag(id);
TagEntity tagEntity = TagFactory.updateToEntity(tagDto, tag);
return this.tagRepository.save(tagEntity);
}
public void deleteTag(Long id) {
TagEntity tag = getTag(id);
this.tagRepository.delete(tag);
}
public TagEntity getTag(Long id) {
Optional<TagEntity> tag = this.tagRepository.findById(id);
if (tag.isEmpty())
throw new HttpNotFoundException("Le tag avec l'id " + id + " n'a pas été trouvé");
return tag.get();
}
}
@@ -1,26 +1,43 @@
package com.music.projectmusicapi.services;
import com.music.projectmusicapi.dao.CategoryRepository;
import com.music.projectmusicapi.dao.user.UserFactory;
import com.music.projectmusicapi.dto.UserDto;
import com.music.projectmusicapi.entities.CategoryEntity;
import com.music.projectmusicapi.entities.UserEntity;
import com.music.projectmusicapi.dao.user.UserRepository;
import com.music.projectmusicapi.exceptions.HttpBadRequestException;
import com.music.projectmusicapi.exceptions.HttpNotFoundException;
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 java.util.ArrayList;
import java.util.Collection;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class UsersService {
public class UsersService implements UserDetailsService {
private final UserRepository userRepository;
private final UserFactory userFactory;
private final CategoryRepository categoryRepository;
public UserEntity createUser(UserDto usersDTO) {
if (!usersDTO.getPassword().equals(usersDTO.getConfirmPassword()))
throw new HttpBadRequestException("Les deux mots de passes sont différents");
UserEntity userEntity = userFactory.toUser(usersDTO);
if (userEntity.getPassword().length() < 4)
throw new HttpBadRequestException("Le mot de passe doit contenir au moins 4 caractères");
Optional<UserEntity> oldUser = this.userRepository.findByEmail(usersDTO.getEmail());
if (oldUser.isPresent())
throw new HttpBadRequestException("L'addresse mail est déjà utilisée");
UserEntity userEntity = UserFactory.toUser(usersDTO);
return this.userRepository.save(userEntity);
}
@@ -36,15 +53,62 @@ public class UsersService {
public UserEntity findOne(Long id) {
return this.getUser(id);
}
public UserEntity getUser(Long id) {
Optional<UserEntity> userEntity = this.userRepository.findById(id);
if (userEntity.isEmpty())
if (!userEntity.isPresent())
throw new HttpNotFoundException("L'utilisateur avec l'id " + id + "n'a pas été trouvé");
return userEntity.get();
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("yo");
Optional<UserEntity> userEntity = this.userRepository.findByEmail(username);
if (!userEntity.isPresent())
throw new UsernameNotFoundException("L'utilistaeur n'a pas été trouvé");
UserEntity user = userEntity.get();
Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
SimpleGrantedAuthority simpleGrantedAuthority = user.getIsAdmin() ? new SimpleGrantedAuthority("ADMIN") : new SimpleGrantedAuthority("USER");
authorities.add(simpleGrantedAuthority);
return new User(user.getEmail(), user.getPassword(), authorities);
}
public UserEntity findMe(Authentication authentication) {
Optional<UserEntity> userEntity = this.userRepository.findByEmail(authentication.getName());
if (!userEntity.isPresent())
throw new HttpNotFoundException("L'utilisateur avec l'email " + authentication.getName() + "n'a pas été trouvé");
return userEntity.get();
}
public void resetDatabase() {
UserDto adminDto = new UserDto();
adminDto.setFirstName("Admin");
adminDto.setLastName("Admin");
adminDto.setEmail("admin@gmail.com");
adminDto.setPassword("admin");
UserEntity admin = userFactory.toUser(adminDto);
admin.setIsAdmin(true);
admin.setCoins(99999F);
admin.setIsBanned(false);
this.userRepository.save(admin);
String[] names = {"dj", "enceintes", "instruments"};
for (String name : names) {
CategoryEntity category = new CategoryEntity();
category.setName(name);
this.categoryRepository.save(category);
}
}
}
+5 -1
View File
@@ -11,4 +11,8 @@ spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.PostgreSQLDialect
spring.jpa.show-sql=true
spring.servlet.multipart.max-file-size=50MB
spring.servlet.multipart.max-request-size=50MB
spring.servlet.multipart.max-request-size=50MB
spring.jpa.open-in-view = false
spring.main.allow-circular-references=true
spring.security.user.password=password