Skip to content

Commit

Permalink
Misison, Step, PR 엔티티 설계 및 PR 조회 기능 (#12)
Browse files Browse the repository at this point in the history
* feat: 깃허브 인증 및 PR 조회 기능

* refactor: PasswordEncoder 패키지 변경

* chore: env file 제거

* fix: 환경변수 값이 바인딩 되지 않는 문제

* feat: 로그인 기능

* fix: PR List 조회 기능 UnAuthorized 문제

* fix: Auth ArgumentResolver 등록 안되는 문제

* refactor: 레포별 모든 PR 조회 기능 컨트롤러 변경

* refactor: 변수 final 키워드 추가

* refactor: jwt payload memberId로 변경

* fix: Querydsl Qclass 빌드 문제

* feat: 현재 로그인한 유저의 미션에 대한 모든 PullRequest 조회

* feat: 레파지토리 이름을 입력 받으면 해당 레포지토리에 있는 로그인한 유저의 PR들을 동기화한다.

* refactor: api path 소유격에서 소유대명사로 수정

* refactor: 동기화시 이미 존재하는 PR이라면 최신 정보로 수정만, 존재하지 않는다면 PR 생성

* refactor: 메서드명 수정

* refactor: GithubClientApi 상수 클래스로 관리

* refactor: Client 통신용 DTO 분리

* refactor: 문자열 포맷팅은 Constants 클래스에서 담당한다.

* refactor: PR 동기화시 존재하지 않는 PR만 저장한다.

* docs: 리팩터링 TODO

* refactor: 토큰 발급 메서드명 변경

* chore: 메서드 개행

* chore: 필드 개행

* chore: 이메일 레디스 해쉬 삭제

* refactor: DTO 이름 통일

* refactor: JsonNaming 사용

* chore: final 키워드 추가

* chore: 리팩터링 TODO

* chore: 메서드 개행

* chore: 사용하지 않는 import 제거

* fix: QClass 필드명 수정

* refactor: 토큰 조회시 token type이랑 같이 조회

* refactor: Type Enum 분리

* refactor: passwordEncoder 파라미터 이름 변경
  • Loading branch information
wonyongChoi05 authored Oct 8, 2023
1 parent 2e495a0 commit 939d184
Show file tree
Hide file tree
Showing 82 changed files with 1,315 additions and 433 deletions.
12 changes: 12 additions & 0 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 0 additions & 8 deletions .idea/modules.xml

This file was deleted.

8 changes: 0 additions & 8 deletions .idea/modules/techhub.main.iml

This file was deleted.

1 change: 1 addition & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

167 changes: 89 additions & 78 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id 'java'
id 'jacoco'
// id 'jacoco'
id 'org.springframework.boot' version '3.1.3'
id 'io.spring.dependency-management' version '1.1.3'
}
Expand All @@ -12,9 +12,9 @@ java {
sourceCompatibility = '17'
}

jacoco {
toolVersion = "0.8.8"
}
//jacoco {
// toolVersion = "0.8.8"
//}

