diff --git "a/.github/ISSUE_TEMPLATE/\354\235\264\354\212\210-\354\240\234\353\252\251.md" "b/.github/ISSUE_TEMPLATE/\354\235\264\354\212\210-\354\240\234\353\252\251.md" deleted file mode 100644 index 840b342..0000000 --- "a/.github/ISSUE_TEMPLATE/\354\235\264\354\212\210-\354\240\234\353\252\251.md" +++ /dev/null @@ -1,16 +0,0 @@ ---- -name: 이슈 제목 -about: 이슈 설명 -title: '' -labels: '' -assignees: '' - ---- - -작업 내용 -ooo 기능 - -하위 태스크 -- [ ] : Job1 -- [ ] : Job2 -- [ ] : Job3 diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 99fdfd5..fb5359d 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -29,13 +29,6 @@ jobs: java-version: '17' distribution: 'temurin' - # (1) 기본 체크아웃 - - name: Checkout - uses: actions/checkout@v3 - with: - token: ${{ secrets.SUBMODULE_TOKEN }} - submodules: true - # gradle caching - name: Gradle Caching uses: actions/cache@v3 diff --git a/README.md b/README.md index f71a550..db883e1 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ### tools - Spring Framework 2.7.16 -- Java 17 +- Java 11 - aws ec2 instance : ubuntu @@ -13,14 +13,18 @@ #### 1. project clone ``` -$ git clone --recurse-submodules {레포주소} +$ git clone [repository HTTP or SSH] -#### 서브모듈 업데이트하는 방법 -$ git submodule update --remote --merge +# submodule 초기화 +$ git submodule init + +# submodule update +$ git submodule update +``` #### 2. gradle ``` -# build.gralde에 아래 내용 없으면 추가 +# build.gralde에 아래 내용 추가 # ./security에서 src/main/resouces로 폴더 copy processResources.dependsOn('copySecret') diff --git a/src/main/java/com/tgd/trip/attraction/controller/AttractionController.java b/src/main/java/com/tgd/trip/attraction/controller/AttractionController.java index 3306964..3b6a6c0 100644 --- a/src/main/java/com/tgd/trip/attraction/controller/AttractionController.java +++ b/src/main/java/com/tgd/trip/attraction/controller/AttractionController.java @@ -4,10 +4,8 @@ import com.tgd.trip.attraction.dto.AttractionDto; import com.tgd.trip.attraction.mapper.AttractionMapper; import com.tgd.trip.attraction.service.AttractionService; -import com.tgd.trip.global.dto.PageResponse; import com.tgd.trip.global.util.Coordinate; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.web.PageableDefault; import org.springframework.http.HttpStatus; @@ -27,22 +25,20 @@ public class AttractionController { @GetMapping("/all") public ResponseEntity getAllAttractions(Coordinate coordinate, @RequestParam(name = "height", required = false) Double height, - @RequestParam(name = "width", required = false) Double width, - @PageableDefault(page = 1) Pageable pageable) { - Page attractions = attractionService.getAttractionsFromCenter(coordinate, height, width, pageable); - Page responsePage = attractionMapper.entityToPageResponse(attractions); + @RequestParam(name = "width", required = false) Double width) { + System.out.println(coordinate.longitude() + " " + coordinate.latitude()); + List attractions = attractionService.getAttractionsFromCenter(coordinate, height, width); List responses = attractionMapper.entityToResponse(attractions); - return ResponseEntity.ok(new PageResponse<>(responses, responsePage)); + return ResponseEntity.ok(responses); } - @GetMapping - public ResponseEntity> getAttractions(@RequestParam String keyword, - @RequestParam(name = "sidoCode", required = false) Long sidoCode, - @PageableDefault(page = 1) Pageable pageable) { - Page attractions = attractionService.getAttractions(keyword, sidoCode, pageable); - Page responsePage = attractionMapper.entityToPageResponse(attractions); + @GetMapping() + public ResponseEntity getAttractions(@RequestParam(name = "sido_code", required = false) Long sidoCode, + @RequestParam(name = "gugun_code", required = false) Long gugunCode, + @PageableDefault Pageable pageable) { + List attractions = attractionService.getAttractions(gugunCode, sidoCode, pageable); List responses = attractionMapper.entityToResponse(attractions); - return ResponseEntity.ok(new PageResponse<>(responses, responsePage)); + return ResponseEntity.ok(responses); } @PostMapping(value = "{attraction-id}/wish") @@ -58,18 +54,4 @@ public ResponseEntity deleteAttractionBookmark(@PathVariable("attraction-id") attractionService.deleteBookmark(attractionId, userId); return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); } - - @PostMapping(value = "{attraction-id}/like") - public ResponseEntity createAttractionLike(@PathVariable("attraction-id") Long attractionId, - @RequestParam("userId") Long userId) { - attractionService.createLike(attractionId, userId); - return ResponseEntity.status(HttpStatus.CREATED).build(); - } - - @DeleteMapping(value = "{attraction-id}/like") - public ResponseEntity deleteAttractionLike(@PathVariable("attraction-id") Long attractionId, - @RequestParam("userId") Long userId) { - attractionService.deleteLike(attractionId, userId); - return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); - } } diff --git a/src/main/java/com/tgd/trip/attraction/domain/Attraction.java b/src/main/java/com/tgd/trip/attraction/domain/Attraction.java index d6adfc8..63363e8 100644 --- a/src/main/java/com/tgd/trip/attraction/domain/Attraction.java +++ b/src/main/java/com/tgd/trip/attraction/domain/Attraction.java @@ -5,8 +5,6 @@ import javax.persistence.*; import javax.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.List; @Entity @Getter @@ -43,13 +41,4 @@ public class Attraction extends BaseEntity { @JoinColumn(name = "sido_code") }) private Gugun gugun; - @OneToMany(mappedBy = "attraction", cascade = CascadeType.PERSIST, fetch = FetchType.LAZY, orphanRemoval = true) - private List attractionLikes = new ArrayList<>(); - - public void addLike(AttractionLike attractionLike) { - if (!this.attractionLikes.contains(attractionLike)) { - attractionLikes.add(attractionLike); - } - attractionLike.setAttraction(this); - } } diff --git a/src/main/java/com/tgd/trip/attraction/domain/AttractionLike.java b/src/main/java/com/tgd/trip/attraction/domain/AttractionLike.java deleted file mode 100644 index cd2d900..0000000 --- a/src/main/java/com/tgd/trip/attraction/domain/AttractionLike.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.tgd.trip.attraction.domain; - -import com.tgd.trip.user.domain.User; -import lombok.*; - -import javax.persistence.*; - -@Entity -@Getter -@Setter -@NoArgsConstructor -public class AttractionLike { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long attractionLikeId; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "user_id") - private User user; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "attraction_id") - private Attraction attraction; - - public AttractionLike(User user) { - this.user = user; - } -} diff --git a/src/main/java/com/tgd/trip/attraction/mapper/AttractionMapper.java b/src/main/java/com/tgd/trip/attraction/mapper/AttractionMapper.java index adb2651..84284e9 100644 --- a/src/main/java/com/tgd/trip/attraction/mapper/AttractionMapper.java +++ b/src/main/java/com/tgd/trip/attraction/mapper/AttractionMapper.java @@ -2,23 +2,15 @@ import com.tgd.trip.attraction.domain.Attraction; import com.tgd.trip.attraction.dto.AttractionDto; -import org.springframework.data.domain.Page; import org.springframework.stereotype.Component; import java.util.List; +import java.util.stream.Collectors; @Component public class AttractionMapper { - public AttractionDto.Response entityToResponse(Attraction attraction) { - return new AttractionDto.Response(attraction); - } - - public List entityToResponse(Page attractions) { - return attractions.map(this::entityToResponse).stream().toList(); - } - - public Page entityToPageResponse(Page attractions) { - return attractions.map(this::entityToResponse); + public List entityToResponse(List attractions) { + return attractions.stream().map(AttractionDto.Response::new).collect(Collectors.toList()); } } diff --git a/src/main/java/com/tgd/trip/attraction/repository/AttractionLikeRepository.java b/src/main/java/com/tgd/trip/attraction/repository/AttractionLikeRepository.java deleted file mode 100644 index cb41b03..0000000 --- a/src/main/java/com/tgd/trip/attraction/repository/AttractionLikeRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.tgd.trip.attraction.repository; - -import com.tgd.trip.attraction.domain.Attraction; -import com.tgd.trip.attraction.domain.AttractionLike; -import com.tgd.trip.user.domain.User; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface AttractionLikeRepository extends JpaRepository { - - boolean existsByUserAndAttraction(User user, Attraction attraction); - - void deleteByUserAndAttraction(User findUser, Attraction findAttraction); -} diff --git a/src/main/java/com/tgd/trip/attraction/repository/AttractionRepository.java b/src/main/java/com/tgd/trip/attraction/repository/AttractionRepository.java index 1706d5b..c7ac2b9 100644 --- a/src/main/java/com/tgd/trip/attraction/repository/AttractionRepository.java +++ b/src/main/java/com/tgd/trip/attraction/repository/AttractionRepository.java @@ -1,20 +1,16 @@ package com.tgd.trip.attraction.repository; import com.tgd.trip.attraction.domain.Attraction; -import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; public interface AttractionRepository extends JpaRepository { - Page findAllByLatitudeBetweenAndLongitudeBetween(Double startLat, Double endLat, Double startLong, Double endLong, Pageable pageable); + List findAllByLatitudeBetweenAndLongitudeBetween(Double startLat, Double endLat, Double startLong, Double endLong); List findAllByGugun_IdGugunCodeAndGugun_IdSidoCode(Long gugunCode, Long sidoCode, Pageable pageable); - Page findAllByTitleContainingAndSido_SidoCode(String keyword, Long sidoCode, Pageable pageable); - List findAllBySido_SidoCode(Long sidoCode); - - Page findAllByTitleContaining(String title, Pageable pageable); + List findAllByTitleContaining(String title); } diff --git a/src/main/java/com/tgd/trip/attraction/service/AttractionService.java b/src/main/java/com/tgd/trip/attraction/service/AttractionService.java index 205fee5..55c1d96 100644 --- a/src/main/java/com/tgd/trip/attraction/service/AttractionService.java +++ b/src/main/java/com/tgd/trip/attraction/service/AttractionService.java @@ -1,7 +1,9 @@ package com.tgd.trip.attraction.service; -import com.tgd.trip.attraction.domain.*; -import com.tgd.trip.attraction.repository.*; +import com.tgd.trip.attraction.domain.Attraction; +import com.tgd.trip.attraction.domain.AttractionBookmark; +import com.tgd.trip.attraction.repository.AttractionBookmarkRepository; +import com.tgd.trip.attraction.repository.AttractionRepository; import com.tgd.trip.global.exception.CustomException; import com.tgd.trip.global.exception.ErrorCode; import com.tgd.trip.global.util.Coordinate; @@ -10,10 +12,11 @@ import com.tgd.trip.user.service.UserService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.*; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import javax.transaction.Transactional; +import java.util.List; @Service @RequiredArgsConstructor @@ -22,23 +25,20 @@ public class AttractionService { private final AttractionRepository attractionRepository; private final AttractionBookmarkRepository attractionBookmarkRepository; - private final AttractionLikeRepository attractionLikeRepository; private final UserService userService; - public Page getAttractionsFromCenter(Coordinate center, Double height, Double width, Pageable pageable) { + public List getAttractionsFromCenter(Coordinate center, Double height, Double width) { Pair squareCoordinate = center.getSquareCoordinate(height, width); Coordinate topLeft = squareCoordinate.first(); Coordinate bottomRight = squareCoordinate.second(); log.debug("찾고자 하는 상단 좌표 : " + topLeft + ", 하단 좌표" + bottomRight); - Page attractions = attractionRepository.findAllByLatitudeBetweenAndLongitudeBetween(topLeft.latitude(), bottomRight.latitude(), topLeft.longitude(), bottomRight.longitude(), pageable); + List attractions = attractionRepository.findAllByLatitudeBetweenAndLongitudeBetween(topLeft.latitude(), bottomRight.latitude(), topLeft.longitude(), bottomRight.longitude()); return attractions; } - public Page getAttractions(String keywowrd, Long sidoCode, Pageable pageable) { - if (sidoCode == null) { - return attractionRepository.findAllByTitleContaining(keywowrd, pageable); - } - return attractionRepository.findAllByTitleContainingAndSido_SidoCode(keywowrd, sidoCode, PageRequest.of(pageable.getPageNumber() - 1, pageable.getPageSize())); + public List getAttractions(Long gugunCode, Long sidoCode, Pageable pageable) { + log.debug("구군 코드 : " + gugunCode + ", 시도 코드 :" + sidoCode); + return attractionRepository.findAllByGugun_IdGugunCodeAndGugun_IdSidoCode(gugunCode, sidoCode, pageable.previousOrFirst()); } public Attraction getAttraction(Long attractionId) { @@ -61,26 +61,4 @@ public void deleteBookmark(Long attractionId, Long userId) { Attraction findAttraction = getAttraction(attractionId); attractionBookmarkRepository.deleteByUserAndAttraction(findUser, findAttraction); } - - @Transactional - public void createLike(Long attractionId, Long userId) { - User findUser = userService.getVerifyUser(userId); - Attraction findAttraction = getAttraction(attractionId); - - // 유저가 해당 관광지를 좋아요 했다면 더 이상 좋아요 불가능 - if (attractionLikeRepository.existsByUserAndAttraction(findUser, findAttraction)) { - throw new CustomException(ErrorCode.TOO_MANY_LIKES); - } - - AttractionLike attractionLike = new AttractionLike(findUser); - findAttraction.addLike(attractionLike); - attractionLikeRepository.save(attractionLike); - } - - @Transactional - public void deleteLike(Long attractionId, Long userId) { - User findUser = userService.getVerifyUser(userId); - Attraction findAttraction = getAttraction(attractionId); - attractionLikeRepository.deleteByUserAndAttraction(findUser, findAttraction); - } } diff --git a/src/main/java/com/tgd/trip/global/dto/PageInfo.java b/src/main/java/com/tgd/trip/global/dto/PageInfo.java deleted file mode 100644 index 3951c3c..0000000 --- a/src/main/java/com/tgd/trip/global/dto/PageInfo.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.tgd.trip.global.dto; - -public record PageInfo(int page, int size, long totalSize, int totalPage) { -} diff --git a/src/main/java/com/tgd/trip/global/dto/PageResponse.java b/src/main/java/com/tgd/trip/global/dto/PageResponse.java deleted file mode 100644 index 4de72e7..0000000 --- a/src/main/java/com/tgd/trip/global/dto/PageResponse.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.tgd.trip.global.dto; - -import org.springframework.data.domain.Page; - -import java.util.List; - -public record PageResponse(List data, PageInfo pageInfo) { - - public PageResponse(List data, Page page) { - this(data, new PageInfo(page.getNumber() + 1, page.getSize(), page.getTotalElements(), page.getTotalPages())); - } -} diff --git a/src/main/java/com/tgd/trip/global/exception/ErrorCode.java b/src/main/java/com/tgd/trip/global/exception/ErrorCode.java index 2473a98..682f502 100644 --- a/src/main/java/com/tgd/trip/global/exception/ErrorCode.java +++ b/src/main/java/com/tgd/trip/global/exception/ErrorCode.java @@ -9,11 +9,8 @@ public enum ErrorCode { SCHEDULE_NOT_FOUND(HttpStatus.NOT_FOUND, "스케줄이 존재하지 않습니다."), DAY_NOT_FOUND(HttpStatus.NOT_FOUND, "일자가 존재하지 않습니다."), - ATTRACTION_NOT_FOUND(HttpStatus.NOT_FOUND, "관광지가 존재하지 않습니다."), - COMMENT_NOT_FOUND(HttpStatus.NOT_FOUND, "댓글이 존재하지 않습니다."), - DIFFERENT_USER(HttpStatus.FORBIDDEN, "같은 사용자가 아닙니다."), - TOO_MANY_LIKES(HttpStatus.TOO_MANY_REQUESTS, "이미 좋아요를 했습니다."), - USER_NOT_FOUND(HttpStatus.NOT_FOUND, "사용자가 존재하지 않습니다."); + ATTRACTION_NOT_FOUND(HttpStatus.NOT_FOUND, "관광지가 존재하지 않습니다."); + ; private final HttpStatus httpStatus; private final String message; diff --git a/src/main/java/com/tgd/trip/global/oauth2/controller/OAuth2Controller.java b/src/main/java/com/tgd/trip/global/oauth2/controller/OAuth2Controller.java new file mode 100644 index 0000000..94ca7fc --- /dev/null +++ b/src/main/java/com/tgd/trip/global/oauth2/controller/OAuth2Controller.java @@ -0,0 +1,48 @@ +//package com.tgd.trip.global.oauth2.controller; +// +//import com.tgd.trip.global.oauth2.dto.SocialLoginRequest; +//import com.tgd.trip.global.oauth2.util.LoginResponse; +//import lombok.RequiredArgsConstructor; +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.http.ResponseEntity; +//import org.springframework.security.core.userdetails.UserDetails; +//import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; +//import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; +//import org.springframework.web.bind.annotation.*; +// +//import javax.validation.Valid; +//import java.net.URI; +//import java.util.Map; +// +//@RequiredArgsConstructor +//@RestController +//@RequestMapping("/api/oauth2") +//@Slf4j +//public class OAuth2Controller { +// private final OAuth2UserService oAuth2UserService; +// +// @PostMapping("/social-login") +// public ResponseEntity getUserInfo(@RequestBody Map request) { +// String accessToken = request.get("accessToken"); +// +// // OAuth2UserRequest를 생성하기 위해 OAuth2UserRequestFactory를 주입받아 사용 +// OAuth2UserRequestFactory userRequestFactory = ...; // OAuth2UserRequestFactory 주입 +// +// // OAuth2UserRequest를 생성하여 accessToken을 전달 +// OAuth2UserRequest userRequest = userRequestFactory.createOAuth2UserRequest("google", accessToken); +// +// // OAuth2UserService의 loadUser 메서드를 호출하여 OAuth2User를 가져옴 +// OAuth2User oAuth2User = oAuth2UserService.loadUser(userRequest); +// +// // OAuth2User를 활용하여 로그인 로직 처리 +// // ... +// +// return ResponseEntity.ok("로그인 성공"); +// } +// @GetMapping("/{id}") +// public ResponseEntity getUser(@PathVariable("id") Long id) { +// return ResponseEntity.ok( +// userService.getUser(id) +// ); +// } +//} diff --git a/src/main/java/com/tgd/trip/user/service/CustomOAuth2User.java b/src/main/java/com/tgd/trip/global/oauth2/dto/CustomOAuth2User.java similarity index 74% rename from src/main/java/com/tgd/trip/user/service/CustomOAuth2User.java rename to src/main/java/com/tgd/trip/global/oauth2/dto/CustomOAuth2User.java index 75fe244..8f882af 100644 --- a/src/main/java/com/tgd/trip/user/service/CustomOAuth2User.java +++ b/src/main/java/com/tgd/trip/global/oauth2/dto/CustomOAuth2User.java @@ -1,13 +1,11 @@ -package com.tgd.trip.user.service; +package com.tgd.trip.global.oauth2.dto; -import com.tgd.trip.user.domain.Role; +import com.tgd.trip.global.oauth2.util.OAuthAttributes; import com.tgd.trip.user.domain.User; import com.tgd.trip.util.AuthorityUtils; import lombok.Getter; -import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.oauth2.core.user.DefaultOAuth2User; -import org.springframework.transaction.annotation.Transactional; import java.util.Collection; import java.util.List; @@ -16,17 +14,17 @@ @Getter public class CustomOAuth2User extends DefaultOAuth2User { - private final String email; private final List roles; + private final Long userId; public CustomOAuth2User(Collection authorities, Map attributes, String nameAttributeKey, - String email, + Long userId, List roles) { super(authorities, attributes, nameAttributeKey); - this.email = email; this.roles = roles; + this.userId = userId; } public static CustomOAuth2User of(User user, Map attributes, OAuthAttributes oAuthAttributes) { @@ -34,7 +32,8 @@ public static CustomOAuth2User of(User user, Map attributes, OAu AuthorityUtils.getAuthorities(user.getRoles()), attributes, oAuthAttributes.getProviderId(), - user.getEmail(), - user.getRoles()); + user.getUserId(), + user.getRoles() + ); } } \ No newline at end of file diff --git a/src/main/java/com/tgd/trip/user/domain/LoginDto.java b/src/main/java/com/tgd/trip/global/oauth2/dto/LoginDto.java similarity index 74% rename from src/main/java/com/tgd/trip/user/domain/LoginDto.java rename to src/main/java/com/tgd/trip/global/oauth2/dto/LoginDto.java index 647df0c..e0c039c 100644 --- a/src/main/java/com/tgd/trip/user/domain/LoginDto.java +++ b/src/main/java/com/tgd/trip/global/oauth2/dto/LoginDto.java @@ -1,4 +1,4 @@ -package com.tgd.trip.user.domain; +package com.tgd.trip.global.oauth2.dto; import lombok.Getter; diff --git a/src/main/java/com/tgd/trip/user/domain/ProviderType.java b/src/main/java/com/tgd/trip/global/oauth2/dto/ProviderType.java similarity index 85% rename from src/main/java/com/tgd/trip/user/domain/ProviderType.java rename to src/main/java/com/tgd/trip/global/oauth2/dto/ProviderType.java index ff9012e..97d7f2a 100644 --- a/src/main/java/com/tgd/trip/user/domain/ProviderType.java +++ b/src/main/java/com/tgd/trip/global/oauth2/dto/ProviderType.java @@ -1,4 +1,4 @@ -package com.tgd.trip.user.domain; +package com.tgd.trip.global.oauth2.dto; import lombok.Getter; diff --git a/src/main/java/com/tgd/trip/global/oauth2/dto/SocialLoginRequest.java b/src/main/java/com/tgd/trip/global/oauth2/dto/SocialLoginRequest.java new file mode 100644 index 0000000..c37a49f --- /dev/null +++ b/src/main/java/com/tgd/trip/global/oauth2/dto/SocialLoginRequest.java @@ -0,0 +1,14 @@ +package com.tgd.trip.global.oauth2.dto; + +import com.tgd.trip.global.oauth2.dto.ProviderType; +import lombok.Getter; + +import javax.validation.constraints.NotNull; + +@Getter +public class SocialLoginRequest { + @NotNull + private ProviderType userType; + @NotNull + private String code; +} \ No newline at end of file diff --git a/src/main/java/com/tgd/trip/user/domain/GoogleUserInfo.java b/src/main/java/com/tgd/trip/global/oauth2/dto/UserInfo/GoogleUserInfo.java similarity index 93% rename from src/main/java/com/tgd/trip/user/domain/GoogleUserInfo.java rename to src/main/java/com/tgd/trip/global/oauth2/dto/UserInfo/GoogleUserInfo.java index a8441ed..b368f9f 100644 --- a/src/main/java/com/tgd/trip/user/domain/GoogleUserInfo.java +++ b/src/main/java/com/tgd/trip/global/oauth2/dto/UserInfo/GoogleUserInfo.java @@ -1,4 +1,4 @@ -package com.tgd.trip.user.domain; +package com.tgd.trip.global.oauth2.dto.UserInfo; import lombok.Data; diff --git a/src/main/java/com/tgd/trip/user/domain/KakaoUserInfo.java b/src/main/java/com/tgd/trip/global/oauth2/dto/UserInfo/KakaoUserInfo.java similarity index 93% rename from src/main/java/com/tgd/trip/user/domain/KakaoUserInfo.java rename to src/main/java/com/tgd/trip/global/oauth2/dto/UserInfo/KakaoUserInfo.java index 41fa8c3..5f406c9 100644 --- a/src/main/java/com/tgd/trip/user/domain/KakaoUserInfo.java +++ b/src/main/java/com/tgd/trip/global/oauth2/dto/UserInfo/KakaoUserInfo.java @@ -1,4 +1,4 @@ -package com.tgd.trip.user.domain; +package com.tgd.trip.global.oauth2.dto.UserInfo; import lombok.Data; diff --git a/src/main/java/com/tgd/trip/user/domain/NaverUserInfo.java b/src/main/java/com/tgd/trip/global/oauth2/dto/UserInfo/NaverUserInfo.java similarity index 93% rename from src/main/java/com/tgd/trip/user/domain/NaverUserInfo.java rename to src/main/java/com/tgd/trip/global/oauth2/dto/UserInfo/NaverUserInfo.java index 5ced173..c182f1e 100644 --- a/src/main/java/com/tgd/trip/user/domain/NaverUserInfo.java +++ b/src/main/java/com/tgd/trip/global/oauth2/dto/UserInfo/NaverUserInfo.java @@ -1,4 +1,4 @@ -package com.tgd.trip.user.domain; +package com.tgd.trip.global.oauth2.dto.UserInfo; import lombok.Data; diff --git a/src/main/java/com/tgd/trip/user/domain/OAuth2UserInfo.java b/src/main/java/com/tgd/trip/global/oauth2/dto/UserInfo/OAuth2UserInfo.java similarity index 73% rename from src/main/java/com/tgd/trip/user/domain/OAuth2UserInfo.java rename to src/main/java/com/tgd/trip/global/oauth2/dto/UserInfo/OAuth2UserInfo.java index a28080b..dca4e13 100644 --- a/src/main/java/com/tgd/trip/user/domain/OAuth2UserInfo.java +++ b/src/main/java/com/tgd/trip/global/oauth2/dto/UserInfo/OAuth2UserInfo.java @@ -1,4 +1,4 @@ -package com.tgd.trip.user.domain; +package com.tgd.trip.global.oauth2.dto.UserInfo; public interface OAuth2UserInfo { String getProviderId(); diff --git a/src/main/java/com/tgd/trip/global/oauth2/service/CustomOAuth2UserRequestFactory.java b/src/main/java/com/tgd/trip/global/oauth2/service/CustomOAuth2UserRequestFactory.java new file mode 100644 index 0000000..70de9da --- /dev/null +++ b/src/main/java/com/tgd/trip/global/oauth2/service/CustomOAuth2UserRequestFactory.java @@ -0,0 +1,67 @@ +//package com.tgd.trip.global.oauth2.service; +// +//import org.springframework.security.oauth2.client.registration.ClientRegistration; +//import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +//import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; +//import org.springframework.security.oauth2.core.ClientAuthenticationMethod; +//import org.springframework.security.oauth2.core.OAuth2AccessToken; +//import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; +//import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; +//import org.springframework.stereotype.Service; +// +//@Service +//public class CustomOAuth2UserRequestFactory implements OAuth2UserRequestFactory { +// +// private final ClientRegistrationRepository clientRegistrationRepository; +// private final OAuth2UserRequestRepository userRequestRepository; +// +// public CustomOAuth2UserRequestFactory(ClientRegistrationRepository clientRegistrationRepository, +// OAuth2UserRequestRepository userRequestRepository) { +// this.clientRegistrationRepository = clientRegistrationRepository; +// this.userRequestRepository = userRequestRepository; +// } +// +// @Override +// public OAuth2UserRequest createOAuth2UserRequest(ClientRegistration clientRegistration, OAuth2AccessToken accessToken) { +// AuthenticationMethod authenticationMethod = AuthenticationMethod.CLIENT_SECRET_BASIC; +// if (clientRegistration.getClientAuthenticationMethod() == ClientAuthenticationMethod.NONE) { +// authenticationMethod = AuthenticationMethod.NONE; +// } +// +// OAuth2UserRequest.Builder builder = OAuth2UserRequest.withClientRegistration(clientRegistration) +// .accessToken(accessToken) +// .authenticationMethod(authenticationMethod); +// +// OAuth2UserRequest userRequest = builder.build(); +// this.userRequestRepository.saveUserRequest(userRequest, null); +// +// return userRequest; +// } +// +// @Override +// public OAuth2UserRequest createOAuth2UserRequest(String registrationId, OAuth2AccessToken accessToken) { +// ClientRegistration clientRegistration = this.clientRegistrationRepository.findByRegistrationId(registrationId); +// if (clientRegistration == null) { +// throw new IllegalArgumentException("Invalid Client Registration with Id: " + registrationId); +// } +// +// return createOAuth2UserRequest(clientRegistration, accessToken); +// } +// +// @Override +// public OAuth2UserRequest createOAuth2UserRequest(OAuth2AuthorizationRequest authorizationRequest) { +// String registrationId = authorizationRequest.getAttribute(OAuth2ParameterNames.REGISTRATION_ID); +// if (registrationId == null) { +// throw new IllegalArgumentException("Missing Client Registration Id"); +// } +// +// ClientRegistration clientRegistration = this.clientRegistrationRepository.findByRegistrationId(registrationId); +// if (clientRegistration == null) { +// throw new IllegalArgumentException("Invalid Client Registration with Id: " + registrationId); +// } +// +// OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, +// "your_access_token_here", null, null); +// return createOAuth2UserRequest(clientRegistration, accessToken); +// } +//} diff --git a/src/main/java/com/tgd/trip/user/service/OAuth2UserService.java b/src/main/java/com/tgd/trip/global/oauth2/service/OAuth2UserService.java similarity index 84% rename from src/main/java/com/tgd/trip/user/service/OAuth2UserService.java rename to src/main/java/com/tgd/trip/global/oauth2/service/OAuth2UserService.java index c85e85d..316ede6 100644 --- a/src/main/java/com/tgd/trip/user/service/OAuth2UserService.java +++ b/src/main/java/com/tgd/trip/global/oauth2/service/OAuth2UserService.java @@ -1,5 +1,11 @@ -package com.tgd.trip.user.service; +package com.tgd.trip.global.oauth2.service; +import com.tgd.trip.global.oauth2.dto.CustomOAuth2User; +import com.tgd.trip.global.oauth2.dto.UserInfo.GoogleUserInfo; +import com.tgd.trip.global.oauth2.dto.UserInfo.KakaoUserInfo; +import com.tgd.trip.global.oauth2.dto.UserInfo.NaverUserInfo; +import com.tgd.trip.global.oauth2.dto.UserInfo.OAuth2UserInfo; +import com.tgd.trip.global.oauth2.util.OAuthAttributes; import com.tgd.trip.jwt.JwtTokenProvider; import com.tgd.trip.user.domain.*; import com.tgd.trip.user.repository.UserRepository; @@ -12,6 +18,10 @@ import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.CrossOrigin; + +import java.util.Map; + import java.util.*; @@ -20,11 +30,11 @@ @RequiredArgsConstructor public class OAuth2UserService extends DefaultOAuth2UserService { private final UserRepository userRepository; - private final JwtTokenProvider jwtTokenProvider; //로그인 필요한 url 요청시 여기로 넘어옴 @Override @Transactional + @CrossOrigin(origins = "http://localhost:5173") public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { log.info("userRequest: {}", userRequest); @@ -55,7 +65,7 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic String provider = oAuth2UserInfo.getProvider(); //google , naver, facebook etc String providerId = clientRegistration.getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName(); - String name = provider + "_" + oAuth2UserInfo.getName() + "_" + providerId; + String name = oAuth2UserInfo.getName(); String email = oAuth2UserInfo.getEmail(); log.info("email: {}", email); @@ -63,7 +73,6 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic Optional optionalUser = userRepository.findByEmail(email); User user = null; - System.out.println(user); if (optionalUser.isPresent()) { log.info("로그인을 이미 했음, 자동회원가입이 되어있다."); user = optionalUser.get(); @@ -72,7 +81,7 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic .password("githere") .name(name) .email(email) - .roles(List.of(Role.USER.name())) + .roles(List.of(Role.GEST.name())) .providerId(providerId) .provider(provider) .build(); diff --git a/src/main/java/com/tgd/trip/global/oauth2/util/LoginResponse.java b/src/main/java/com/tgd/trip/global/oauth2/util/LoginResponse.java new file mode 100644 index 0000000..f04b7eb --- /dev/null +++ b/src/main/java/com/tgd/trip/global/oauth2/util/LoginResponse.java @@ -0,0 +1,14 @@ +package com.tgd.trip.global.oauth2.util; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Getter +public class LoginResponse { + private Long id; +} \ No newline at end of file diff --git a/src/main/java/com/tgd/trip/user/service/OAuthAttributes.java b/src/main/java/com/tgd/trip/global/oauth2/util/OAuthAttributes.java similarity index 75% rename from src/main/java/com/tgd/trip/user/service/OAuthAttributes.java rename to src/main/java/com/tgd/trip/global/oauth2/util/OAuthAttributes.java index 9df3186..ee93f92 100644 --- a/src/main/java/com/tgd/trip/user/service/OAuthAttributes.java +++ b/src/main/java/com/tgd/trip/global/oauth2/util/OAuthAttributes.java @@ -1,16 +1,16 @@ -package com.tgd.trip.user.service; +package com.tgd.trip.global.oauth2.util; import com.tgd.trip.exception.CustomException; import com.tgd.trip.exception.ExceptionCode; -import com.tgd.trip.user.domain.*; +import com.tgd.trip.global.oauth2.dto.ProviderType; +import com.tgd.trip.global.oauth2.dto.UserInfo.GoogleUserInfo; +import com.tgd.trip.global.oauth2.dto.UserInfo.KakaoUserInfo; +import com.tgd.trip.global.oauth2.dto.UserInfo.OAuth2UserInfo; import lombok.Builder; import lombok.Getter; -import org.springframework.security.crypto.password.PasswordEncoder; -import java.util.Collections; import java.util.Map; -import java.util.UUID; @Getter public class OAuthAttributes { @@ -31,6 +31,8 @@ public static OAuthAttributes of(String provider, return ofGoogle(providerId, attributes); }else if(provider.equals(ProviderType.KAKAO.getProvider())){ return ofKakao(providerId, attributes); + }else if(provider.equals(ProviderType.NAVER.getProvider())){ + return ofNaver(providerId, attributes); } throw new CustomException(ExceptionCode.PROVIDER_NOT_FOUND); } @@ -51,6 +53,14 @@ private static OAuthAttributes ofKakao(String providerId, .build(); } + private static OAuthAttributes ofNaver(String providerId, + Map attributes) { + return OAuthAttributes.builder() + .providerId(providerId) + .oAuth2UserInfo(new KakaoUserInfo(attributes)) + .build(); + } + // public User toEntity(OAuth2UserInfo oAuth2UserInfo, // String username, // String provider, diff --git a/src/main/java/com/tgd/trip/user/domain/UserPrincipal.java b/src/main/java/com/tgd/trip/global/oauth2/util/UserPrincipal.java similarity index 95% rename from src/main/java/com/tgd/trip/user/domain/UserPrincipal.java rename to src/main/java/com/tgd/trip/global/oauth2/util/UserPrincipal.java index 4bcc111..20f8814 100644 --- a/src/main/java/com/tgd/trip/user/domain/UserPrincipal.java +++ b/src/main/java/com/tgd/trip/global/oauth2/util/UserPrincipal.java @@ -1,5 +1,6 @@ -package com.tgd.trip.user.domain; +package com.tgd.trip.global.oauth2.util; +import com.tgd.trip.user.domain.User; import com.tgd.trip.util.AuthorityUtils; import lombok.Getter; import org.springframework.security.core.GrantedAuthority; diff --git a/src/main/java/com/tgd/trip/global/util/Coordinate.java b/src/main/java/com/tgd/trip/global/util/Coordinate.java index f6397ea..5d41f1e 100644 --- a/src/main/java/com/tgd/trip/global/util/Coordinate.java +++ b/src/main/java/com/tgd/trip/global/util/Coordinate.java @@ -33,7 +33,10 @@ public Pair getSquareCoordinate(double height, double width) { double maxLongitude = Math.max(lng1, lng2); double minLongitude = Math.min(lng1, lng2); - return new Pair<>(new Coordinate(minLatitude, minLongitude), new Coordinate(maxLatitude, maxLongitude)); + return new Pair<>( + new Coordinate(minLatitude, minLongitude), + new Coordinate(maxLatitude, maxLongitude) + ); } private record Delta(double longitudeDelta, double latitudeDelta) { diff --git a/src/main/java/com/tgd/trip/jwt/JwtAuthenticationFilter.java b/src/main/java/com/tgd/trip/jwt/JwtAuthenticationFilter.java index b540441..0cc04c9 100644 --- a/src/main/java/com/tgd/trip/jwt/JwtAuthenticationFilter.java +++ b/src/main/java/com/tgd/trip/jwt/JwtAuthenticationFilter.java @@ -1,21 +1,12 @@ package com.tgd.trip.jwt; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.tgd.trip.user.domain.LoginDto; import lombok.RequiredArgsConstructor; -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.context.SecurityContextHolder; -import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; -import org.springframework.web.filter.GenericFilterBean; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -29,7 +20,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 헤더에서 JWT를 받아옴 String token = jwtTokenProvider.resolveToken((HttpServletRequest) request); - System.out.println(token); + System.out.println("요청 헤더에 있는 토큰" + token); // 유효한 토큰인지 확인 if (token != null && jwtTokenProvider.validateToken(token)) { // 토큰이 유효하면 토큰으로부터 유저 정보를 받아옴 diff --git a/src/main/java/com/tgd/trip/jwt/JwtTokenProvider.java b/src/main/java/com/tgd/trip/jwt/JwtTokenProvider.java index 11a0538..6e9ac63 100644 --- a/src/main/java/com/tgd/trip/jwt/JwtTokenProvider.java +++ b/src/main/java/com/tgd/trip/jwt/JwtTokenProvider.java @@ -34,8 +34,8 @@ public class JwtTokenProvider { // } // JWT 토큰 생성 - public String createToken(String userPK, List roles) { - Claims claims = Jwts.claims().setSubject(userPK); // JWT payload에 저장되는 정보 단위 + public String createToken(Long userPK, List roles) { + Claims claims = Jwts.claims().setSubject(userPK.toString()); // JWT payload에 저장되는 정보 단위 claims.put("roles", roles); // 정보 저장 (key-value) Date now = new Date(); return Jwts.builder() @@ -49,6 +49,7 @@ public String createToken(String userPK, List roles) { // JWT 토큰에서 인증 정보 조회 public Authentication getAuthentication(String token) { + System.out.println("여기느옴?"); // UserDetails userDetails = userDetailsService.loadUserByUsername(this.getUserPK(token)); SecurityUser userDetails = (SecurityUser) userDetailsService.loadUserByUsername(this.getUserPK(token)); // System.out.println(userDetails.getAuthorities()); @@ -62,6 +63,7 @@ public String getUserPK(String token) { // Request의 Header에서 token 값을 가져옵니다. "X-AUTH-TOKEN": "TOKEN 값" public String resolveToken(HttpServletRequest request) { + System.out.println("여기는 옴?222222"); return request.getHeader("X-AUTH-TOKEN"); } diff --git a/src/main/java/com/tgd/trip/jwt/OAuth2LoginSuccessHandler.java b/src/main/java/com/tgd/trip/jwt/OAuth2LoginSuccessHandler.java index 6016458..d9a519c 100644 --- a/src/main/java/com/tgd/trip/jwt/OAuth2LoginSuccessHandler.java +++ b/src/main/java/com/tgd/trip/jwt/OAuth2LoginSuccessHandler.java @@ -1,24 +1,21 @@ package com.tgd.trip.jwt; -import com.tgd.trip.security.LoginResponse; -import com.tgd.trip.user.service.CustomOAuth2User; +import com.tgd.trip.global.oauth2.dto.CustomOAuth2User; +import com.tgd.trip.user.domain.Role; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.oauth2.core.user.DefaultOAuth2User; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.stereotype.Component; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.util.UriComponentsBuilder; +import org.springframework.ui.Model; import javax.servlet.ServletException; +import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.nio.charset.StandardCharsets; +import java.net.URLEncoder; @Component @RequiredArgsConstructor @@ -32,22 +29,30 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { log.info("OAuth login 성공"); - log.info("뭔가뭔가날라옴 : {}", authentication); CustomOAuth2User oAuth2User = (CustomOAuth2User) authentication.getPrincipal(); - loginSuccess(response, oAuth2User); + loginSuccess(request, response, oAuth2User); } - private void loginSuccess(HttpServletResponse response, CustomOAuth2User oAuth2User) throws IOException { - String accessToken = jwtTokenProvider.createToken(oAuth2User.getEmail(), oAuth2User.getRoles()); - response.setHeader("Authorization", "Bearer " + accessToken); - log.info("oauth email : {} login success", oAuth2User.getEmail()); - log.info("accessToken : {}", accessToken); - response.getWriter().println(accessToken); - login(accessToken); - } + private void loginSuccess(HttpServletRequest request, HttpServletResponse response, CustomOAuth2User oAuth2User) throws IOException { + String accessToken = jwtTokenProvider.createToken(oAuth2User.getUserId(), oAuth2User.getRoles()); + + Cookie cookie = new Cookie("Authorization", accessToken); + + // 쿠키 설정 + cookie.setPath("/"); + cookie.setHttpOnly(false); + cookie.setSecure(true); // HTTPS를 사용할 때만 쿠키가 전송되도록 설정 + response.addCookie(cookie); // 쿠키를 응답에 추가 + + log.info("cookie : {}", cookie); + log.info("oauth email : {} login success", oAuth2User.getUserId()); + log.info("oauth role : {}", oAuth2User.getRoles()); + log.info("accessToken 여기까진 온다 : {}", accessToken); + + String redirectUrl = "http://localhost:5173/login"; + + log.info("Url : {}", redirectUrl); - public ResponseEntity login(String accessToken) { - String jwt = accessToken; - return ResponseEntity.ok(jwt); + response.sendRedirect(redirectUrl); } -} \ No newline at end of file +} diff --git a/src/main/java/com/tgd/trip/schedule/controller/ScheduleController.java b/src/main/java/com/tgd/trip/schedule/controller/ScheduleController.java index 860c177..0628384 100644 --- a/src/main/java/com/tgd/trip/schedule/controller/ScheduleController.java +++ b/src/main/java/com/tgd/trip/schedule/controller/ScheduleController.java @@ -1,7 +1,6 @@ package com.tgd.trip.schedule.controller; import com.tgd.trip.schedule.domain.Schedule; -import com.tgd.trip.schedule.dto.CommentDto; import com.tgd.trip.schedule.dto.ScheduleDto; import com.tgd.trip.schedule.mapper.ScheduleMapper; import com.tgd.trip.schedule.service.ScheduleService; @@ -27,19 +26,17 @@ public class ScheduleController { private final ScheduleMapper scheduleMapper; @PostMapping - public ResponseEntity createSchedule(@RequestPart ScheduleDto.Post post, - @RequestParam(value = "image", required = false) MultipartFile file) { + public ResponseEntity createSchedule(@RequestBody ScheduleDto.Post post) { log.info(String.valueOf(post)); - Schedule schedule = scheduleService.createSchedule(post, file); + Schedule schedule = scheduleService.createSchedule(post); return ResponseEntity.created(URI.create(String.format("api/schedule/%s", schedule.getScheduleId()))).build(); } @PatchMapping("{schedule-id}") public ResponseEntity updateSchedule(@PathVariable("schedule-id") Long id, - @RequestPart ScheduleDto.Patch patch, - @RequestParam(value = "image", required = false) MultipartFile file) { + @RequestBody ScheduleDto.Patch patch) { log.info(String.valueOf(patch)); - Schedule schedule = scheduleService.updateSchedule(id, patch, file); + Schedule schedule = scheduleService.updateSchedule(id, patch); ScheduleDto.Response response = scheduleMapper.entityToResponse(schedule); return ResponseEntity.ok(response); } @@ -89,40 +86,4 @@ public ResponseEntity deleteScheduleBookmark(@PathVariable("schedule-id") Lon scheduleService.deleteBookmark(scheduleId, userId); return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); } - - @PostMapping(value = "{schedule-id}/like") - public ResponseEntity createScheduleLike(@PathVariable("schedule-id") Long scheduleId, - @RequestParam("userId") Long userId) { - scheduleService.createLike(scheduleId, userId); - return ResponseEntity.status(HttpStatus.CREATED).build(); - } - - @PostMapping(value = "{schedule-id}/comment") - public ResponseEntity createComment(@PathVariable("schedule-id") Long scheduleId, - @RequestBody CommentDto.Post post) { - scheduleService.createComment(scheduleId, post); - return ResponseEntity.status(HttpStatus.CREATED).build(); - } - - @PatchMapping(value = "{schedule-id}/comment/{comment-id}") - public ResponseEntity updateComment(@PathVariable("schedule-id") Long scheduleId, - @PathVariable("comment-id") Long commentId, - @RequestBody CommentDto.Patch patch) { - scheduleService.updateComment(scheduleId, commentId, patch); - return ResponseEntity.status(HttpStatus.CREATED).build(); - } - - @GetMapping(value = "{schedule-id}/comment") - public ResponseEntity getComments(@PathVariable("schedule-id") Long scheduleId) { - Schedule schedule = scheduleService.getSchedule(scheduleId); - List responses = scheduleMapper.entityToCommentResponse(schedule); - return ResponseEntity.ok(responses); - } - - @DeleteMapping(value = "{schedule-id}/comment/{comment-id}") - public ResponseEntity deleteComment(@PathVariable("schedule-id") Long scheduleId, - @PathVariable("comment-id") Long commentId) { - scheduleService.deleteComment(scheduleId, commentId); - return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); - } } diff --git a/src/main/java/com/tgd/trip/schedule/domain/Comment.java b/src/main/java/com/tgd/trip/schedule/domain/Comment.java index 95d2144..0b9ce81 100644 --- a/src/main/java/com/tgd/trip/schedule/domain/Comment.java +++ b/src/main/java/com/tgd/trip/schedule/domain/Comment.java @@ -1,13 +1,10 @@ package com.tgd.trip.schedule.domain; import com.tgd.trip.global.BaseEntity; -import com.tgd.trip.schedule.dto.CommentDto; import com.tgd.trip.user.domain.User; import lombok.*; import javax.persistence.*; -import javax.validation.constraints.NotNull; -import java.util.Optional; @Entity @Getter @@ -19,22 +16,11 @@ public class Comment extends BaseEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long commentId; @Column(columnDefinition = "TEXT") - @NotNull private String content; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne @JoinColumn(name = "schedule_id") private Schedule schedule; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne @JoinColumn(name = "user_id") private User user; - - public Comment(User user, String content) { - this.user = user; - this.content = content; - } - - public void update(CommentDto.Patch patch) { - Optional.of(patch.content()) - .ifPresent(this::setContent); - } } diff --git a/src/main/java/com/tgd/trip/schedule/domain/Schedule.java b/src/main/java/com/tgd/trip/schedule/domain/Schedule.java index 082beea..3b9e832 100644 --- a/src/main/java/com/tgd/trip/schedule/domain/Schedule.java +++ b/src/main/java/com/tgd/trip/schedule/domain/Schedule.java @@ -1,11 +1,12 @@ package com.tgd.trip.schedule.domain; import com.tgd.trip.global.BaseEntity; -import com.tgd.trip.schedule.dto.ScheduleDto; import lombok.*; import javax.persistence.*; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; @Getter @Setter @@ -14,41 +15,17 @@ @AllArgsConstructor @Builder public class Schedule extends BaseEntity { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long scheduleId; private String title; private String content; + private Long likes; private String imgUrl; private Boolean viewYn = false; @OneToMany(mappedBy = "schedule", cascade = CascadeType.PERSIST, fetch = FetchType.LAZY, orphanRemoval = true) - private List scheduleLikes = new ArrayList<>(); - @OneToMany(mappedBy = "schedule", cascade = CascadeType.PERSIST, fetch = FetchType.LAZY, orphanRemoval = true) private final List days = new ArrayList<>(); - @OneToMany(mappedBy = "schedule", cascade = CascadeType.PERSIST, fetch = FetchType.LAZY, orphanRemoval = true) - private final List comments = new ArrayList<>(); - - public Schedule(ScheduleDto.Post post, String imgUrl) { - Optional.of(post.title()) - .ifPresent(this::setTitle); - Optional.of(post.content()) - .ifPresent(this::setContent); - Optional.of(imgUrl) - .ifPresent(this::setImgUrl); - Optional.of(post.viewYn()) - .ifPresent(this::setViewYn); - } - - public void updateSchedule(ScheduleDto.Patch patch, String imgUrl) { - Optional.of(patch.title()) - .ifPresent(this::setTitle); - Optional.of(patch.content()) - .ifPresent(this::setContent); - Optional.of(imgUrl) - .ifPresent(this::setImgUrl); - Optional.of(patch.viewYn()) - .ifPresent(this::setViewYn); - } public void addDays(Day day) { if (!this.days.contains(day)) { @@ -57,17 +34,10 @@ public void addDays(Day day) { day.setSchedule(this); } - public void addLike(ScheduleLike scheduleLike){ - if(!this.scheduleLikes.contains(scheduleLike)){ - scheduleLikes.add(scheduleLike); - } - scheduleLike.setSchedule(this); - } - - public void addComments(Comment comment){ - if(!this.comments.contains(comment)){ - comments.add(comment); - } - comment.setSchedule(this); + public Schedule(String title, String content) { + Optional.of(title) + .ifPresent(this::setTitle); + Optional.of(content) + .ifPresent(this::setContent); } } diff --git a/src/main/java/com/tgd/trip/schedule/domain/ScheduleLike.java b/src/main/java/com/tgd/trip/schedule/domain/ScheduleLike.java deleted file mode 100644 index f429e28..0000000 --- a/src/main/java/com/tgd/trip/schedule/domain/ScheduleLike.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.tgd.trip.schedule.domain; - -import com.tgd.trip.global.BaseEntity; -import com.tgd.trip.user.domain.User; -import lombok.*; - -import javax.persistence.*; - -@Entity -@Getter -@Setter -@NoArgsConstructor -public class ScheduleLike extends BaseEntity { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long scheduleLikeId; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "user_id") - private User user; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "schedule_id") - private Schedule schedule; - - public ScheduleLike(User user) { - this.user = user; - } -} diff --git a/src/main/java/com/tgd/trip/schedule/dto/CommentDto.java b/src/main/java/com/tgd/trip/schedule/dto/CommentDto.java deleted file mode 100644 index 2fe5c21..0000000 --- a/src/main/java/com/tgd/trip/schedule/dto/CommentDto.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.tgd.trip.schedule.dto; - -import com.tgd.trip.user.dto.UserDto; - -import java.time.LocalDateTime; - -public class CommentDto { - - public record Post(String content, Long userId) { - } - - public record Patch(String content, Long userId) { - } - - public record Response(Long commentId, String content, UserDto.SimpleResponse writer, LocalDateTime createdAt, LocalDateTime updatedAt) { - } - -} diff --git a/src/main/java/com/tgd/trip/schedule/dto/DayDto.java b/src/main/java/com/tgd/trip/schedule/dto/DayDto.java index ddbde7d..79547e2 100644 --- a/src/main/java/com/tgd/trip/schedule/dto/DayDto.java +++ b/src/main/java/com/tgd/trip/schedule/dto/DayDto.java @@ -7,15 +7,19 @@ public class DayDto { - public record Post(LocalDate date, List dayAttractions) { + public record Post(LocalDate date, List dayAttractions){ + + } - public record Patch(LocalDate date, List dayAttractions) { + public record Patch(LocalDate date, List dayAttractions){ + + } + public record Response(LocalDate date, List attractions){ - public record Response(Long dayId, LocalDate date, List attractions) { } + public record DateResponse(LocalDate date){ - public record DateResponse(Long dayId, LocalDate date) { } } diff --git a/src/main/java/com/tgd/trip/schedule/dto/ScheduleDto.java b/src/main/java/com/tgd/trip/schedule/dto/ScheduleDto.java index 4f93c3b..cb6ff3c 100644 --- a/src/main/java/com/tgd/trip/schedule/dto/ScheduleDto.java +++ b/src/main/java/com/tgd/trip/schedule/dto/ScheduleDto.java @@ -6,10 +6,20 @@ public class ScheduleDto { - public record Post(String title, String content, Boolean viewYn, List days) { + public record Post(String title, + String content, + Boolean viewYn, + String imgUrl, + List days + ) { } - public record Patch(String title, String content, Boolean viewYn, List days) { + public record Patch(String title, + String content, + Boolean viewYn, + String imgUrl, + List days + ) { } @Builder diff --git a/src/main/java/com/tgd/trip/schedule/mapper/ScheduleMapper.java b/src/main/java/com/tgd/trip/schedule/mapper/ScheduleMapper.java index 489ff31..f7ea4f0 100644 --- a/src/main/java/com/tgd/trip/schedule/mapper/ScheduleMapper.java +++ b/src/main/java/com/tgd/trip/schedule/mapper/ScheduleMapper.java @@ -2,8 +2,8 @@ import com.tgd.trip.attraction.dto.AttractionDto; import com.tgd.trip.schedule.domain.Schedule; -import com.tgd.trip.schedule.dto.*; -import com.tgd.trip.user.dto.UserDto; +import com.tgd.trip.schedule.dto.DayDto; +import com.tgd.trip.schedule.dto.ScheduleDto; import org.springframework.stereotype.Component; import java.util.List; @@ -17,43 +17,23 @@ public ScheduleDto.Response entityToResponse(Schedule schedule) { .title(schedule.getTitle()) .content(schedule.getContent()) .viewYn(schedule.getViewYn()) - .dayResponses( - schedule.getDays().stream() - .map(day -> new DayDto.Response( - day.getDayId(), - day.getDate(), - day.getDayAttractions().stream() - .map(dayAttraction -> new AttractionDto.Response(dayAttraction.getAttraction())) - .toList())) - .toList()) + .dayResponses(schedule.getDays().stream().map( + day -> new DayDto.Response(day.getDate(), day.getDayAttractions().stream().map(dayAttraction -> new AttractionDto.Response(dayAttraction.getAttraction())).toList()) + ).toList()) .build(); } public List simpleResponses(List schedules) { - return schedules.stream() - .map(schedule -> new ScheduleDto.SimpleResponse( + return schedules.stream().map(schedule -> + new ScheduleDto.SimpleResponse( schedule.getScheduleId(), schedule.getTitle(), schedule.getContent(), schedule.getImgUrl(), - schedule.getDays().stream() - .map(day -> new DayDto.DateResponse(day.getDayId(), day.getDate())) - .toList())) - .toList(); + schedule.getDays().stream().map(day -> + new DayDto.DateResponse(day.getDate())) + .toList()) + ).toList(); } - public List entityToCommentResponse(Schedule schedule) { - return schedule.getComments().stream() - .map(comment -> new CommentDto.Response( - comment.getCommentId(), - comment.getContent(), - new UserDto.SimpleResponse( - comment.getUser().getUserId(), - comment.getUser().getNickName(), - comment.getUser().getImgUrl() - ), - comment.getCreatedAt(), - comment.getModifiedAt())) - .toList(); - } } diff --git a/src/main/java/com/tgd/trip/schedule/repository/CommentRepository.java b/src/main/java/com/tgd/trip/schedule/repository/CommentRepository.java deleted file mode 100644 index 006365a..0000000 --- a/src/main/java/com/tgd/trip/schedule/repository/CommentRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.tgd.trip.schedule.repository; - -import com.tgd.trip.schedule.domain.Comment; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface CommentRepository extends JpaRepository { - -} diff --git a/src/main/java/com/tgd/trip/schedule/repository/ScheduleLikeRepository.java b/src/main/java/com/tgd/trip/schedule/repository/ScheduleLikeRepository.java deleted file mode 100644 index d15a93f..0000000 --- a/src/main/java/com/tgd/trip/schedule/repository/ScheduleLikeRepository.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.tgd.trip.schedule.repository; - -import com.tgd.trip.schedule.domain.Schedule; -import com.tgd.trip.schedule.domain.ScheduleLike; -import com.tgd.trip.user.domain.User; -import org.springframework.data.jpa.repository.JpaRepository; - -import java.time.LocalDateTime; - -public interface ScheduleLikeRepository extends JpaRepository { - - boolean existsByCreatedAtBetweenAndUserAndSchedule(LocalDateTime startDate, LocalDateTime endDate, User user, Schedule schedule); -} diff --git a/src/main/java/com/tgd/trip/schedule/repository/ScheduleRepository.java b/src/main/java/com/tgd/trip/schedule/repository/ScheduleRepository.java index 2c2a91f..bba1798 100644 --- a/src/main/java/com/tgd/trip/schedule/repository/ScheduleRepository.java +++ b/src/main/java/com/tgd/trip/schedule/repository/ScheduleRepository.java @@ -8,5 +8,5 @@ public interface ScheduleRepository extends JpaRepository { - List findAllByTitleContainingAndViewYnNot(String keyword, Boolean viewYn, Pageable pageable); + List findAllByTitleContaining(String keyword, Pageable pageable); } diff --git a/src/main/java/com/tgd/trip/schedule/service/DayAttractionService.java b/src/main/java/com/tgd/trip/schedule/service/DayAttractionService.java index 5b5ee8b..bd8eab2 100644 --- a/src/main/java/com/tgd/trip/schedule/service/DayAttractionService.java +++ b/src/main/java/com/tgd/trip/schedule/service/DayAttractionService.java @@ -12,7 +12,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import javax.transaction.Transactional; import java.util.List; @RequiredArgsConstructor @@ -23,7 +22,6 @@ public class DayAttractionService { private final DayAttractionRepository dayAttractionRepository; private final AttractionRepository attractionRepository; - @Transactional public void update(DayAttractionDto dayAttractionDto, Day day) { // 관광지 정보 찾아오기 Attraction attraction = attractionRepository.findById(dayAttractionDto.attractionId()) @@ -34,7 +32,6 @@ public void update(DayAttractionDto dayAttractionDto, Day day) { dayAttractionRepository.save(dayAttraction); } - @Transactional public void deleteAll(List dayAttractionIds) { dayAttractionRepository.deleteAllByIds(dayAttractionIds); } diff --git a/src/main/java/com/tgd/trip/schedule/service/ScheduleService.java b/src/main/java/com/tgd/trip/schedule/service/ScheduleService.java index f6292bb..a011b1b 100644 --- a/src/main/java/com/tgd/trip/schedule/service/ScheduleService.java +++ b/src/main/java/com/tgd/trip/schedule/service/ScheduleService.java @@ -5,9 +5,9 @@ import com.tgd.trip.global.s3.S3Uploader; import com.tgd.trip.photo.domain.Photo; import com.tgd.trip.schedule.domain.*; -import com.tgd.trip.schedule.dto.CommentDto; import com.tgd.trip.schedule.dto.ScheduleDto; -import com.tgd.trip.schedule.repository.*; +import com.tgd.trip.schedule.repository.ScheduleBookmarkRepository; +import com.tgd.trip.schedule.repository.ScheduleRepository; import com.tgd.trip.user.domain.User; import com.tgd.trip.user.service.UserService; import lombok.RequiredArgsConstructor; @@ -18,7 +18,6 @@ import org.springframework.web.multipart.MultipartFile; import javax.transaction.Transactional; -import java.time.*; import java.util.List; @Service @@ -28,25 +27,14 @@ public class ScheduleService { private final ScheduleRepository scheduleRepository; private final ScheduleBookmarkRepository scheduleBookmarkRepository; - private final ScheduleLikeRepository scheduleLikeRepository; - private final CommentRepository commentRepository; private final DayAttractionService dayAttractionService; private final S3Uploader s3Uploader; private final UserService userService; @Transactional - public Schedule createSchedule(ScheduleDto.Post post, MultipartFile file) { + public Schedule createSchedule(ScheduleDto.Post post) { // 일정 이름, 내용을 가지는 객체 생성 - String imgUrl = ""; - - // 일정용 이미지 업로드 - if (file != null) { - imgUrl = s3Uploader.saveUploadFile(file); - imgUrl = s3Uploader.getFilePath(imgUrl); - log.debug("filePath : " + imgUrl); - } - - Schedule schedule = new Schedule(post, imgUrl); + Schedule schedule = new Schedule(post.title(), post.content()); post.days().forEach(dayDtoPost -> { // 새로운 일자 객체 생성 및 일정 객체와 연결 @@ -62,21 +50,10 @@ public Schedule createSchedule(ScheduleDto.Post post, MultipartFile file) { } @Transactional - public Schedule updateSchedule(Long scheduleId, ScheduleDto.Patch patch, MultipartFile file) { + public Schedule updateSchedule(Long scheduleId, ScheduleDto.Patch patch) { // 기존 스케줄 가져오기 Schedule schedule = getSchedule(scheduleId); - // 일정용 이미지 업로드 - String imgUrl = ""; - if (file != null) { - imgUrl = s3Uploader.saveUploadFile(file); - imgUrl = s3Uploader.getFilePath(imgUrl); - log.debug("filePath : " + imgUrl); - } - - // 일정 객체 업데이트 - schedule.updateSchedule(patch, imgUrl); - // 받아온 day로 새로운 일자 만들기 patch.days().forEach(dayDtoPatch -> { // 기존에 존재하는 일자 가져오기 @@ -102,19 +79,19 @@ public Schedule updateSchedule(Long scheduleId, ScheduleDto.Patch patch, Multipa return schedule; } + public Schedule getSchedule(Long id) { return scheduleRepository.findById(id) .orElseThrow(() -> new CustomException(ErrorCode.SCHEDULE_NOT_FOUND)); } - @Transactional public void deleteSchedule(Long id) { Schedule schedule = getSchedule(id); scheduleRepository.delete(schedule); } public List getSchedules(String keyword, String sort, Pageable pageable) { - List schedules = scheduleRepository.findAllByTitleContainingAndViewYnNot(keyword, true, PageRequest.of(pageable.getPageNumber(), pageable.getPageSize())); + List schedules = scheduleRepository.findAllByTitleContaining(keyword, PageRequest.of(pageable.getPageNumber(), pageable.getPageSize())); return schedules; } @@ -153,73 +130,4 @@ public void deleteBookmark(Long scheduleId, Long userId) { Schedule findSchedule = getSchedule(scheduleId); scheduleBookmarkRepository.deleteByUserAndSchedule(findUser, findSchedule); } - - @Transactional - public void createLike(Long scheduleId, Long userId) { - User findUser = userService.getVerifyUser(userId); - Schedule findSchedule = getSchedule(scheduleId); - - // 오늘의 시작 시간과 끝 시간을 구하기 - LocalDate today = LocalDate.now(); - LocalDateTime startOfDay = today.atStartOfDay(); - LocalDateTime endOfDay = today.atTime(LocalTime.MAX); - - // 찾은 범위를 바탕으로 해당 스케줄에 해당 유저가 좋아요를 했는지 검증 - if (scheduleLikeRepository.existsByCreatedAtBetweenAndUserAndSchedule(startOfDay, endOfDay, findUser, findSchedule)) { - throw new CustomException(ErrorCode.TOO_MANY_LIKES); - } - - // 좋아요 생성 - ScheduleLike scheduleLike = new ScheduleLike(findUser); - findSchedule.addLike(scheduleLike); - scheduleLikeRepository.save(scheduleLike); - } - - @Transactional - public void createComment(Long scheduleId, CommentDto.Post post) { - // 스케줄 예외 처리 - Schedule findSchedule = getSchedule(scheduleId); - - // 유저 예외 처리 - User findUser = userService.getVerifyUser(post.userId()); - - // 댓글 생성 - Comment comment = new Comment(findUser, post.content()); - findSchedule.addComments(comment); - commentRepository.save(comment); - } - - @Transactional - public void updateComment(Long scheduleId, Long commentId, CommentDto.Patch patch) { - // 스케줄 예외 처리 - getSchedule(scheduleId); - - // 유저 예외 처리 - User findUser = userService.getVerifyUser(patch.userId()); - - // 댓글 가져오기 - Comment findComment = commentRepository.findById(commentId) - .orElseThrow(() -> new CustomException(ErrorCode.COMMENT_NOT_FOUND)); - - // 유저 검증 - if (!findUser.getEmail().equals(findComment.getUser().getEmail())) { - throw new CustomException(ErrorCode.DIFFERENT_USER); - } - - // 댓글 수정 - findComment.update(patch); - commentRepository.save(findComment); - } - - @Transactional - public void deleteComment(Long scheduleId, Long commentId) { - // 스케줄 예외 처리 - getSchedule(scheduleId); - - // 댓글 가져오기 - Comment findComment = commentRepository.findById(commentId) - .orElseThrow(() -> new CustomException(ErrorCode.COMMENT_NOT_FOUND)); - - commentRepository.delete(findComment); - } } diff --git a/src/main/java/com/tgd/trip/security/SecurityConfig.java b/src/main/java/com/tgd/trip/security/SecurityConfig.java index 97b2553..0659831 100644 --- a/src/main/java/com/tgd/trip/security/SecurityConfig.java +++ b/src/main/java/com/tgd/trip/security/SecurityConfig.java @@ -51,14 +51,14 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .cors().configurationSource(corsConfigurationSource()) // CORS 구성을 위한 설정 소스를 지정합니다. .and() - .headers().frameOptions().disable() // X-Frame-Options를 비활성화합니다. +// .headers().frameOptions().disable() // X-Frame-Options를 비활성화합니다. - .and() +// .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 세션을 상태 없이 관리합니다. .and() .authorizeRequests() // 요청에 대한 사용 권한 체크 시작 - .antMatchers(HttpMethod.GET,"/api/user/**").authenticated() + .antMatchers("/api/user/**").authenticated() .anyRequest().permitAll() .and().addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), UsernamePasswordAuthenticationFilter.class) @@ -75,12 +75,12 @@ public CorsConfigurationSource corsConfigurationSource() { // CORS 구성을 위한 CorsConfigurationSource를 설정합니다. CorsConfiguration configuration = new CorsConfiguration(); - configuration.setAllowedOrigins(List.of("*")); // 모든 Origin을 허용합니다. +// configuration.setAllowedOrigins(List.of("*")); // 모든 Origin을 허용합니다. + configuration.setAllowedOriginPatterns(List.of("*")); configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PATCH", "PUT", "DELETE", "HEAD")); // 허용할 HTTP 메서드를 설정합니다. configuration.setAllowedHeaders(List.of("*")); // 모든 헤더를 허용합니다. configuration.setExposedHeaders(List.of("*")); // 노출할 헤더를 설정합니다. configuration.setAllowCredentials(false); // 인증 정보를 포함하지 않도록 설정합니다. - UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); // 모든 경로에 대해 CORS 구성을 적용합니다. diff --git a/src/main/java/com/tgd/trip/security/SecurityUser.java b/src/main/java/com/tgd/trip/security/SecurityUser.java index 71b937e..cac15df 100644 --- a/src/main/java/com/tgd/trip/security/SecurityUser.java +++ b/src/main/java/com/tgd/trip/security/SecurityUser.java @@ -1,8 +1,11 @@ package com.tgd.trip.security; +import lombok.extern.log4j.Log4j; +import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.userdetails.User; +@Slf4j public class SecurityUser extends User { private com.tgd.trip.user.domain.User user; diff --git a/src/main/java/com/tgd/trip/security/SecurityUserDetailService.java b/src/main/java/com/tgd/trip/security/SecurityUserDetailService.java index 0a0c7e6..214ea63 100644 --- a/src/main/java/com/tgd/trip/security/SecurityUserDetailService.java +++ b/src/main/java/com/tgd/trip/security/SecurityUserDetailService.java @@ -20,9 +20,7 @@ public SecurityUserDetailService(UserRepository mapper) { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { -// System.out.println("loadByUserName"); - - Optional user = repo.findByEmail(username); + Optional user = repo.findById(Long.parseLong(username)); if (user == null) { throw new UsernameNotFoundException(username + " 사용자 없음"); } else { diff --git a/src/main/java/com/tgd/trip/user/controller/UserController.java b/src/main/java/com/tgd/trip/user/controller/UserController.java index 9f2a39c..c9324b1 100644 --- a/src/main/java/com/tgd/trip/user/controller/UserController.java +++ b/src/main/java/com/tgd/trip/user/controller/UserController.java @@ -2,23 +2,15 @@ import com.tgd.trip.jwt.JwtTokenProvider; import com.tgd.trip.security.SecurityUser; -import com.tgd.trip.user.domain.User; -import com.tgd.trip.user.domain.UserPrincipal; -import com.tgd.trip.user.repository.UserRepository; -import com.tgd.trip.user.service.OAuth2UserService; +import com.tgd.trip.user.domain.SignupDto; +import com.tgd.trip.user.service.UserService; import lombok.RequiredArgsConstructor; -import lombok.extern.log4j.Log4j; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; -import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.web.bind.annotation.*; -import java.util.Map; -import java.util.Optional; - @RequiredArgsConstructor @RestController @RequestMapping("/api/user") @@ -26,16 +18,30 @@ public class UserController { private final PasswordEncoder passwordEncoder; private final JwtTokenProvider jwtTokenProvider; - private final UserRepository reop; - - @GetMapping("/login/test") - public ResponseEntity test(@AuthenticationPrincipal SecurityUser securityUser){ - log.info("테스트 요청 토큰 : {}", securityUser); - log.info(securityUser.getAuthorities().stream().toList().toString()); - if (securityUser.getAuthorities().stream().anyMatch(auth -> auth.getAuthority().equals("ROLE_USER"))) - return ResponseEntity.ok("OK"); - else - return ResponseEntity.ok("fail"); + private final UserService userService; + + @GetMapping("/signup") + public ResponseEntity signup(@AuthenticationPrincipal SecurityUser securityUser, @RequestParam Long userId) { + + SignupDto tempuser = null; + System.out.println(userId); + if (securityUser.getAuthorities().stream().anyMatch(auth -> auth.getAuthority().equals("ROLE_GEST"))) { // 요청한 유저가 게스트 라면 + tempuser = userService.getSignup(userId); + } + + return ResponseEntity.ok(tempuser); + } + + @PostMapping("/signup") + public ResponseEntity signup(@AuthenticationPrincipal SecurityUser securityUser, + @RequestBody SignupDto userInfo) { + System.out.println("회원가입 추가정보 받음!!!" + userInfo); + String newToken = null; + if (securityUser.getAuthorities().stream().anyMatch(auth -> auth.getAuthority().equals("ROLE_GEST"))) { // 요청한 유저가 게스트 라면 + newToken = userService.postSignup(userInfo); + } + + return ResponseEntity.ok(newToken); } @GetMapping("/test") diff --git a/src/main/java/com/tgd/trip/user/domain/Role.java b/src/main/java/com/tgd/trip/user/domain/Role.java index 02c6f6a..9081375 100644 --- a/src/main/java/com/tgd/trip/user/domain/Role.java +++ b/src/main/java/com/tgd/trip/user/domain/Role.java @@ -7,7 +7,8 @@ @ToString public enum Role { USER("일반유저"), - ADMIN("어드민"); + ADMIN("어드민"), + GEST("처음 접속한 유저"); private final String role; } diff --git a/src/main/java/com/tgd/trip/user/domain/SignupDto.java b/src/main/java/com/tgd/trip/user/domain/SignupDto.java new file mode 100644 index 0000000..9f017c3 --- /dev/null +++ b/src/main/java/com/tgd/trip/user/domain/SignupDto.java @@ -0,0 +1,28 @@ +package com.tgd.trip.user.domain; + +import lombok.*; + +import java.time.LocalDate; + +@ToString +@Getter +@Setter +@AllArgsConstructor +public class SignupDto { + private Long userId; + private String name; + private String email; + private LocalDate birth; + private String nickName; + private Boolean sex; + + @Builder + public SignupDto(User user) { + this.userId = user.getUserId(); + this.name = user.getName(); + this.email = user.getEmail(); + this.birth = user.getBirth(); + this.nickName = user.getNickName(); + this.sex = user.getSex(); + } +} diff --git a/src/main/java/com/tgd/trip/user/domain/User.java b/src/main/java/com/tgd/trip/user/domain/User.java index 8154a43..c977c64 100644 --- a/src/main/java/com/tgd/trip/user/domain/User.java +++ b/src/main/java/com/tgd/trip/user/domain/User.java @@ -28,13 +28,13 @@ public class User extends BaseEntity { private String email; @NotNull @ElementCollection(fetch = FetchType.EAGER) + @CollectionTable(name = "USER_ROLES", joinColumns = @JoinColumn(name = "USER_ID")) private List roles = new ArrayList<>(); private String provider; private String providerId; - private UserStatus status = UserStatus.ACTIVE; + private UserStatus status=UserStatus.ACTIVE; private LocalDate birth; private String nickName; - private String imgUrl; @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List scheduleBookmarks = new ArrayList<>(); @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY) @@ -42,7 +42,7 @@ public class User extends BaseEntity { private Boolean sex; @Builder - public User(Long userId, String password, String name, String email, List roles, String provider, String providerId, LocalDate birth, String nickName, Boolean sex) { + public User(Long userId, String password, String name, String email, List roles, String provider, String providerId, LocalDate birth, String nickName, Boolean sex){ this.userId = userId; this.password = password; this.name = name; @@ -56,7 +56,7 @@ public User(Long userId, String password, String name, String email, List roles, String provider, String providerId) { + public User( String password, String name, String email, List roles, String provider, String providerId){ this.password = password; this.name = name; this.email = email; diff --git a/src/main/java/com/tgd/trip/user/dto/UserDto.java b/src/main/java/com/tgd/trip/user/dto/UserDto.java deleted file mode 100644 index b631b5a..0000000 --- a/src/main/java/com/tgd/trip/user/dto/UserDto.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.tgd.trip.user.dto; - -public class UserDto { - - public record SimpleResponse(Long userId, String nickname, String imgUrl){} -} diff --git a/src/main/java/com/tgd/trip/user/service/UserService.java b/src/main/java/com/tgd/trip/user/service/UserService.java index a41bd6c..f66a1cf 100644 --- a/src/main/java/com/tgd/trip/user/service/UserService.java +++ b/src/main/java/com/tgd/trip/user/service/UserService.java @@ -1,28 +1,65 @@ package com.tgd.trip.user.service; -import com.tgd.trip.global.exception.CustomException; -import com.tgd.trip.global.exception.ErrorCode; +import com.tgd.trip.jwt.JwtTokenProvider; +import com.tgd.trip.user.domain.Role; +import com.tgd.trip.user.domain.SignupDto; import com.tgd.trip.user.domain.User; import com.tgd.trip.user.repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + @RequiredArgsConstructor @Service public class UserService { private final UserRepository userRepository; - + private final JwtTokenProvider provider; public User getVerifyUser(String email) { - return userRepository.findByEmail(email) - .orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND)); + return userRepository.findByEmail(email).orElseThrow(); } public User getVerifyUser(Long id) { - return userRepository.findById(id) - .orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND)); + return userRepository.findById(id).orElseThrow(); + } + + public SignupDto getSignup(Long userId) { + User user = null; + SignupDto tempuser = null; + Optional optionalUser = userRepository.findById(userId); + if (optionalUser.isPresent()) { + user = optionalUser.get(); + tempuser = new SignupDto(user); + } + + return tempuser; + } + + public String postSignup(SignupDto user) { + String newToken = null; + //signupDto로 추가정보 안한 유저 정보 가져옴 + Optional optionalUser = userRepository.findById(user.getUserId()); + if (optionalUser.isPresent()) { + User oldUser = optionalUser.get(); + oldUser.setNickName(user.getNickName()); + oldUser.setBirth(user.getBirth()); + oldUser.setSex(user.getSex()); + + oldUser.getRoles().add(Role.USER.name()); + System.out.println(oldUser); + + userRepository.save(oldUser); + + newToken = provider.createToken(oldUser.getUserId(), oldUser.getRoles()); + } + + return newToken; } + public void createUser(User user) { userRepository.save(user); } diff --git a/src/test/java/com/tgd/trip/attraction/service/AttractionServiceTest.java b/src/test/java/com/tgd/trip/attraction/service/AttractionServiceTest.java index ae46dd6..45a3a72 100644 --- a/src/test/java/com/tgd/trip/attraction/service/AttractionServiceTest.java +++ b/src/test/java/com/tgd/trip/attraction/service/AttractionServiceTest.java @@ -3,17 +3,17 @@ import com.tgd.trip.attraction.domain.Attraction; import com.tgd.trip.attraction.repository.AttractionRepository; import com.tgd.trip.global.util.Coordinate; +import com.tgd.trip.global.util.Pair; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; import java.util.Arrays; import java.util.List; +import static org.assertj.core.api.BDDAssumptions.given; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.anyDouble; import static org.mockito.Mockito.*; @@ -37,16 +37,15 @@ class AttractionServiceTest { Attraction attraction1 = new Attraction(); Attraction attraction2 = new Attraction(); List expectedAttractions = Arrays.asList(attraction1, attraction2); - PageRequest of = PageRequest.of(1, 10); // when - when(attractionRepository.findAllByLatitudeBetweenAndLongitudeBetween(anyDouble(), anyDouble(), anyDouble(), anyDouble(), any()).getContent()) + when(attractionRepository.findAllByLatitudeBetweenAndLongitudeBetween(anyDouble(), anyDouble(), anyDouble(), anyDouble())) .thenReturn(expectedAttractions); - Page attractions = attractionService.getAttractionsFromCenter(center, height, width, of); + List attractions = attractionService.getAttractionsFromCenter(center, height, width); // then assertEquals(expectedAttractions, attractions); verify(attractionRepository, times(1)) - .findAllByLatitudeBetweenAndLongitudeBetween(anyDouble(), anyDouble(), anyDouble(), anyDouble(), any()); + .findAllByLatitudeBetweenAndLongitudeBetween(anyDouble(), anyDouble(), anyDouble(), anyDouble()); } } \ No newline at end of file