Skip to content

Commit

Permalink
- Add findOwn endpoint to BookController
Browse files Browse the repository at this point in the history
- Implement findOwn in BookService
- Enforce owner verification in BookService methods
- Add repository method to find books by ids without pagination
- Refactor BookService constructor to inject BookRepository
  • Loading branch information
Chip3211 committed Sep 16, 2024
1 parent ac0270c commit 24bef13
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,9 @@ public Boolean isSubscribed(@PathVariable Long id) throws NotFoundException {
return service.subscribed(id);
}

@GetMapping("/own")
public List<Book> findOwn() throws CustomException {
return service.findOwn();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ public interface BookRepository extends JpaRepository<Book, Long> {
@Query("select b from Book b where b.id in :ids")
Page<Book> findByIds(@Param("ids") List<Long> ids, Pageable pageable);

@Query("select b from Book b where b.id in :ids")
List<Book> findByIds(@Param("ids") List<Long> ids);

@Query("select b from Book b where b.id = :id and (b.visible or b.owner.account.username = :username)")
Optional<Book> findById(@Param("id") Long id, @Param("username") String username);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class BookService extends BaseService implements ICRUDService<Book, BookDraft>, IPageableService<Book>, ISearchService<Book> {
Expand All @@ -31,11 +32,13 @@ public class BookService extends BaseService implements ICRUDService<Book, BookD
private final AuthorRepository authorRepository;

private final RecipeRepository recipeRepository;
private final BookRepository bookRepository;

protected BookService(BookRepository repository, AuthorRepository authorRepository, RecipeRepository recipeRepository) {
protected BookService(BookRepository repository, AuthorRepository authorRepository, RecipeRepository recipeRepository, BookRepository bookRepository) {
this.repository = repository;
this.authorRepository = authorRepository;
this.recipeRepository = recipeRepository;
this.bookRepository = bookRepository;
}

@Override
Expand All @@ -56,8 +59,13 @@ public Book create(BookDraft object) throws CustomException {

@Override
public Book update(Long id, JsonNode json) throws CustomException {
var author = authorRepository.findByAccountUsername(getPrincipal().getUsername()).orElseThrow(() -> new NotFoundException(Author.class));
var book = this.findById(id);

if (!book.getOwner().getId().equals(author.getId())) {
throw new ForbiddenException(Book.class);
}

if (json.has("label")) {
var label = JSONUtils.parseObject(json.get("label"), String.class);
book.setLabel(label);
Expand All @@ -73,13 +81,18 @@ public Book update(Long id, JsonNode json) throws CustomException {

@Override
public boolean deleteById(Long id) throws CustomException {
var author = authorRepository.findByAccountUsername(getPrincipal().getUsername()).orElseThrow(() -> new NotFoundException(Author.class));
var book = findById(id);

if (!book.getOwner().getId().equals(author.getId())) {
throw new ForbiddenException(Book.class);
}

var authors = authorRepository.findAllByBookIds(List.of((id)));

for (var author : authors) {
author.getBooks().removeIf(b -> b.getId().equals(id));
authorRepository.save(author);
for (var a : authors) {
a.getBooks().removeIf(b -> b.getId().equals(id));
authorRepository.save(a);
}


Expand Down Expand Up @@ -108,11 +121,20 @@ public Page<Book> findByPage(Pageable pageable) throws CustomException {
var author = authorRepository.findByAccountUsername(getPrincipal().getUsername())
.orElseThrow(() -> new NotFoundException(Author.class));

var ids = author.getBooks().stream().map(BaseEntity::getId).toList();
var ids = author.getBooks().stream().map(BaseEntity::getId).collect(Collectors.toList());
ids.addAll(author.getSubscribedBooks().stream().map(BaseEntity::getId).toList());

return repository.findByIds(ids, pageable);
}

public List<Book> findOwn() throws CustomException {
var author = authorRepository.findByAccountUsername(getPrincipal().getUsername())
.orElseThrow(() -> new NotFoundException(Author.class));

var ids = author.getBooks().stream().map(BaseEntity::getId).toList();

return repository.findByIds(ids);
}

@Override
public Page<Book> findBySearch(String searchTerm, Pageable pageable) {
Expand All @@ -127,8 +149,13 @@ public Page<Recipe> findRecipesFromParent(Long id, Pageable pageable) throws Cus
}

public Book toggleRecipe(Long bookId, Long recipeId) throws CustomException {
var author = authorRepository.findByAccountUsername(getPrincipal().getUsername()).orElseThrow(() -> new NotFoundException(Author.class));
var book = findById(bookId);

if (!book.getOwner().getId().equals(author.getId())) {
throw new ForbiddenException(Book.class);
}

var recipe = recipeRepository.findById(recipeId)
.orElseThrow(() -> new NotFoundException(Recipe.class));

Expand All @@ -155,13 +182,14 @@ public Boolean toggleSubscription(Long id) throws NotFoundException, ForbiddenEx
throw new ForbiddenException(Book.class);
}

var bookIsPresent =
author.getSubscribedBooks().removeIf(b -> b.getId().equals(book.getId()));
var authorIsPresent =
book.getSubscriber().removeIf(a -> a.getId().equals(author.getId()));

if (!bookIsPresent)
author.getSubscribedBooks().add(book);
if (!authorIsPresent) {
book.getSubscriber().add(author);
}

authorRepository.save(author);
bookRepository.save(book);

return true;
}
Expand Down

0 comments on commit 24bef13

Please sign in to comment.