Skip to content
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
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ dependencies {
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.12.6")
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.12.6")

// WebClient
implementation ("org.springframework.boot:spring-boot-starter-webflux")
}

tasks.withType<Test> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package cmf.commitField.domain.totalCommit.config;

import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

// CORS 오류 설정 용
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8090") // 프론트엔드 도메인
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package cmf.commitField.domain.totalCommit.controller;

import cmf.commitField.domain.totalCommit.dto.TotalCommitResponseDto;
import cmf.commitField.domain.totalCommit.service.TotalCommitService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class TotalCommitController {
private final TotalCommitService totalCommitService;

@GetMapping("/api/commits/{username}")
public TotalCommitResponseDto getTotalCommits(@PathVariable String username) {
return totalCommitService.getTotalCommitCount(username);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package cmf.commitField.domain.totalCommit.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;

/*
응답구조 토대로 구현
{
"data": {
"user": {
"contributionsCollection": {
"totalCommitContributions": 116,
"restrictedContributionsCount": 0
}
}
}
}
*/
@Getter
@NoArgsConstructor
public class TotalCommitGraphQLResponse {
private Data data;

@Getter
@NoArgsConstructor
public static class Data {
CommitUser user;
}


@Getter
@NoArgsConstructor
public static class CommitUser {
private ContributionsCollection contributionsCollection;
}

@Getter
@NoArgsConstructor
public static class ContributionsCollection {
private long totalCommitContributions;
private long restrictedContributionsCount;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package cmf.commitField.domain.totalCommit.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class TotalCommitResponseDto {
private long totalCommitContributions;
private long restrictedContributionsCount;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package cmf.commitField.domain.totalCommit.service;

import cmf.commitField.domain.totalCommit.dto.TotalCommitGraphQLResponse;
import cmf.commitField.domain.totalCommit.dto.TotalCommitResponseDto;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;

import java.util.Map;


@Service
@RequiredArgsConstructor
public class TotalCommitService {
private static final String BASE_URL = "https://api.github.com/graphql";

@Value("${github.token}")
private String PAT;


private final WebClient webClient = WebClient.builder()
.baseUrl(BASE_URL)
.defaultHeader(HttpHeaders.CONTENT_TYPE , MediaType.APPLICATION_JSON_VALUE)
.build();

public TotalCommitResponseDto getTotalCommitCount(String username) {
// String query = String.format("""
// {"query": "query { user(login: \\\"%s\\\") { contributionsCollection { totalCommitContributions restrictedContributionsCount } } }"}
// """, username);
// GraphQL 쿼리를 Map으로 구성
Map<String, String> requestBody = Map.of(
"query", String.format(
"query { user(login: \"%s\") { contributionsCollection { totalCommitContributions restrictedContributionsCount } } }",
username
)
);

TotalCommitGraphQLResponse response = webClient.post()
.header("Authorization", "bearer " + PAT)
.bodyValue(requestBody)
.retrieve()
.bodyToMono(TotalCommitGraphQLResponse.class)
.block();

TotalCommitGraphQLResponse.ContributionsCollection contributions = response.getData().getUser().getContributionsCollection();

return new TotalCommitResponseDto(
contributions.getTotalCommitContributions(),
contributions.getRestrictedContributionsCount()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ public SecurityConfig(CustomOAuth2UserService customOAuth2UserService) {

@Bean
protected SecurityFilterChain config(HttpSecurity http) throws Exception {
// 권한 설정
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/actuator/**").permitAll() // actuator 엔드포인트 허용
.anyRequest().authenticated() // 그 외 모든 요청은 인증 필요
);

//로그인 관련 설정
http
.oauth2Login(oauth2 -> oauth2
Expand Down
16 changes: 15 additions & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,18 @@ spring:
name: "commit-field"
cookieDomain: "${custom.dev.cookieDomain}"
frontUrl: "${custom.dev.frontUrl}"
backUrl: "${custom.dev.backUrl}"
backUrl: "${custom.dev.backUrl}"

# swagger 설정
springdoc:
swagger-ui:
path: /api-test # swagger-ui 접근 경로에 대한 별칭, 해당 주소로 접속해도 http://localhost:8080/swagger-ui/index.html로 리다이렉션 됨.

groups-order: DESC # path, query, body, response 순으로 출력

tags-sorter: alpha # 태그를 알파벳 순으로 정렬

operations-sorter: method # delete - get - patch - post - put 순으로 정렬, alpha를 사용하면 알파벳 순으로 정렬 가능

# paths-to-match:
# - /api/** # swagger-ui에 표시할 api의 엔드포인트 패턴