configurations {
compileOnly {
Expand All @@ -30,6 +30,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
implementation 'org.mindrot:jbcrypt:0.4'

//redis
Expand All @@ -41,6 +42,11 @@ dependencies {
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'

// JWT
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'

// Mail
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
Expand All @@ -62,6 +68,7 @@ tasks.named('test') {
}

def generated = 'build/generated'
def application = 'src/main/generated'

tasks.withType(JavaCompile) {
options.getGeneratedSourceOutputDirectory().set(file(generated))
Expand All @@ -71,84 +78,88 @@ sourceSets {
main.java.srcDirs += [generated]
}

clean {
task customClean(type: Delete) {
delete file(generated)
delete file(application)
}

jacocoTestReport {
reports {
html.required = true

html.destination file("${buildDir}/jacoco/index.html")
}

afterEvaluate {
classDirectories.setFrom(
files(classDirectories.files.collect {
fileTree(dir: it, excludes: [
'**/*Application*',
'**/*Exception*',
'**/*Response*',
'**/*Request*',
'**/BaseTimeEntity',
'**/*Dto*',
'**/S3*',
'**/*Interceptor*',
'**/*ArgumentResolver*',
'**/*ExceptionHandler*',
'**/LoggingUtils',
'**/*Url*',
'**/*AdminController*',
'**/*Config*',
'**/*Wrapper*'
])
})
)
}

finalizedBy 'jacocoTestCoverageVerification'
}

jacocoTestCoverageVerification {
def Qdomains = []

for (qPattern in '*.QA'..'*.QZ') { // qPattern = '*.QA', '*.QB', ... '*.QZ'
Qdomains.add(qPattern + '*')
}

violationRules {
rule {
enabled = true
element = "CLASS"

limit {
counter = 'LINE'
value = 'COVEREDRATIO'
minimum = 0.7
}

excludes = [
'*.*Application',
'*.*Exception*',
'*.*Dto',
'*.S3*',
'*.*Response',
'*.*Request',
'*.BaseTimeEntity',
'*.*Interceptor',
'*.*ArgumentResolver',
'*.*ExceptionHandler',
'*.LoggingUtils',
'*.*Url',
'*.*AdminController',
'*.*Config',
'*.*Wrapper'
] + Qdomains
}
}
}
clean.dependsOn customClean


//jacocoTestReport {
// reports {
// html.required = true
//
// html.destination file("${buildDir}/jacoco/index.html")
// }
//
// afterEvaluate {
// classDirectories.setFrom(
// files(classDirectories.files.collect {
// fileTree(dir: it, excludes: [
// '**/*Application*',
// '**/*Exception*',
// '**/*Response*',
// '**/*Request*',
// '**/BaseTimeEntity',
// '**/*Dto*',
// '**/S3*',
// '**/*Interceptor*',
// '**/*ArgumentResolver*',
// '**/*ExceptionHandler*',
// '**/LoggingUtils',
// '**/*Url*',
// '**/*AdminController*',
// '**/*Config*',
// '**/*Wrapper*'
// ])
// })
// )
// }
//
// finalizedBy 'jacocoTestCoverageVerification'
//}

//jacocoTestCoverageVerification {
// def Qdomains = []
//
// for (qPattern in '*.QA'..'*.QZ') { // qPattern = '*.QA', '*.QB', ... '*.QZ'
// Qdomains.add(qPattern + '*')
// }
//
// violationRules {
// rule {
// enabled = true
// element = "CLASS"
//
// limit {
// counter = 'LINE'
// value = 'COVEREDRATIO'
// minimum = 0.7
// }
//
// excludes = [
// '*.*Application',
// '*.*Exception*',
// '*.*Dto',
// '*.S3*',
// '*.*Response',
// '*.*Request',
// '*.BaseTimeEntity',
// '*.*Interceptor',
// '*.*ArgumentResolver',
// '*.*ExceptionHandler',
// '*.LoggingUtils',
// '*.*Url',
// '*.*AdminController',
// '*.*Config',
// '*.*Wrapper'
// ] + Qdomains
// }
// }
//}

test {
useJUnitPlatform()
finalizedBy 'jacocoTestReport'
// finalizedBy 'jacocoTestReport'
}
12 changes: 11 additions & 1 deletion docker/docker-compose.local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: '3'

services:
mysql:
container_name: techhub
container_name: mysql
image: mysql/mysql-server
environment:
MYSQL_DATABASE: techhub
Expand All @@ -16,3 +16,13 @@ services:
- "--character-set-server=utf8mb4"
- "--collation-server=utf8mb4_unicode_ci"

redis:
container_name: redis
image: redis:alpine
command: redis-server --port 6379
hostname: localhost
labels:
- "name=redis"
- "mode=standalone"
ports:
- 16379:6379
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.integrated.techhub.auth.application;

import com.integrated.techhub.member.domain.repository.MemberRepository;
import com.integrated.techhub.member.exception.MemberExistsException;
import com.integrated.techhub.member.exception.MemberAlreadyExistsException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

Expand All @@ -13,7 +13,7 @@ public class AuthQueryService {

public void validateExistedMember(final String email) {
if (memberRepository.existsByEmail(email)) {
throw new MemberExistsException();
throw new MemberAlreadyExistsException();
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package com.integrated.techhub.auth.application;

import com.integrated.techhub.auth.domain.AccessToken;
import com.integrated.techhub.auth.domain.PasswordEncoder;
import com.integrated.techhub.auth.dto.SignUpRequest;
import com.integrated.techhub.auth.domain.RefreshToken;
import com.integrated.techhub.auth.domain.repository.AccessTokenRepository;
import com.integrated.techhub.auth.domain.repository.RefreshTokenRepository;
import com.integrated.techhub.auth.dto.request.SignUpRequest;
import com.integrated.techhub.auth.dto.response.TokenResponse;
import com.integrated.techhub.common.auth.jwt.JwtProvider;
import com.integrated.techhub.member.domain.Member;
import com.integrated.techhub.member.domain.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
Expand All @@ -13,15 +19,30 @@
@RequiredArgsConstructor
public class AuthService {

private final JwtProvider jwtProvider;
private final MemberRepository memberRepository;
private final AuthQueryService authQueryService;
private final PasswordEncoder passwordEncoder;
private final AccessTokenRepository accessTokenRepository;
private final RefreshTokenRepository refreshTokenRepository;

public Long registerMember(final SignUpRequest request) {
authQueryService.validateExistedMember(request.email());
Member member = request.toEntity();
final Member member = request.toEntity();
member.encodePassword(passwordEncoder);
return memberRepository.save(member).getId();
}

public TokenResponse getTokens(final String email, final String password) {
final Member member = memberRepository.getByEmail(email);
member.validateMatchPassword(passwordEncoder, password);
final String accessToken = jwtProvider.generateAccessToken(member.getId());
final String refreshToken = jwtProvider.generateRefreshToken(member.getId()).getToken();
return new TokenResponse(accessToken, refreshToken);
}

public void saveGithubTokens(final AccessToken accessToken, final RefreshToken refreshToken) {
accessTokenRepository.save(accessToken);
refreshTokenRepository.save(refreshToken);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.integrated.techhub.auth.application.client;

import com.integrated.techhub.auth.application.client.dto.response.GithubPrInfoResponse;
import com.integrated.techhub.auth.application.client.dto.response.OAuthGithubUsernameResponse;
import com.integrated.techhub.auth.application.client.dto.response.OAuthTokensResponse;

import java.util.List;

public interface GithubClient {

OAuthTokensResponse getGithubTokens(final String code);

OAuthTokensResponse getNewAccessToken(final String refreshToken);

OAuthGithubUsernameResponse getGithubUsername(final String accessToken);

List<GithubPrInfoResponse> getPrsByRepoName(final String accessToken, final String repo);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.integrated.techhub.auth.application.client;


import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "spring.security.oauth2.client.registration.github")
public record GithubClientProperties (
String clientId,
String clientSecret
) {
}
Loading

0 comments on commit 939d184

Please sign in to comment.