Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 마이페이지 계정정보 조회 API 추가 #672

Merged
merged 5 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.gdschongik.gdsc.domain.member.api;

import com.gdschongik.gdsc.domain.member.application.CommonMemberService;
import com.gdschongik.gdsc.domain.member.dto.response.MemberAccountInfoResponse;
import com.gdschongik.gdsc.domain.member.dto.response.MemberDepartmentResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand Down Expand Up @@ -34,4 +35,11 @@ public ResponseEntity<List<MemberDepartmentResponse>> searchDepartments(
List<MemberDepartmentResponse> response = commonMemberService.searchDepartments(departmentName);
return ResponseEntity.ok().body(response);
}

@Operation(summary = "내 계정 정보 조회", description = "내 계정 정보를 조회합니다.")
@GetMapping("/me/account-info")
public ResponseEntity<MemberAccountInfoResponse> getAccountInfo() {
MemberAccountInfoResponse response = commonMemberService.getAccountInfo();
return ResponseEntity.ok().body(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
import com.gdschongik.gdsc.domain.member.dao.MemberRepository;
import com.gdschongik.gdsc.domain.member.domain.Department;
import com.gdschongik.gdsc.domain.member.domain.Member;
import com.gdschongik.gdsc.domain.member.dto.response.MemberAccountInfoResponse;
import com.gdschongik.gdsc.domain.member.dto.response.MemberDepartmentResponse;
import com.gdschongik.gdsc.domain.membership.dao.MembershipRepository;
import com.gdschongik.gdsc.domain.membership.domain.Membership;
import com.gdschongik.gdsc.global.exception.CustomException;
import com.gdschongik.gdsc.global.util.MemberUtil;
import com.gdschongik.gdsc.infra.github.client.GithubClient;
import java.util.Arrays;
import java.util.List;
import lombok.RequiredArgsConstructor;
Expand All @@ -23,6 +26,8 @@ public class CommonMemberService {

private final MembershipRepository membershipRepository;
private final MemberRepository memberRepository;
private final MemberUtil memberUtil;
private final GithubClient githubClient;

@Transactional(readOnly = true)
public List<MemberDepartmentResponse> getDepartments() {
Expand Down Expand Up @@ -81,4 +86,11 @@ public void demoteMemberToAssociateByMembership(Long membershipId) {

log.info("[CommonMemberService] 준회원 강등 완료: memberId={}", member.getId());
}

@Transactional(readOnly = true)
public MemberAccountInfoResponse getAccountInfo() {
Member currentMember = memberUtil.getCurrentMember();
String githubHandle = githubClient.getGithubHandle(currentMember.getOauthId());
return MemberAccountInfoResponse.of(currentMember, githubHandle);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.gdschongik.gdsc.domain.member.dto.response;

import com.gdschongik.gdsc.domain.member.domain.Member;

public record MemberAccountInfoResponse(String name, String githubHandle) {
public static MemberAccountInfoResponse of(Member member, String githubHandle) {
return new MemberAccountInfoResponse(member.getName(), githubHandle);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public class GithubConstant {

public static final String GITHUB_DOMAIN = "github.com/";
public static final String GITHUB_ASSIGNMENT_PATH = "week%d/WIL.md";
public static final String GITHUB_USER_API_URL = "https://api.github.com/user/%s";

private GithubConstant() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ public enum ErrorCode {
GITHUB_CONTENT_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 파일입니다."),
GITHUB_FILE_READ_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "깃허브 파일 읽기에 실패했습니다."),
GITHUB_COMMIT_DATE_FETCH_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "깃허브 커밋 날짜 조회에 실패했습니다."),
GITHUB_USER_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 깃허브 유저입니다."),
;
private final HttpStatus status;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.gdschongik.gdsc.infra.github;

import static com.gdschongik.gdsc.global.common.constant.GithubConstant.*;

import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.kohsuke.github.connector.GitHubConnectorRequest;

@RequiredArgsConstructor
public class GithubHandleRequest implements GitHubConnectorRequest {

private final String oauthId;

@Override
public String method() {
return "GET";
}

@Override
public Map<String, List<String>> allHeaders() {
return Map.of();
}

@Override
public String header(String s) {
return "";
}

@Override
public String contentType() {
return "";
}

@Override
public InputStream body() {
return null;
}

@Override
public URL url() {
try {
return new URL(GITHUB_USER_API_URL.formatted(oauthId));
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
Sangwook02 marked this conversation as resolved.
Show resolved Hide resolved
}

@Override
public boolean hasBody() {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.gdschongik.gdsc.infra.github;

import java.io.IOException;
import org.kohsuke.github.connector.GitHubConnector;
import org.kohsuke.github.connector.GitHubConnectorRequest;
import org.kohsuke.github.connector.GitHubConnectorResponse;
import org.springframework.stereotype.Component;

@Component
public class GithubHttpConnector implements GitHubConnector {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

라이브러리 잠깐 살펴봤는데요, GithubConnector를 implements 하여 DI하지 않고, 그냥 GithubClient 에서 바로 DEFAULT 구현체로 초기화해버리면 될 것 같은데 어떻게 생각하시나요?

private final GitHubConnector githubConnector = GitHubConnector.DEFAULT;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그렇네요.
특별한 구현 없으니 이게 더 간단하고 깔끔할 것 같네요.
반영할게요!

@Override
public GitHubConnectorResponse send(GitHubConnectorRequest gitHubConnectorRequest) throws IOException {
return DEFAULT.send(gitHubConnectorRequest);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,32 @@
import static com.gdschongik.gdsc.global.common.constant.GithubConstant.*;
import static com.gdschongik.gdsc.global.exception.ErrorCode.*;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.gdschongik.gdsc.domain.study.domain.AssignmentSubmission;
import com.gdschongik.gdsc.domain.study.domain.AssignmentSubmissionFetchExecutor;
import com.gdschongik.gdsc.domain.study.domain.AssignmentSubmissionFetcher;
import com.gdschongik.gdsc.global.exception.CustomException;
import com.gdschongik.gdsc.infra.github.GithubHandleRequest;
import com.gdschongik.gdsc.infra.github.GithubHttpConnector;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.kohsuke.github.GHCommit;
import org.kohsuke.github.GHContent;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;
import org.kohsuke.github.connector.GitHubConnectorResponse;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class GithubClient {

private final GitHub github;
private final GithubHttpConnector githubHttpConnector;

public GHRepository getRepository(String ownerRepo) {
try {
Expand All @@ -32,6 +38,16 @@ public GHRepository getRepository(String ownerRepo) {
}
}

public String getGithubHandle(String oauthId) {
try (GitHubConnectorResponse response = githubHttpConnector.send(new GithubHandleRequest(oauthId));
InputStream inputStream = response.bodyStream(); ) {
// api가 login이라는 이름으로 사용자의 github handle을 반환합니다.
return (String) new ObjectMapper().readValue(inputStream, Map.class).get("login");
} catch (IOException e) {
throw new CustomException(GITHUB_USER_NOT_FOUND);
}
}

/**
* 직접 요청을 수행하는 대신, fetcher를 통해 요청을 수행합니다.
* 요청 수행 시 발생하는 예외의 경우 과제 채점에 사용되므로, 실제 요청은 채점 로직 내부에서 수행되어야 합니다.
Expand Down