Commit c3dfa2f0 authored by Daniel Puchala's avatar Daniel Puchala
Browse files

Merge remote-tracking branch 'origin/devel-controller' into devel

# Conflicts:
#	rest/src/main/java/cz/fi/muni/pa165/movierecommender/rest/api/ReviewControllerProvider.java
parents 582cf0a5 18b2f154
package cz.fi.muni.pa165.movierecommender.api.dto.create;
import cz.fi.muni.pa165.movierecommender.api.dto.SimpleMovieDto;
import cz.fi.muni.pa165.movierecommender.api.dto.SimpleUserDto;
import lombok.Data;
import javax.validation.constraints.Max;
......@@ -15,10 +17,9 @@ import javax.validation.constraints.NotNull;
public class ReviewCreateDto implements CreateDto {
@NotNull
private Long userId;
private SimpleUserDto user;
@NotNull
private Long movieId;
private SimpleMovieDto movie;
@NotNull
private String text;
......
......@@ -39,8 +39,6 @@ import static java.util.Objects.requireNonNull;
* @author Daniel Puchala
* @author Petr Šlézar - authentication
*/
@Entity
@Getter
@Setter
......@@ -103,14 +101,6 @@ public class User extends GenericEntity implements UserDetails {
this.avatar = avatar;
}
public void addReview(Review review) {
reviews.add(review);
}
public void removeReview(Review review) {
reviews.remove(review);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
......@@ -170,3 +160,4 @@ public class User extends GenericEntity implements UserDetails {
return userType.equals(UserType.ADMIN);
}
}
......@@ -87,19 +87,19 @@ public class MovieControllerProvider implements MovieController {
return movieFacade.update(movie);
}
@GetMapping("{id}/recommended")
@GetMapping("/{id}/recommended")
@ResponseBody
public List<MovieDto> getRecommendedMovies(@PathVariable Long id) {
return movieFacade.getRecommendedByMovie(id);
}
@GetMapping("{id}/reviews")
@GetMapping("/{id}/reviews")
@ResponseBody
public List<ReviewDto> getMovieReviews(@PathVariable Long id) {
return reviewFacade.findByMovie(id);
}
@GetMapping("{id}/rating")
@GetMapping("/{id}/rating")
@ResponseBody
public Double getAverageRating(@PathVariable Long id) {
return reviewFacade.getAverageRating(id);
......
......@@ -2,13 +2,17 @@ package cz.fi.muni.pa165.movierecommender.rest.api;
import cz.fi.muni.pa165.movierecommender.api.dto.ReviewDto;
import cz.fi.muni.pa165.movierecommender.api.dto.create.ReviewCreateDto;
import cz.fi.muni.pa165.movierecommender.api.dto.update.ReviewUpdateDto;
import cz.fi.muni.pa165.movierecommender.rest.core.RoutesHolder;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
......@@ -30,7 +34,18 @@ public interface ReviewController {
List<ReviewDto> findByMovie(@PathVariable Long movieId);
@PreAuthorize("isAuthenticated()")
@GetMapping("/create")
@PostMapping
@ResponseBody
ReviewDto createReview(@RequestBody ReviewCreateDto reviewCreateDto);
@PreAuthorize("isAuthenticated() and #reviewUpdateDto.user.name == principal.username")
@PatchMapping
@ResponseBody
ReviewDto updateReview(@RequestBody ReviewUpdateDto reviewUpdateDto);
@PreAuthorize("isAuthenticated()")
@DeleteMapping("{id}")
@ResponseBody
void deleteReview(@PathVariable Long id);
}
......@@ -2,18 +2,30 @@ package cz.fi.muni.pa165.movierecommender.rest.api;
import cz.fi.muni.pa165.movierecommender.api.dto.ReviewDto;
import cz.fi.muni.pa165.movierecommender.api.dto.create.ReviewCreateDto;
import cz.fi.muni.pa165.movierecommender.api.dto.update.ReviewUpdateDto;
import cz.fi.muni.pa165.movierecommender.api.facade.ReviewFacade;
import cz.fi.muni.pa165.movierecommender.persistence.entity.Review;
import cz.fi.muni.pa165.movierecommender.rest.core.RoutesHolder;
import cz.fi.muni.pa165.movierecommender.service.service.exception.ForbiddenOperationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.constraints.NotNull;
import java.security.Principal;
import java.util.List;
/**
......@@ -46,11 +58,39 @@ public class ReviewControllerProvider implements ReviewController {
}
@PreAuthorize("isAuthenticated()")
@PostMapping("/create")
@PostMapping
@ResponseBody
public ReviewDto createReview(ReviewCreateDto reviewCreateDto) {
public ReviewDto createReview(@RequestBody ReviewCreateDto reviewCreateDto) {
if (reviewCreateDto == null) throw new IllegalArgumentException("Create review body cannnot be null");
return reviewFacade.create(reviewCreateDto);
}
@PreAuthorize("isAuthenticated() and #reviewCreateDto.user.name == principal.username")
@PatchMapping
@ResponseBody
public ReviewDto updateReview(@RequestBody ReviewUpdateDto reviewUpdateDto){
if(reviewUpdateDto == null) throw new IllegalArgumentException("Update review body cannot be null");
return reviewFacade.update(reviewUpdateDto);
}
@PreAuthorize("isAuthenticated()")
@DeleteMapping("{id}")
@ResponseBody
public void deleteReview(@PathVariable Long id){
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
boolean hasAdminRole = authentication.getAuthorities().stream()
.anyMatch(r -> r.getAuthority().equals("TYPE_ADMIN"));
String currentUserName = authentication.getName();
ReviewDto review = reviewFacade.findById(id);
if(!hasAdminRole && !currentUserName.equals(review.getUser().getName())){
throw new ForbiddenOperationException("Cannot delete not own review or no admin rights");
}
reviewFacade.delete(id);
}
}
\ No newline at end of file
......@@ -53,8 +53,8 @@ public class ReviewFacadeImpl extends GenericFacadeImpl<Review, ReviewDto, Revie
@Override
protected Review mapToCreatedEntity(ReviewCreateDto dto) {
User author = userService.findById(dto.getUserId());
Movie movie = movieService.findById(dto.getMovieId());
User author = userService.findById(dto.getUser().getId());
Movie movie = movieService.findById(dto.getMovie().getId());
Review createdReview = createMapper.toModel(dto);
createdReview.setUser(author);
......@@ -71,8 +71,8 @@ public class ReviewFacadeImpl extends GenericFacadeImpl<Review, ReviewDto, Revie
@Override
protected Review mapToUpdatedEntity(ReviewUpdateDto dto) {
User author = userService.findById(dto.getUserId());
Movie movie = movieService.findById(dto.getMovieId());
User author = userService.findById(dto.getUser().getId());
Movie movie = movieService.findById(dto.getMovie().getId());
Review updatedReview = updateMapper.toModel(dto);
updatedReview.setUser(author);
......@@ -146,12 +146,12 @@ public class ReviewFacadeImpl extends GenericFacadeImpl<Review, ReviewDto, Revie
public ReviewDto create(ReviewCreateDto createDto) {
Review entity = mapToCreatedEntity(createDto);
User author = userService.findById(createDto.getUserId());
User author = userService.findById(createDto.getUser().getId());
Set<Review> authorReviews = author.getReviews();
authorReviews.add(entity);
userService.update(author);
Movie movie = movieService.findById(createDto.getMovieId());
Movie movie = movieService.findById(createDto.getMovie().getId());
Set<Review> movieReviews = movie.getReviews();
movieReviews.add(entity);
movieService.update(movie);
......@@ -167,12 +167,12 @@ public class ReviewFacadeImpl extends GenericFacadeImpl<Review, ReviewDto, Revie
public ReviewDto update(ReviewUpdateDto updateDto) {
Review entity = mapToUpdatedEntity(updateDto);
User author = userService.findById(updateDto.getUserId());
User author = userService.findById(updateDto.getUser().getId());
Set<Review> authorReviews = author.getReviews();
authorReviews.add(entity);
userService.update(author);
Movie movie = movieService.findById(updateDto.getMovieId());
Movie movie = movieService.findById(updateDto.getMovie().getId());
Set<Review> movieReviews = movie.getReviews();
movieReviews.add(entity);
movieService.update(movie);
......
......@@ -3,6 +3,8 @@ package cz.fi.muni.pa165.movierecommender.service.mapper.create;
import cz.fi.muni.pa165.movierecommender.api.dto.create.ReviewCreateDto;
import cz.fi.muni.pa165.movierecommender.persistence.entity.Review;
import cz.fi.muni.pa165.movierecommender.service.mapper.SimpleMovieMapper;
import cz.fi.muni.pa165.movierecommender.service.mapper.SimpleUserMapper;
import org.mapstruct.Mapper;
/**
......@@ -10,7 +12,7 @@ import org.mapstruct.Mapper;
* <p>
* A simple mapper using mapstruct. Those attributes which are not mapped, will be later added in facade.
*/
@Mapper
@Mapper(uses = {SimpleMovieMapper.class, SimpleUserMapper.class})
public interface ReviewCreateMapper {
Review toModel(ReviewCreateDto dto);
......
......@@ -2,6 +2,8 @@ package cz.fi.muni.pa165.movierecommender.service.mapper.update;
import cz.fi.muni.pa165.movierecommender.api.dto.update.ReviewUpdateDto;
import cz.fi.muni.pa165.movierecommender.persistence.entity.Review;
import cz.fi.muni.pa165.movierecommender.service.mapper.SimpleMovieMapper;
import cz.fi.muni.pa165.movierecommender.service.mapper.SimpleUserMapper;
import org.mapstruct.Mapper;
/**
......@@ -9,7 +11,7 @@ import org.mapstruct.Mapper;
* <p>
* A simple mapper using mapstruct. Those attributes which are not mapped, will be later added in facade.
*/
@Mapper
@Mapper(uses = {SimpleMovieMapper.class, SimpleUserMapper.class})
public interface ReviewUpdateMapper {
Review toModel(ReviewUpdateDto dto);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment