Skip to content

Commit

Permalink
๐Ÿ› Fix: ๋กœ๊ทธ์ธ ์™„๋ฃŒ ์‹œ ๋ฉ”์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ๋˜๋„๋ก ์ˆ˜์ • (#7)
Browse files Browse the repository at this point in the history
* Feat: Member DB ์ˆ˜์ •

- ํ•œ๊ธ€์ด๋ฆ„, ์˜์–ด์ด๋ฆ„, ๊ธฐ์ˆ˜, ๊ณผ์ • ์ถ”๊ฐ€
- ๊ณผ์ • ํ‘œํ˜„ํ•˜๋Š” Enumerate ์ถ”๊ฐ€
- ์ˆ˜์ •์— ๋”ฐ๋ฅธ ์˜ค๋ฅ˜ ์ˆ˜์ •
  - getNickname -> getKoreaName of getEnglishName

Related to: #2

* Rename: Member DB Field ์ด๋ฆ„ ๋ณ€๊ฒฝ

Related to: #2

* Feat: /api/auth/member ๊ด€๋ จ DTO ์ž‘์„ฑ

Related to: #2

* Feat: /api/auth/member API ๊ด€๋ จ DTO ๋‚ด์šฉ ์ถ”๊ฐ€

Related to: #2

* Feat: /api/auth/member ๊ด€๋ จ MemberService ์ถ”๊ฐ€

Related to: #2

* Feat: /api/auth/member ๊ด€๋ จ MemberContoller ์ถ”๊ฐ€

Related to: #2

* Feat: CORS Error ์ˆ˜์ •

Related to: #2

* Fix: RefreshToken ๋งค๋ฒˆ ์ƒ์„ฑ ์˜ค๋ฅ˜ ์ˆ˜์ •

Related to: #2

* Refactor: ์ฝ”๋“œ ๋ฆฌ๋ทฐ ๋‚ด์šฉ ๋ฐ˜์˜

- ๋ถˆํ•„์š” ์ฝ”๋“œ ์‚ญ์ œ
- ๋ฐ˜ํ™˜๊ฐ’ ์˜ค๋ฅ˜ ์ˆ˜์ •

Related to: #2

* Test: MemberRepository Test ์ฝ”๋“œ ์ถ”๊ฐ€

Related to: #2

* Chore: Test์šฉ application yml ์ถ”๊ฐ€

Related to: #2

* ์นด์นด์˜ค ํšŒ์›๊ฐ€์ž…/๋กœ๊ทธ์ธ, /api/auth/member API ๊ธฐ๋Šฅ ์ถ”๊ฐ€ (#6)

* โœจ ์นด์นด์˜ค ๋กœ๊ทธ์ธ/ํšŒ์›๊ฐ€์ž… ๊ตฌํ˜„ (#3)

* Style: codeStyle ์ถ”๊ฐ€

* Feat: Member, Profile Entity, MemberRepository ์ถ”๊ฐ€

+ MemberRepositoryTest ์ถ”๊ฐ€

Related to: #1

* Feat: ์นด์นด์˜ค ๋กœ๊ทธ์ธ, ํšŒ์›๊ฐ€์ž… ๊ธฐ๋Šฅ ์ถ”๊ฐ€

- ๊ถŒํ•œ ํ•„์š”ํ•œ API ์ ‘์† ์‹œ ์นด์นด์˜ค ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ๋ฐ˜ํ™˜
  - ๋กœ๊ทธ์ธ ์„ฑ๊ณต ์‹œ ๊ฐ€์ž…์ด ์•ˆ๋˜์–ด์žˆ์œผ๋ฉด ๊ฐ€์ž…, ๋˜์–ด์žˆ์œผ๋ฉด ๊ถŒํ•œ ๋ถ€์—ฌ
  - ๊ถŒํ•œ์€ JWT ๋ฐœ๊ธ‰ ํ›„ ์ฟ ํ‚ค์— ์ถ”๊ฐ€, ๋งค ์š”์ฒญ๋งˆ๋‹ค JwtFilter๋ฅผ ๊ฑฐ์น˜๋ฉฐ ์ฟ ํ‚ค์˜ Jwt ํ™•

Related to: #1

* Style: ์ฝ”๋“œ ํฌ๋งท, ๋น„๋ฐ€๋ฒˆํ˜ธ ๋…ธ์ถœ ๋“ฑ ์ˆ˜์ •

Related to: #1

* โœจ /api/auth/member API ๊ธฐ๋Šฅ ์ถ”๊ฐ€ (#4)

* Feat: Member DB ์ˆ˜์ •

- ํ•œ๊ธ€์ด๋ฆ„, ์˜์–ด์ด๋ฆ„, ๊ธฐ์ˆ˜, ๊ณผ์ • ์ถ”๊ฐ€
- ๊ณผ์ • ํ‘œํ˜„ํ•˜๋Š” Enumerate ์ถ”๊ฐ€
- ์ˆ˜์ •์— ๋”ฐ๋ฅธ ์˜ค๋ฅ˜ ์ˆ˜์ •
  - getNickname -> getKoreaName of getEnglishName

Related to: #2

* Rename: Member DB Field ์ด๋ฆ„ ๋ณ€๊ฒฝ

Related to: #2

* Feat: /api/auth/member ๊ด€๋ จ DTO ์ž‘์„ฑ

Related to: #2

* Feat: /api/auth/member API ๊ด€๋ จ DTO ๋‚ด์šฉ ์ถ”๊ฐ€

Related to: #2

* Feat: /api/auth/member ๊ด€๋ จ MemberService ์ถ”๊ฐ€

Related to: #2

* Feat: /api/auth/member ๊ด€๋ จ MemberContoller ์ถ”๊ฐ€

Related to: #2

* Feat: CORS Error ์ˆ˜์ •

Related to: #2

* Fix: RefreshToken ๋งค๋ฒˆ ์ƒ์„ฑ ์˜ค๋ฅ˜ ์ˆ˜์ •

Related to: #2

* Refactor: ์ฝ”๋“œ ๋ฆฌ๋ทฐ ๋‚ด์šฉ ๋ฐ˜์˜

- ๋ถˆํ•„์š” ์ฝ”๋“œ ์‚ญ์ œ
- ๋ฐ˜ํ™˜๊ฐ’ ์˜ค๋ฅ˜ ์ˆ˜์ •

Related to: #2

* Chore: DB๋ฅผ MariaDB -> H2๋กœ ๋ณ€๊ฒฝ

Ralted to: #5

* Test: Test์šฉ application ์ถ”๊ฐ€

Related to: #5

* Feat: ๊นƒํ—ˆ๋ธŒ ์•ก์…˜ ์ž‘์„ฑ

Related to: #5

* Feat: ๋„์ปค ํŒŒ์ผ ์ž‘์„ฑ

Related to: #5

* Feat: ํ…Œ์ŠคํŠธ์šฉ ๋„์ปค ์ปดํฌ์ฆˆ ํŒŒ์ผ ์ž‘์„ฑ

Related to: #5

* Refactor: import ์ถ”๊ฐ€

* Fix: ๊นƒํ—ˆ๋ธŒ ์•ก์…˜ ์˜คํƒ€ ์ˆ˜์ •

Related to: #5

* Feat: SSL ์ ์šฉ

* Fix: SSL ์ˆ˜์ •

* Fix: SSL ์ˆ˜์ •

์Šคํฌ๋ฆฝํŠธ ์ˆ˜์ •

* Fix: SSL ์Šคํฌ๋ฆฝํŠธ ์ˆ˜์ •

* Fix: SSL ์Šคํฌ๋ฆฝํŠธ ์ˆ˜์ •

* Feat: ์นด์นด์˜ค ๋กœ๊ทธ์ธ ์™„๋ฃŒ ์‹œ ๋ฉ”์ธ ํŽ˜์ด์ง€๋กœ redirect

Related to: #1

---------

Co-authored-by: ๋ฐ•์ง€ํ˜ <[email protected]>
  • Loading branch information
Taejin1221 and pjh5365 authored Sep 8, 2024
1 parent 91a283f commit f12a0b4
Show file tree
Hide file tree
Showing 8 changed files with 191 additions and 4 deletions.
83 changes: 83 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Build and Push Docker Image and Deploy

# main, dev ๋ธŒ๋žœ์น˜์— push or PR ์ด ์˜ค๋ฉด ์‹คํ–‰
on:
push:
branches:
- main
- dev
pull_request:
branches:
- main
- dev

jobs:
# ๋„์ปค ์ด๋ฏธ์ง€ ๋นŒ๋“œ, ํ‘ธ์‹œ
build_and_push:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

# DB ์„ธํŒ… ์ •๋ณด ์ž…๋ ฅ
- name: Set up application.yml
run: |
echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.yml
echo "${{ secrets.APPLICATION_TEST }}" > ./src/main/resources/application-test.yml
# SSL ์ ์šฉ
- name: Create SSH Key File
run: echo "${{ secrets.PRIVATE_KEY }}" > /tmp/private_key.pem

- name: Set Permissions for SSH Key
run: chmod 600 /tmp/private_key.pem

- name: Copy keystore.p12 from EC2
run: scp -o StrictHostKeyChecking=no -i /tmp/private_key.pem ${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }}:/home/${{ secrets.EC2_USER }}/keystore.p12 ./src/main/resources/keystore.p12

# ๋„์ปค ์ด๋ฏธ์ง€ ๋นŒ๋“œ์šฉ ํ™˜๊ฒฝ ์„ธํŒ… ๋ฐ ๋„์ปค ์ด๋ฏธ์ง€ ๋นŒ๋“œ
- name: set up test DB and docker build
run: |
docker compose -f docker-compose-auth-test-db.yml up -d # ๋„์ปค ์ปดํฌ์ฆˆํŒŒ์ผ๋กœ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ์„ธํŒ…
DOCKER_BUILDKIT=0 docker build --network testNet -t ${{ secrets.DOCKER_IMAGE_NAME }}:latest . # ๋„์ปค ๋นŒ๋“œ (๋นŒ๋“œ ๊ณผ์ •์—์„œ ๋„คํŠธ์›Œํฌ ์‚ฌ์šฉ์„ ์œ„ํ•ด ๋นŒ๋“œํ‚ท 0)
docker compose -f docker-compose-auth-test-db.yml down # ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ์ œ๊ฑฐ (๋„คํŠธ์›Œํฌ๊นŒ์ง€ ์‚ญ์ œ๋จ)
# ๋„์ปค ๋กœ๊ทธ์ธ
- name: docker Login
uses: docker/[email protected]
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

# ๋„์ปค ์ด๋ฏธ์ง€ push
- name: push docker images
run: |
docker push ${{ secrets.DOCKER_IMAGE_NAME }}:latest
# ๋„์ปค ์ด๋ฏธ์ง€ EC2 ์ธ์Šคํ„ด์Šค์— ๋ฐฐํฌ
deploy_to_ec2:
needs: build_and_push
runs-on: ubuntu-24.04

steps:
- name: Deploy to EC2
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST }} # EC2 IP ์ฃผ์†Œ
username: ${{ secrets.EC2_USER }} # EC2 ์‚ฌ์šฉ์ž
key: ${{ secrets.PRIVATE_KEY }} # pem ํ‚ค

# ๊ธฐ์กด ์ปจํ…Œ์ด๋„ˆ ์ค‘์ง€
script: |
CONTAINER_ID=$(sudo docker ps -aq --filter "name=kaboo-auth")
if [ ! -z "$CONTAINER_ID" ]; then
sudo docker stop $CONTAINER_ID || true
sudo docker rm -f $CONTAINER_ID || true
fi
# ์ตœ์‹  ๋„์ปค ์ด๋ฏธ์ง€๋กœ ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰
sudo docker pull ${{ secrets.DOCKER_IMAGE_NAME }}:latest # ๋„์ปค ์ตœ์‹  ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ
# ๋„์ปค ์ด๋ฏธ์ง€ ์‹คํ–‰ (host.docker.internal ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋„๋ก)
docker run --name kaboo-auth -d --add-host host.docker.internal:host-gateway -p 8081:8081 ${{ secrets.DOCKER_IMAGE_NAME }}:latest
sudo docker image prune -f # ๊ตฌ๋ฒ„์ „์˜ ๋„์ปค ์ด๋ฏธ์ง€ ์ œ๊ฑฐ
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ fabric.properties

.idea/*

!.idea/codeStyles
!.idea/runConfigurations

### Java ###
Expand Down Expand Up @@ -174,7 +175,9 @@ gradle-app.setting
# Java heap dump
*.hprof

# End of https://www.toptal.com/developers/gitignore/api/java,gradle,macos,intellij+allauth.yml
oauth.yml
# End of https://www.toptal.com/developers/gitignore/api/java,gradle,macos,intellij+all
application.yml
application-test.yml
database.yml
jwt.yml
oauth.yml
14 changes: 14 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Build
FROM eclipse-temurin:17-jdk AS build
LABEL authors="pjh5365"

WORKDIR /src
COPY . /src
RUN ./gradlew build

# Run
FROM eclipse-temurin:17-jre
EXPOSE 8081
COPY --from=build /src/build/libs/*SNAPSHOT.jar kaboo-auth.jar

ENTRYPOINT ["java", "-jar", "kaboo-auth.jar"]
15 changes: 15 additions & 0 deletions docker-compose-auth-test-db.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# ํ…Œ์ŠคํŠธ DB ํ™˜๊ฒฝ ์„ธํŒ…
services:
redis:
image: redis:alpine
container_name: redis
ports:
- "6379:6379"
networks:
- testNet

networks:
testNet:
name: testNet # ๋„คํŠธ์›Œํฌ ์ด๋ฆ„ ์ง€์ •
driver: bridge # ๋ธŒ๋ฆฟ์ง€ ๋ชจ๋“œ
attachable: true # ์™ธ๋ถ€์ ‘์† ํ—ˆ์šฉ
2 changes: 1 addition & 1 deletion src/main/java/kaboo/kaboo_auth/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.oauth2Login(auth -> auth
.userInfoEndpoint(userInfoEndpointConfig -> userInfoEndpointConfig.userService(customOAuth2Service))
.successHandler(loginSuccessHandler));

return http.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.IOException;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
Expand All @@ -26,6 +27,9 @@ public class LoginSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
private final int accessTokenValidTime = 10 * 60; // ์œ ํšจ๊ธฐ๊ฐ„ : 10๋ถ„
private final int refreshTokenValidTime = 10 * 24 * 60 * 60; // ์œ ํšจ๊ธฐ๊ฐ„ : 10์ผ

@Value("${AUTH.REDIRECT_URL}")
String redirectURL;

private Cookie createCookie(String key, String value, int maxAge) {
Cookie cookie = new Cookie(key, value);
cookie.setMaxAge(maxAge);
Expand All @@ -49,6 +53,6 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo
response.addCookie(createCookie("Username", username, refreshTokenValidTime));
response.addCookie(createCookie("Authorization", accessToken, accessTokenValidTime));
response.addCookie(createCookie("RefreshToken", refreshToken, refreshTokenValidTime));
response.sendRedirect("/");
response.sendRedirect(redirectURL);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

@SpringBootTest
@ActiveProfiles("test")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,24 @@

import static org.junit.jupiter.api.Assertions.*;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.transaction.annotation.Transactional;

import kaboo.kaboo_auth.domain.Course;
import kaboo.kaboo_auth.domain.entity.Member;

@DataJpaTest
@Transactional
@DisplayName("Member Repository Test")
@ActiveProfiles("test")
class MemberRepositoryTest {
@Autowired
MemberRepository memberRepository;
Expand Down Expand Up @@ -58,4 +63,66 @@ void findByUsername_Failure() {
// Then
assertEquals(result, Optional.empty());
}

@Test
@DisplayName("DB์— ์กด์žฌํ•˜๋Š” classNum ์ฐพ์„ ๋•Œ findByClassNum method ํ…Œ์ŠคํŠธ")
void findByClassNum_Success() {
// Given
Member member1 = Member.builder().englishName("Alice").classNum(1).build();
Member member2 = Member.builder().englishName("Bob").classNum(1).build();

memberRepository.save(member1);
memberRepository.save(member2);

List<Member> expectedMembers = Arrays.asList(member1, member2);

// When
List<Member> byClassNum = memberRepository.findByClassNum(1);

// Then
assertEquals(byClassNum.size(), 2, "๋ฆฌ์ŠคํŠธ์˜ ํฌ๊ธฐ๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.");
assertTrue(byClassNum.containsAll(expectedMembers), "๋ฆฌ์ŠคํŠธ์— ๋ชจ๋“  ๋ฉค๋ฒ„๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.");
}

@Test
@DisplayName("DB์— ์กด์žฌํ•˜์ง€ ์•Š๋Š” classNum ์ฐพ์„ ๋•Œ findByClassNum method ํ…Œ์ŠคํŠธ")
void findByClassNum_Failure() {
// Given

// When
List<Member> byClassNum = memberRepository.findByClassNum(1);

// Then
assertEquals(byClassNum.size(), 0);
}

@Test
@DisplayName("findByKoreaName ์„ฑ๊ณต ํ…Œ์ŠคํŠธ")
void findByKoreaName_Success() {
// Given
Member member = Member.builder()
.koreaName("ํ™๊ธธ๋™")
.classNum(1)
.course(Course.AI)
.build();
memberRepository.save(member);

// When
Optional<Member> byKoreaName = memberRepository.findByKoreaName("ํ™๊ธธ๋™");

// Then
assertEquals(byKoreaName.get(), member);
}

@Test
@DisplayName("findByKoreaName ์‹คํŒจ ํ…Œ์ŠคํŠธ")
void findByKoreaName_Failure() {
// Given

// When
Optional<Member> byKoreaName = memberRepository.findByKoreaName("ํ™๊ธธ๋™");

// Then
assertTrue(byKoreaName.isEmpty());
}
}

0 comments on commit f12a0b4

Please sign in to comment.