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 all 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,58 @@
package com.gdschongik.gdsc.infra.github;

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

import com.gdschongik.gdsc.global.exception.CustomException;
import com.gdschongik.gdsc.global.exception.ErrorCode;
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 GithubUserRequest 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 CustomException(ErrorCode.INTERNAL_SERVER_ERROR);
}
}

@Override
public boolean hasBody() {
return false;
}
}
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.GithubUserRequest;
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.GitHubConnector;
import org.kohsuke.github.connector.GitHubConnectorResponse;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class GithubClient {

private final GitHub github;
private final GitHubConnector gitHubConnector = GitHubConnector.DEFAULT;

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 = gitHubConnector.send(new GithubUserRequest(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