From 17c4454a761f453dd9a89cc77d6fa97beae67980 Mon Sep 17 00:00:00 2001 From: Maslyna Date: Fri, 7 Apr 2023 17:32:49 +0200 Subject: [PATCH 1/6] Created FullProofDTO Added to controller and TalentProofService getTalentProofs method --- .../controller/TalentProofController.java | 15 ++++-- .../talent/model/dto/FullProofDTO.java | 23 +++++++++ .../talent/repo/TalentProofRepository.java | 3 ++ .../talent/service/TalentProofService.java | 48 +++++++++++++++++-- 4 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/provedcode/talent/model/dto/FullProofDTO.java diff --git a/src/main/java/com/provedcode/talent/controller/TalentProofController.java b/src/main/java/com/provedcode/talent/controller/TalentProofController.java index f9a2101..df4501e 100644 --- a/src/main/java/com/provedcode/talent/controller/TalentProofController.java +++ b/src/main/java/com/provedcode/talent/controller/TalentProofController.java @@ -1,14 +1,13 @@ package com.provedcode.talent.controller; import com.provedcode.talent.mapper.TalentProofMapper; +import com.provedcode.talent.model.dto.FullProofDTO; import com.provedcode.talent.model.dto.ProofDTO; import com.provedcode.talent.service.TalentProofService; import lombok.AllArgsConstructor; import org.springframework.data.domain.Page; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.*; import java.util.Optional; @@ -24,4 +23,12 @@ Page getAllProofs(@RequestParam(value = "page") Optional page @RequestParam(value = "size") Optional size) { return talentProofService.getAllProofsPage(page, size).map(talentProofMapper::toProofDTO); } + + @GetMapping("/{talent-id}/proofs") + FullProofDTO getTalentInformationWithProofs(@PathVariable("talent-id") Long talentId, + @RequestParam(value = "page") Optional page, + @RequestParam(value = "size") Optional size, + Authentication authentication) { + return talentProofService.getTalentProofs(talentId, page, size, authentication); + } } diff --git a/src/main/java/com/provedcode/talent/model/dto/FullProofDTO.java b/src/main/java/com/provedcode/talent/model/dto/FullProofDTO.java new file mode 100644 index 0000000..ddb981d --- /dev/null +++ b/src/main/java/com/provedcode/talent/model/dto/FullProofDTO.java @@ -0,0 +1,23 @@ +package com.provedcode.talent.model.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotEmpty; +import lombok.Builder; +import org.springframework.data.domain.Page; + + +@Builder +public record FullProofDTO ( + Long id, + @NotEmpty + @JsonProperty("first_name") + String firstName, + @NotEmpty + @JsonProperty("last_name") + String lastName, + String image, + @NotEmpty + String specialization, + Page proofs +) { +} diff --git a/src/main/java/com/provedcode/talent/repo/TalentProofRepository.java b/src/main/java/com/provedcode/talent/repo/TalentProofRepository.java index 8db70e6..282832c 100644 --- a/src/main/java/com/provedcode/talent/repo/TalentProofRepository.java +++ b/src/main/java/com/provedcode/talent/repo/TalentProofRepository.java @@ -6,6 +6,9 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; + public interface TalentProofRepository extends JpaRepository { + Page findByTalentId(Long talentId, Pageable pageable); Page findByStatus(ProofStatus status, Pageable pageable); } \ No newline at end of file diff --git a/src/main/java/com/provedcode/talent/service/TalentProofService.java b/src/main/java/com/provedcode/talent/service/TalentProofService.java index a4d817a..56cb04c 100644 --- a/src/main/java/com/provedcode/talent/service/TalentProofService.java +++ b/src/main/java/com/provedcode/talent/service/TalentProofService.java @@ -2,11 +2,18 @@ import com.provedcode.config.PageProperties; import com.provedcode.talent.model.ProofStatus; +import com.provedcode.talent.model.dto.FullProofDTO; +import com.provedcode.talent.model.dto.ProofDTO; +import com.provedcode.talent.model.entity.Talent; import com.provedcode.talent.model.entity.TalentProof; import com.provedcode.talent.repo.TalentProofRepository; +import com.provedcode.talent.repo.TalentRepository; import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; +import org.springframework.http.HttpStatus; +import org.springframework.security.core.Authentication; import org.springframework.stereotype.Service; import org.springframework.web.server.ResponseStatusException; @@ -16,8 +23,10 @@ @Service @AllArgsConstructor +@Slf4j public class TalentProofService { TalentProofRepository talentProofRepository; + TalentRepository talentRepository; PageProperties pageProperties; public Page getAllProofsPage(Optional page, Optional size) { @@ -28,9 +37,40 @@ public Page getAllProofsPage(Optional page, Optional page, Optional size, Authentication authentication) { + Talent talent = talentRepository.findById(talentId) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Talent with id = %s not found".formatted(talentId))); + if (page.orElse(pageProperties.defaultPageNum()) < 0) { + throw new ResponseStatusException(BAD_REQUEST, "'page' query parameter must be greater than or equal to 0"); + } + if (size.orElse(pageProperties.defaultPageSize()) <= 0) { + throw new ResponseStatusException(BAD_REQUEST, "'size' query parameter must be greater than or equal to 1"); + } + Page proofs = null; + log.info("auth = {}", authentication); + + + proofs = talentProofRepository.findByTalentId(talentId, + PageRequest.of(page.orElse(pageProperties.defaultPageNum()), size.orElse(pageProperties.defaultPageSize()))); + + return FullProofDTO.builder() + .id(talent.getId()) + .image(talent.getImage()) + .firstName(talent.getFirstName()) + .lastName(talent.getLastName()) + .specialization(talent.getSpecialization()) + .proofs(proofs.map(i -> ProofDTO.builder() + .id(i.getId()) + .created(i.getCreated().toString()) + .link(i.getLink()) + .text(i.getText()) + .status(i.getStatus()).build())) + .build(); } } From 76aca7caa0860476a42028a3ef799bd6006ebbfd Mon Sep 17 00:00:00 2001 From: Maslyna Date: Fri, 7 Apr 2023 17:46:26 +0200 Subject: [PATCH 2/6] Added security --- .../talent/repo/TalentProofRepository.java | 1 + .../talent/service/TalentProofService.java | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/provedcode/talent/repo/TalentProofRepository.java b/src/main/java/com/provedcode/talent/repo/TalentProofRepository.java index 282832c..8624c8d 100644 --- a/src/main/java/com/provedcode/talent/repo/TalentProofRepository.java +++ b/src/main/java/com/provedcode/talent/repo/TalentProofRepository.java @@ -9,6 +9,7 @@ import java.util.Optional; public interface TalentProofRepository extends JpaRepository { + Page findByTalentIdAndStatus(Long talentId, ProofStatus status, Pageable pageable); Page findByTalentId(Long talentId, Pageable pageable); Page findByStatus(ProofStatus status, Pageable pageable); } \ No newline at end of file diff --git a/src/main/java/com/provedcode/talent/service/TalentProofService.java b/src/main/java/com/provedcode/talent/service/TalentProofService.java index 56cb04c..fc71f27 100644 --- a/src/main/java/com/provedcode/talent/service/TalentProofService.java +++ b/src/main/java/com/provedcode/talent/service/TalentProofService.java @@ -8,6 +8,8 @@ import com.provedcode.talent.model.entity.TalentProof; import com.provedcode.talent.repo.TalentProofRepository; import com.provedcode.talent.repo.TalentRepository; +import com.provedcode.user.model.entity.UserInfo; +import com.provedcode.user.repo.UserInfoRepository; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -18,6 +20,7 @@ import org.springframework.web.server.ResponseStatusException; import java.util.Optional; +import java.util.stream.Collectors; import static org.springframework.http.HttpStatus.BAD_REQUEST; @@ -27,6 +30,7 @@ public class TalentProofService { TalentProofRepository talentProofRepository; TalentRepository talentRepository; + UserInfoRepository userInfoRepository; PageProperties pageProperties; public Page getAllProofsPage(Optional page, Optional size) { @@ -52,12 +56,18 @@ public FullProofDTO getTalentProofs(Long talentId, Optional page, Optio if (size.orElse(pageProperties.defaultPageSize()) <= 0) { throw new ResponseStatusException(BAD_REQUEST, "'size' query parameter must be greater than or equal to 1"); } + UserInfo userInfo = userInfoRepository.findByLogin(authentication.getName()) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Talent with id = %s not found".formatted(talentId))); Page proofs = null; - log.info("auth = {}", authentication); - - proofs = talentProofRepository.findByTalentId(talentId, - PageRequest.of(page.orElse(pageProperties.defaultPageNum()), size.orElse(pageProperties.defaultPageSize()))); + log.info("auth = {}", authentication); + if (userInfo.getTalent().getId() != talentId) { + proofs = talentProofRepository.findByTalentIdAndStatus(talentId, ProofStatus.PUBLISHED, + PageRequest.of(page.orElse(pageProperties.defaultPageNum()), size.orElse(pageProperties.defaultPageSize()))); + } else { + proofs = talentProofRepository.findByTalentId(talentId, + PageRequest.of(page.orElse(pageProperties.defaultPageNum()), size.orElse(pageProperties.defaultPageSize()))); + } return FullProofDTO.builder() .id(talent.getId()) From 49ad88b7284a30a319d85f37c19b6247327ecee9 Mon Sep 17 00:00:00 2001 From: Maslyna Date: Sat, 8 Apr 2023 00:04:50 +0200 Subject: [PATCH 3/6] Added sort --- .../controller/TalentProofController.java | 8 +++-- .../talent/service/TalentProofService.java | 33 ++++++++++++------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/provedcode/talent/controller/TalentProofController.java b/src/main/java/com/provedcode/talent/controller/TalentProofController.java index df4501e..62aae74 100644 --- a/src/main/java/com/provedcode/talent/controller/TalentProofController.java +++ b/src/main/java/com/provedcode/talent/controller/TalentProofController.java @@ -25,10 +25,12 @@ Page getAllProofs(@RequestParam(value = "page") Optional page } @GetMapping("/{talent-id}/proofs") - FullProofDTO getTalentInformationWithProofs(@PathVariable("talent-id") Long talentId, + FullProofDTO getTalentInformationWithProofs(Authentication authentication, + @PathVariable("talent-id") Long talentId, @RequestParam(value = "page") Optional page, @RequestParam(value = "size") Optional size, - Authentication authentication) { - return talentProofService.getTalentProofs(talentId, page, size, authentication); + @RequestParam(value = "direction") Optional direction, + @RequestParam(value = "sort", defaultValue = "created") String... sort) { + return talentProofService.getTalentProofs(talentId, page, size, direction, authentication, sort); } } diff --git a/src/main/java/com/provedcode/talent/service/TalentProofService.java b/src/main/java/com/provedcode/talent/service/TalentProofService.java index fc71f27..961dc8f 100644 --- a/src/main/java/com/provedcode/talent/service/TalentProofService.java +++ b/src/main/java/com/provedcode/talent/service/TalentProofService.java @@ -14,13 +14,13 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Sort; import org.springframework.http.HttpStatus; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Service; import org.springframework.web.server.ResponseStatusException; import java.util.Optional; -import java.util.stream.Collectors; import static org.springframework.http.HttpStatus.BAD_REQUEST; @@ -47,26 +47,37 @@ public Page getAllProofsPage(Optional page, Optional page, Optional size, Authentication authentication) { + public FullProofDTO getTalentProofs(Long talentId, Optional page, Optional size, + Optional direction, Authentication authentication, String... sortProperties) { Talent talent = talentRepository.findById(talentId) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Talent with id = %s not found".formatted(talentId))); + UserInfo userInfo = userInfoRepository.findByLogin(authentication.getName()) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Talent with id = %s not found".formatted(talentId))); + Page proofs = null; + PageRequest pageRequest = null; + String sortDirection = direction.orElseGet(Sort.DEFAULT_DIRECTION::name); + if (page.orElse(pageProperties.defaultPageNum()) < 0) { throw new ResponseStatusException(BAD_REQUEST, "'page' query parameter must be greater than or equal to 0"); } if (size.orElse(pageProperties.defaultPageSize()) <= 0) { throw new ResponseStatusException(BAD_REQUEST, "'size' query parameter must be greater than or equal to 1"); } - UserInfo userInfo = userInfoRepository.findByLogin(authentication.getName()) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Talent with id = %s not found".formatted(talentId))); - Page proofs = null; + if (!sortDirection.equalsIgnoreCase(Sort.Direction.ASC.name()) && !sortDirection.equalsIgnoreCase(Sort.Direction.DESC.name())) { + throw new ResponseStatusException(BAD_REQUEST, "'direction' query param must be equals ASC or DESC"); + } + + pageRequest = PageRequest.of( + page.orElse(pageProperties.defaultPageNum()), + size.orElse(pageProperties.defaultPageSize()), + Sort.Direction.valueOf(sortDirection), + sortProperties + ); - log.info("auth = {}", authentication); - if (userInfo.getTalent().getId() != talentId) { - proofs = talentProofRepository.findByTalentIdAndStatus(talentId, ProofStatus.PUBLISHED, - PageRequest.of(page.orElse(pageProperties.defaultPageNum()), size.orElse(pageProperties.defaultPageSize()))); + if (!userInfo.getLogin().equals(authentication.getName())) { + proofs = talentProofRepository.findByTalentIdAndStatus(talentId, ProofStatus.PUBLISHED, pageRequest); } else { - proofs = talentProofRepository.findByTalentId(talentId, - PageRequest.of(page.orElse(pageProperties.defaultPageNum()), size.orElse(pageProperties.defaultPageSize()))); + proofs = talentProofRepository.findByTalentId(talentId, pageRequest); } return FullProofDTO.builder() From b37c2e1f5bd6e6bb11ca21a537b7138a9a2d0365 Mon Sep 17 00:00:00 2001 From: Maslyna Date: Sat, 8 Apr 2023 12:24:44 +0200 Subject: [PATCH 4/6] Bugfix: No property 'any-property' found for type 'TalentProof --- .../talent/service/TalentProofService.java | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/provedcode/talent/service/TalentProofService.java b/src/main/java/com/provedcode/talent/service/TalentProofService.java index 961dc8f..dbbf68d 100644 --- a/src/main/java/com/provedcode/talent/service/TalentProofService.java +++ b/src/main/java/com/provedcode/talent/service/TalentProofService.java @@ -53,8 +53,8 @@ public FullProofDTO getTalentProofs(Long talentId, Optional page, Optio .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Talent with id = %s not found".formatted(talentId))); UserInfo userInfo = userInfoRepository.findByLogin(authentication.getName()) .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Talent with id = %s not found".formatted(talentId))); - Page proofs = null; - PageRequest pageRequest = null; + Page proofs; + PageRequest pageRequest; String sortDirection = direction.orElseGet(Sort.DEFAULT_DIRECTION::name); if (page.orElse(pageProperties.defaultPageNum()) < 0) { @@ -67,17 +67,20 @@ public FullProofDTO getTalentProofs(Long talentId, Optional page, Optio throw new ResponseStatusException(BAD_REQUEST, "'direction' query param must be equals ASC or DESC"); } - pageRequest = PageRequest.of( - page.orElse(pageProperties.defaultPageNum()), - size.orElse(pageProperties.defaultPageSize()), - Sort.Direction.valueOf(sortDirection), - sortProperties - ); - - if (!userInfo.getLogin().equals(authentication.getName())) { - proofs = talentProofRepository.findByTalentIdAndStatus(talentId, ProofStatus.PUBLISHED, pageRequest); - } else { - proofs = talentProofRepository.findByTalentId(talentId, pageRequest); + try { + pageRequest = PageRequest.of( + page.orElse(pageProperties.defaultPageNum()), + size.orElse(pageProperties.defaultPageSize()), + Sort.Direction.valueOf(sortDirection), + sortProperties + ); + if (!userInfo.getLogin().equals(authentication.getName())) { + proofs = talentProofRepository.findByTalentIdAndStatus(talentId, ProofStatus.PUBLISHED, pageRequest); + } else { + proofs = talentProofRepository.findByTalentId(talentId, pageRequest); + } + } catch (RuntimeException exception) { + throw new ResponseStatusException(BAD_REQUEST, exception.getMessage()); } return FullProofDTO.builder() From db01c959f65b18a5a256ecde4819946a57fbc04c Mon Sep 17 00:00:00 2001 From: Maslyna Date: Sat, 8 Apr 2023 12:46:34 +0200 Subject: [PATCH 5/6] Bugfix: not authorise users --- .../com/provedcode/talent/controller/TalentProofController.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/provedcode/talent/controller/TalentProofController.java b/src/main/java/com/provedcode/talent/controller/TalentProofController.java index 62aae74..b104448 100644 --- a/src/main/java/com/provedcode/talent/controller/TalentProofController.java +++ b/src/main/java/com/provedcode/talent/controller/TalentProofController.java @@ -6,6 +6,7 @@ import com.provedcode.talent.service.TalentProofService; import lombok.AllArgsConstructor; import org.springframework.data.domain.Page; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; @@ -25,6 +26,7 @@ Page getAllProofs(@RequestParam(value = "page") Optional page } @GetMapping("/{talent-id}/proofs") + @PreAuthorize("hasRole('TALENT')") FullProofDTO getTalentInformationWithProofs(Authentication authentication, @PathVariable("talent-id") Long talentId, @RequestParam(value = "page") Optional page, From e6a0f70b540493f2a7069ff9891298e5b55c4e23 Mon Sep 17 00:00:00 2001 From: Maslyna Date: Sat, 8 Apr 2023 12:53:48 +0200 Subject: [PATCH 6/6] Bugfix: sort problems --- .../java/com/provedcode/talent/service/TalentProofService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/provedcode/talent/service/TalentProofService.java b/src/main/java/com/provedcode/talent/service/TalentProofService.java index dbbf68d..c81f4c0 100644 --- a/src/main/java/com/provedcode/talent/service/TalentProofService.java +++ b/src/main/java/com/provedcode/talent/service/TalentProofService.java @@ -71,7 +71,7 @@ public FullProofDTO getTalentProofs(Long talentId, Optional page, Optio pageRequest = PageRequest.of( page.orElse(pageProperties.defaultPageNum()), size.orElse(pageProperties.defaultPageSize()), - Sort.Direction.valueOf(sortDirection), + Sort.Direction.valueOf(sortDirection.toUpperCase()), sortProperties ); if (!userInfo.getLogin().equals(authentication.getName())) {