diff --git a/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/request/UserGithubRepoSelectRequest.java b/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/request/UserGithubRepoSelectRequest.java new file mode 100644 index 00000000..6a1ccc86 --- /dev/null +++ b/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/request/UserGithubRepoSelectRequest.java @@ -0,0 +1,9 @@ +package org.ezcode.codetest.application.usermanagement.user.dto.request; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "깃허브 repository 선택 요청") +public record UserGithubRepoSelectRequest( + @Schema(description = "repository 이름", example = "Practice coding") + String repositoryName +) {} \ No newline at end of file diff --git a/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GithubOAuth2Response.java b/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GithubOAuth2Response.java index bf188fd4..a055af43 100644 --- a/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GithubOAuth2Response.java +++ b/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GithubOAuth2Response.java @@ -1,5 +1,6 @@ package org.ezcode.codetest.application.usermanagement.user.dto.response; +import java.util.List; import java.util.Map; import io.swagger.v3.oas.annotations.media.Schema; @@ -41,14 +42,20 @@ public String getName() { } @Override - @Schema(description = "Github Id", example = "1345932") + @Schema(description = "깃허브 고유 Id", example = "1345932") public String getGithubId() { return attributes.get("id").toString(); } @Override - @Schema(description = "Github URL", example = "https://github.com/id") + @Schema(description = "깃허브 홈 URL", example = "https://github.com/id") public String getGithubUrl(){ return attributes.get("html_url").toString(); } + + @Override + @Schema(description = "깃허브 아이디(login name)", example = "ezcode") + public String getOwner(){ + return attributes.get("login").toString(); + } } diff --git a/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GoogleOAuth2Response.java b/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GoogleOAuth2Response.java index dc61936b..984c38ce 100644 --- a/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GoogleOAuth2Response.java +++ b/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/GoogleOAuth2Response.java @@ -48,5 +48,9 @@ public String getGithubUrl() { return ""; } + @Override + public String getOwner() { + return ""; + } } diff --git a/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/OAuth2Response.java b/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/OAuth2Response.java index 619b895b..f0b14756 100644 --- a/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/OAuth2Response.java +++ b/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/OAuth2Response.java @@ -18,4 +18,8 @@ public interface OAuth2Response { //깃헙 링크 String getGithubUrl(); + + + //깃헙 owner + String getOwner(); } diff --git a/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/UserGithubRepoResponse.java b/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/UserGithubRepoResponse.java new file mode 100644 index 00000000..c2ed6f7b --- /dev/null +++ b/src/main/java/org/ezcode/codetest/application/usermanagement/user/dto/response/UserGithubRepoResponse.java @@ -0,0 +1,17 @@ +package org.ezcode.codetest.application.usermanagement.user.dto.response; + + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; + +@Getter +@Schema(description = "유저의 Public Repository 리스트를 보여줍니다") +public class UserGithubRepoResponse { + private String repoName; + private String defaultBranch; + + public UserGithubRepoResponse(String repoName, String defaultBranch) { + this.repoName = repoName; + this.defaultBranch = defaultBranch; + } +} diff --git a/src/main/java/org/ezcode/codetest/common/security/config/WebClientConfig.java b/src/main/java/org/ezcode/codetest/common/security/config/WebClientConfig.java new file mode 100644 index 00000000..27221cf1 --- /dev/null +++ b/src/main/java/org/ezcode/codetest/common/security/config/WebClientConfig.java @@ -0,0 +1,18 @@ +package org.ezcode.codetest.common.security.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; +import org.springframework.web.reactive.function.client.WebClient; + +@Configuration +public class WebClientConfig { + @Bean + public WebClient githubWebClient() { + return WebClient.builder() + .baseUrl("https://api.github.com") + .defaultHeader(HttpHeaders.ACCEPT, "application/vnd.github+json") + .defaultHeader(HttpHeaders.USER_AGENT, "ezcode-codetest-server") + .build(); + } +} diff --git a/src/main/java/org/ezcode/codetest/common/security/hander/CustomSuccessHandler.java b/src/main/java/org/ezcode/codetest/common/security/hander/CustomSuccessHandler.java index 3f95a101..0ccaa66a 100644 --- a/src/main/java/org/ezcode/codetest/common/security/hander/CustomSuccessHandler.java +++ b/src/main/java/org/ezcode/codetest/common/security/hander/CustomSuccessHandler.java @@ -9,8 +9,10 @@ import org.ezcode.codetest.domain.user.exception.code.AuthExceptionCode; import org.ezcode.codetest.domain.user.model.entity.CustomOAuth2User; import org.ezcode.codetest.domain.user.model.entity.User; +import org.ezcode.codetest.domain.user.model.entity.UserGithubInfo; import org.ezcode.codetest.domain.user.service.UserDomainService; import org.ezcode.codetest.common.security.util.JwtUtil; +import org.ezcode.codetest.domain.user.service.UserGithubService; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; @@ -32,17 +34,20 @@ public class CustomSuccessHandler extends SimpleUrlAuthenticationSuccessHandler private final JwtUtil jwtUtil; private final UserDomainService userDomainService; + private final UserGithubService userGithubService; private final RedisTemplate redisTemplate; private final ObjectMapper objectMapper; //json직렬화 private final OAuth2AuthorizedClientService authorizedClientService; private final AESUtil aesUtil; public CustomSuccessHandler(JwtUtil jwtUtil, UserDomainService userDomainService, + UserGithubService userGithubService, RedisTemplate redisTemplate, ObjectMapper objectMapper, OAuth2AuthorizedClientService authorizedClientService, AESUtil aesUtil) { this.jwtUtil = jwtUtil; this.userDomainService = userDomainService; - this.redisTemplate = redisTemplate; + this.userGithubService = userGithubService; + this.redisTemplate = redisTemplate; this.objectMapper = objectMapper; this.authorizedClientService = authorizedClientService; this.aesUtil = aesUtil; @@ -66,15 +71,18 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo oauthToken.getName() ); + UserGithubInfo userGithubInfo = userGithubService.getUserGithubInfoById(loginUser.getId()); + //AES 암호화 try { String encodedGithubToken = aesUtil.encrypt(client.getAccessToken().getTokenValue()); - loginUser.setGithubAccessToken(encodedGithubToken); + + userGithubInfo.setGithubAccessToken(encodedGithubToken); } catch (Exception e) { log.error(e.getMessage()); throw new AuthException(AuthExceptionCode.TOKEN_ENCODE_FAIL); } - userDomainService.updateUserGithubAccessToken(loginUser); + userGithubService.updateUserGithubAccessToken(userGithubInfo); } String accessToken = jwtUtil.createAccessToken( diff --git a/src/main/java/org/ezcode/codetest/domain/user/exception/code/UserExceptionCode.java b/src/main/java/org/ezcode/codetest/domain/user/exception/code/UserExceptionCode.java index 5117b972..9c3e0980 100644 --- a/src/main/java/org/ezcode/codetest/domain/user/exception/code/UserExceptionCode.java +++ b/src/main/java/org/ezcode/codetest/domain/user/exception/code/UserExceptionCode.java @@ -11,7 +11,9 @@ public enum UserExceptionCode implements ResponseCode { NOT_ENOUGH_TOKEN(false, HttpStatus.BAD_REQUEST, "리뷰 토큰이 부족합니다."), - NOT_MATCH_CODE(false, HttpStatus.BAD_REQUEST, "이메일 인증 코드가 일치하지 않습니다."); + NOT_MATCH_CODE(false, HttpStatus.BAD_REQUEST, "이메일 인증 코드가 일치하지 않습니다."), + NO_GITHUB_INFO(false, HttpStatus.BAD_REQUEST, "깃허브 정보가 없습니다."), + NO_GITHUB_REPO(false, HttpStatus.BAD_REQUEST, "해당하는 Repository를 찾을 수 없습니다."); private final boolean success; private final HttpStatus status; diff --git a/src/main/java/org/ezcode/codetest/domain/user/model/entity/User.java b/src/main/java/org/ezcode/codetest/domain/user/model/entity/User.java index ba4ec3c2..27360b07 100644 --- a/src/main/java/org/ezcode/codetest/domain/user/model/entity/User.java +++ b/src/main/java/org/ezcode/codetest/domain/user/model/entity/User.java @@ -72,7 +72,7 @@ public class User extends BaseEntity { private boolean verified; //이메일 인증 여부 - private String githubAccessToken; //깃허브 access_token 값 + private boolean gitPushStatus; //깃허브 자동 push 여부 /* @@ -91,6 +91,7 @@ public static User emailUser(String email, String password, String username, Str .role(UserRole.ADMIN) // 테스트용 .isDeleted(false) .verified(false) + .gitPushStatus(false) .build(); } @@ -108,6 +109,7 @@ public static User socialUser(String email, String username, String nickname, St .password(password) .isDeleted(false) .verified(false) + .gitPushStatus(false) .build(); } @@ -123,13 +125,14 @@ public static User githubUser(String email, String username, String nickname, St .isDeleted(false) .verified(false) .githubUrl(githubUrl) + .gitPushStatus(false) .build(); } @Builder public User(String email, String password, String username, String nickname, - Integer age, Tier tier, UserRole role, boolean isDeleted, boolean verified, String githubUrl) { + Integer age, Tier tier, UserRole role, boolean isDeleted, boolean verified, String githubUrl, boolean gitPushStatus) { this.email = email; this.password = password; this.username = username; @@ -140,6 +143,7 @@ public User(String email, String password, String username, String nickname, this.isDeleted = isDeleted; this.verified = verified; this.githubUrl = githubUrl; + this.gitPushStatus = gitPushStatus; } /* @@ -181,9 +185,6 @@ public void setGithubUrl(String githubUrl){ this.githubUrl = githubUrl; } - public void setGithubAccessToken(String githubAccessToken){ - this.githubAccessToken = githubAccessToken; - } public void decreaseReviewToken() { this.reviewToken -= 1; diff --git a/src/main/java/org/ezcode/codetest/domain/user/model/entity/UserFactory.java b/src/main/java/org/ezcode/codetest/domain/user/model/entity/UserFactory.java index 68d84c48..5eb316c3 100644 --- a/src/main/java/org/ezcode/codetest/domain/user/model/entity/UserFactory.java +++ b/src/main/java/org/ezcode/codetest/domain/user/model/entity/UserFactory.java @@ -12,7 +12,8 @@ public static User createSocialUser( ) { //나중에 확장성 고려해서 switch문 사용 return switch (provider.toLowerCase()) { - case "github" -> User.githubUser( + case "github" -> + User.githubUser( response.getEmail(), response.getName(), nickname, diff --git a/src/main/java/org/ezcode/codetest/domain/user/model/entity/UserGithubInfo.java b/src/main/java/org/ezcode/codetest/domain/user/model/entity/UserGithubInfo.java new file mode 100644 index 00000000..0735665d --- /dev/null +++ b/src/main/java/org/ezcode/codetest/domain/user/model/entity/UserGithubInfo.java @@ -0,0 +1,53 @@ +package org.ezcode.codetest.domain.user.model.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@Table(name = "user_github") +@NoArgsConstructor +public class UserGithubInfo { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", unique = true) + private User user; + + @Column(nullable = false) + private String owner; + + private String repo; + + private String branch; + + private String githubAccessToken; + + @Builder + public UserGithubInfo(User user, String owner) { + this.user = user; + this.owner = owner; + } + + public void setGithubAccessToken(String githubAccessToken){ + this.githubAccessToken = githubAccessToken; + } + + public void setGithubRepo(String githubRepoName, String defaultBranch) { + this.repo = githubRepoName; + this.branch = defaultBranch; + } +} diff --git a/src/main/java/org/ezcode/codetest/domain/user/repository/UserGithubInfoRepository.java b/src/main/java/org/ezcode/codetest/domain/user/repository/UserGithubInfoRepository.java new file mode 100644 index 00000000..9871e1b3 --- /dev/null +++ b/src/main/java/org/ezcode/codetest/domain/user/repository/UserGithubInfoRepository.java @@ -0,0 +1,13 @@ +package org.ezcode.codetest.domain.user.repository; + +import org.ezcode.codetest.domain.user.model.entity.UserGithubInfo; + +public interface UserGithubInfoRepository { + void createUserGithubInfo(UserGithubInfo userGithubInfo); + + UserGithubInfo getUserGithubInfo(Long id); + + void updateGithubAccessToken(UserGithubInfo userGithubInfo); + + void updateGithubInfo(UserGithubInfo userGithub); +} diff --git a/src/main/java/org/ezcode/codetest/domain/user/repository/UserRepository.java b/src/main/java/org/ezcode/codetest/domain/user/repository/UserRepository.java index 590629ca..9eea7b4d 100644 --- a/src/main/java/org/ezcode/codetest/domain/user/repository/UserRepository.java +++ b/src/main/java/org/ezcode/codetest/domain/user/repository/UserRepository.java @@ -21,4 +21,5 @@ public interface UserRepository { void updateReviewTokens(List ids , int newToken); void updateUserGithubAccessToken(User loginUser); + } diff --git a/src/main/java/org/ezcode/codetest/domain/user/service/CustomOAuth2UserService.java b/src/main/java/org/ezcode/codetest/domain/user/service/CustomOAuth2UserService.java index 5825d785..f70aaecf 100644 --- a/src/main/java/org/ezcode/codetest/domain/user/service/CustomOAuth2UserService.java +++ b/src/main/java/org/ezcode/codetest/domain/user/service/CustomOAuth2UserService.java @@ -5,10 +5,13 @@ import org.ezcode.codetest.application.usermanagement.user.dto.response.GithubOAuth2Response; import org.ezcode.codetest.application.usermanagement.user.dto.response.GoogleOAuth2Response; import org.ezcode.codetest.application.usermanagement.user.dto.response.OAuth2Response; +import org.ezcode.codetest.domain.user.exception.UserException; +import org.ezcode.codetest.domain.user.exception.code.UserExceptionCode; import org.ezcode.codetest.domain.user.model.entity.CustomOAuth2User; import org.ezcode.codetest.domain.user.model.entity.User; import org.ezcode.codetest.domain.user.model.entity.UserAuthType; import org.ezcode.codetest.domain.user.model.entity.UserFactory; +import org.ezcode.codetest.domain.user.model.entity.UserGithubInfo; import org.ezcode.codetest.domain.user.model.enums.AuthType; import org.ezcode.codetest.domain.user.repository.UserAuthTypeRepository; import org.ezcode.codetest.domain.user.repository.UserRepository; @@ -30,6 +33,7 @@ public class CustomOAuth2UserService extends DefaultOAuth2UserService { private final UserRepository userRepository; private final UserAuthTypeRepository userAuthTypeRepository; private final UserDomainService userDomainService; + private final UserGithubService userGithubService; @Override @Transactional @@ -75,6 +79,7 @@ private void processUser( updateExistingUser(user, response, authType, provider); } } + private void createNewUser(OAuth2Response response, AuthType authType, String provider) { String nickname = userDomainService.generateUniqueNickname(); User newUser = UserFactory.createSocialUser(response, nickname, provider); @@ -82,6 +87,7 @@ private void createNewUser(OAuth2Response response, AuthType authType, String pr newUser.setReviewToken(20); userRepository.createUser(newUser); userAuthTypeRepository.createUserAuthType(new UserAuthType(newUser, authType)); + updateGithubUrl(newUser, response, provider); } private void updateExistingUser(User user, OAuth2Response response, AuthType authType, String provider) { @@ -95,8 +101,21 @@ private void updateExistingUser(User user, OAuth2Response response, AuthType aut } } private void updateGithubUrl(User user, OAuth2Response response, String provider) { - if ("github".equals(provider) && user.getGithubUrl()==null) { + if ("github".equals(provider)) { user.setGithubUrl(response.getGithubUrl()); + + UserGithubInfo userGithubInfo = + UserGithubInfo.builder() + .owner(response.getOwner()) + .user(user) + .build(); + + try { + userGithubService.createUserGithubInfo(userGithubInfo); + } catch (Exception e) { + throw new UserException(UserExceptionCode.NO_GITHUB_INFO); + } + } } diff --git a/src/main/java/org/ezcode/codetest/domain/user/service/UserDomainService.java b/src/main/java/org/ezcode/codetest/domain/user/service/UserDomainService.java index 95698f78..b64ee7af 100644 --- a/src/main/java/org/ezcode/codetest/domain/user/service/UserDomainService.java +++ b/src/main/java/org/ezcode/codetest/domain/user/service/UserDomainService.java @@ -7,6 +7,7 @@ import org.ezcode.codetest.domain.user.exception.UserException; import org.ezcode.codetest.domain.user.exception.code.UserExceptionCode; import org.ezcode.codetest.domain.user.model.entity.UserAuthType; +import org.ezcode.codetest.domain.user.model.entity.UserGithubInfo; import org.ezcode.codetest.domain.user.model.enums.Adjective; import org.ezcode.codetest.domain.user.model.enums.AuthType; import org.ezcode.codetest.domain.user.model.enums.Noun; @@ -14,6 +15,7 @@ import org.ezcode.codetest.domain.user.exception.code.AuthExceptionCode; import org.ezcode.codetest.domain.user.model.entity.User; import org.ezcode.codetest.domain.user.repository.UserAuthTypeRepository; +import org.ezcode.codetest.domain.user.repository.UserGithubInfoRepository; import org.ezcode.codetest.domain.user.repository.UserRepository; import org.ezcode.codetest.common.security.util.PasswordEncoder; import org.springframework.stereotype.Service; @@ -30,6 +32,7 @@ public class UserDomainService { private final UserRepository userRepository; private final UserAuthTypeRepository userAuthTypeRepository; + private final UserGithubInfoRepository userGithubInfoRepository; private final PasswordEncoder passwordEncoder; private static final java.util.Random RANDOM = new java.util.Random(); @@ -128,8 +131,5 @@ public User getUserByEmail(String email) { return userRepository.getUserByEmail(email); } - public void updateUserGithubAccessToken(User loginUser) { - log.info("Updating github access token for user: {}", loginUser); - userRepository.updateUserGithubAccessToken(loginUser); - } + } diff --git a/src/main/java/org/ezcode/codetest/domain/user/service/UserGithubService.java b/src/main/java/org/ezcode/codetest/domain/user/service/UserGithubService.java new file mode 100644 index 00000000..60782368 --- /dev/null +++ b/src/main/java/org/ezcode/codetest/domain/user/service/UserGithubService.java @@ -0,0 +1,107 @@ +package org.ezcode.codetest.domain.user.service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.ezcode.codetest.application.usermanagement.user.dto.request.UserGithubRepoSelectRequest; +import org.ezcode.codetest.application.usermanagement.user.dto.response.UserGithubRepoResponse; +import org.ezcode.codetest.common.security.util.AESUtil; +import org.ezcode.codetest.domain.user.exception.UserException; +import org.ezcode.codetest.domain.user.exception.code.UserExceptionCode; +import org.ezcode.codetest.domain.user.model.entity.AuthUser; +import org.ezcode.codetest.domain.user.model.entity.UserGithubInfo; +import org.ezcode.codetest.domain.user.repository.UserGithubInfoRepository; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; +import org.springframework.web.reactive.function.client.WebClient; + +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import reactor.core.publisher.Mono; + +@Service +@RequiredArgsConstructor +public class UserGithubService { + private final UserGithubInfoRepository userGithubInfoRepository; + private final WebClient githubWebClient; + private final AESUtil aesUtil; + + + public void updateUserGithubAccessToken(UserGithubInfo userGithubInfo) { + userGithubInfoRepository.updateGithubAccessToken(userGithubInfo); + } + + public void createUserGithubInfo(UserGithubInfo userGithubInfo) { + userGithubInfoRepository.createUserGithubInfo(userGithubInfo); + } + + public UserGithubInfo getUserGithubInfoById(Long id) { + return userGithubInfoRepository.getUserGithubInfo(id); + } + + + @Transactional + public List getGithubRepos(AuthUser authUser) throws Exception { + // 1. 사용자 accessToken 가져오기 + UserGithubInfo userGithub = userGithubInfoRepository.getUserGithubInfo(authUser.getId()); + + if (userGithub == null) { + throw new UserException(UserExceptionCode.NO_GITHUB_INFO); + } + + String accessToken = aesUtil.decrypt(userGithub.getGithubAccessToken()); + + // 2. WebClient로 GitHub API 호출 + return githubWebClient.get() + .uri("/user/repos") + .headers(headers -> { + headers.setBearerAuth(accessToken); + headers.setAccept(List.of(MediaType.APPLICATION_JSON)); + }) + .retrieve() + // .onStatus( + // status -> status == HttpStatus.BAD_REQUEST, // 상태 코드 조건 + // response -> Mono.error(new UserException(UserExceptionCode.NO_GITHUB_INFO)) + // ) + .onStatus( + status -> status.is4xxClientError() || status.is5xxServerError(), + response -> response.bodyToMono(String.class) + .flatMap(errorBody -> Mono.error(new Exception( //UserException 대신 github 문구 받아오게 수정 + "GitHub API 오류: " + response.statusCode() + " - " + errorBody + ))) + ) + .bodyToMono(new ParameterizedTypeReference>>() {}) + .block() + .stream() + .map(repo -> new UserGithubRepoResponse( + repo.get("name").toString(), + repo.get("default_branch").toString() + )) + .collect(Collectors.toList()); + } + + @Transactional + public UserGithubRepoResponse selectGithubRepo(AuthUser authUser, UserGithubRepoSelectRequest request) throws + Exception { + UserGithubInfo userGithub = userGithubInfoRepository.getUserGithubInfo(authUser.getId()); + + if (userGithub == null) { + throw new UserException(UserExceptionCode.NO_GITHUB_INFO); + } + + List repos = getGithubRepos(authUser); + + UserGithubRepoResponse selectedRepo = repos.stream() + .filter(repo -> repo.getRepoName().equals(request.repositoryName())) + .findFirst() + .orElseThrow(() -> new UserException(UserExceptionCode.NO_GITHUB_REPO)); + + userGithub.setGithubRepo(request.repositoryName(), selectedRepo.getDefaultBranch()); + userGithubInfoRepository.updateGithubInfo(userGithub); + + return selectedRepo; + } +} diff --git a/src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserGithubInfoJpaRepository.java b/src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserGithubInfoJpaRepository.java new file mode 100644 index 00000000..84e242b9 --- /dev/null +++ b/src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserGithubInfoJpaRepository.java @@ -0,0 +1,13 @@ +package org.ezcode.codetest.infrastructure.persistence.repository.user; + +import org.ezcode.codetest.domain.user.model.entity.User; +import org.ezcode.codetest.domain.user.model.entity.UserGithubInfo; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface UserGithubInfoJpaRepository extends JpaRepository { + UserGithubInfo findUserGithubInfoByUser(User user); + + UserGithubInfo findUserGithubInfoByUser_Id(Long userId); +} diff --git a/src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserGithubInfoRepositoryImpl.java b/src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserGithubInfoRepositoryImpl.java new file mode 100644 index 00000000..d41c5360 --- /dev/null +++ b/src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserGithubInfoRepositoryImpl.java @@ -0,0 +1,33 @@ +package org.ezcode.codetest.infrastructure.persistence.repository.user; + +import org.ezcode.codetest.domain.user.model.entity.UserGithubInfo; +import org.ezcode.codetest.domain.user.repository.UserGithubInfoRepository; +import org.springframework.stereotype.Repository; + +import lombok.RequiredArgsConstructor; + +@Repository +@RequiredArgsConstructor +public class UserGithubInfoRepositoryImpl implements UserGithubInfoRepository { + private final UserGithubInfoJpaRepository userGithubInfoJpaRepository; + + @Override + public void createUserGithubInfo(UserGithubInfo userGithubInfo) { + userGithubInfoJpaRepository.save(userGithubInfo); + } + + @Override + public UserGithubInfo getUserGithubInfo(Long userId) { + return userGithubInfoJpaRepository.findUserGithubInfoByUser_Id(userId); + } + + @Override + public void updateGithubAccessToken(UserGithubInfo userGithubInfo) { + userGithubInfoJpaRepository.save(userGithubInfo); + } + + @Override + public void updateGithubInfo(UserGithubInfo userGithub) { + userGithubInfoJpaRepository.save(userGithub); + } +} diff --git a/src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserRepositoryImpl.java b/src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserRepositoryImpl.java index 8976fd69..a9090b38 100644 --- a/src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserRepositoryImpl.java +++ b/src/main/java/org/ezcode/codetest/infrastructure/persistence/repository/user/UserRepositoryImpl.java @@ -4,6 +4,7 @@ import java.util.Optional; import org.ezcode.codetest.domain.user.model.entity.User; +import org.ezcode.codetest.domain.user.model.entity.UserGithubInfo; import org.ezcode.codetest.domain.user.repository.UserRepository; import org.springframework.stereotype.Repository; @@ -52,4 +53,6 @@ public void updateUserGithubAccessToken(User loginUser) { userJpaRepository.save(loginUser); } + + } diff --git a/src/main/java/org/ezcode/codetest/presentation/usermanagement/UserGithubController.java b/src/main/java/org/ezcode/codetest/presentation/usermanagement/UserGithubController.java new file mode 100644 index 00000000..f40b917f --- /dev/null +++ b/src/main/java/org/ezcode/codetest/presentation/usermanagement/UserGithubController.java @@ -0,0 +1,47 @@ +package org.ezcode.codetest.presentation.usermanagement; + +import java.util.List; + +import org.ezcode.codetest.application.usermanagement.user.dto.request.UserGithubRepoSelectRequest; +import org.ezcode.codetest.application.usermanagement.user.dto.response.UserGithubRepoResponse; +import org.ezcode.codetest.domain.user.model.entity.AuthUser; +import org.ezcode.codetest.domain.user.service.UserGithubService; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; + +@RestController +@RequestMapping("/api") +@RequiredArgsConstructor +@Tag(name = "깃허브 자동 push 관련 api", description = "자동 Push할 Repository 선택, 자동 Push 여부 선택") +public class UserGithubController { + + private final UserGithubService userGithubService; + + @Operation(summary = "GitHub 레포지토리 목록 조회", description = "사용자의 GitHub 레포지토리 목록을 조회합니다") + @GetMapping("/users/github") + public ResponseEntity> getGithubRepos( + @AuthenticationPrincipal AuthUser authUser + ) throws Exception { + return ResponseEntity.status(HttpStatus.OK).body(userGithubService.getGithubRepos(authUser)); + } + + @Operation(summary = "Repository 선택", description = "사용자의 Repository 중, 자동 push를 원하는 repo를 선택합니다") + @PostMapping("/users/github") + public ResponseEntity selectGithubRepo( + @AuthenticationPrincipal AuthUser authUser, + @Valid @RequestBody UserGithubRepoSelectRequest reqeust + ) throws Exception { + return ResponseEntity.status(HttpStatus.OK).body(userGithubService.selectGithubRepo(authUser, reqeust)); + } +}