Skip to content

Commit

Permalink
Merge branch 'refs/heads/develop_back' into develop_back_notification
Browse files Browse the repository at this point in the history
# Conflicts:
#	backend/core/src/main/resources/config
#	backend/core/src/main/resources/db/migration/V19__notification_update.sql
#	backend/notification/src/main/java/site/timecapsulearchive/notification/infra/fcm/FCMManager.java
#	backend/notification/src/main/resources/config
  • Loading branch information
seokho-1116 committed May 2, 2024
2 parents ce21129 + 7d173b3 commit 30f3696
Show file tree
Hide file tree
Showing 217 changed files with 6,654 additions and 1,568 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/animation-application-ci-cd-flow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ on:
branches:
- develop_back_animation
- 'hotfix/[0-9a-zA-z]+-B-animation-#[0-9a-zA-z]+'
pull_request:
branches:
- develop_back_animation

jobs:
deploy-animation:
Expand Down Expand Up @@ -80,8 +83,8 @@ jobs:
docker ps -q --filter "name=animated_drawings" | xargs -r docker stop
docker ps -aq --filter "name=animated_drawings" | xargs -r docker rm
aws ecr get-login-password --region ${{ secrets.AWS_REGION }} | docker login --username ${{ secrets.AWS_DOCKER_USER }} --password-stdin ${{ secrets.AWS_USER_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com
docker pull ${{ steps.meta.outputs.tags }}
docker image prune -f
docker pull ${{ steps.meta.outputs.tags }}
docker run -d -p 5555:5555 -p 9001:9001 --name animated_drawings -e ENVIRONMENT='dev' ${{ steps.meta.outputs.tags }}
- name: Remove Github Actions IP from security group
Expand Down
42 changes: 30 additions & 12 deletions .github/workflows/core-application-ci-cd-flow.yml
Original file line number Diff line number Diff line change
@@ -1,34 +1,51 @@
name: ci/cd
name: core-ci/cd

on:
push:
branches:
- develop_back
- 'hotfix/[0-9a-zA-z]+-B-#[0-9a-zA-z]+'
- develop_back_core
- 'hotfix/[0-9a-zA-z]+-B-core-#[0-9a-zA-z]+'
pull_request:
branches:
- develop_back
- develop_back_core

jobs:
formatting:
name: formatting
if: ${{ github.event_name == 'push' || github.event_name == 'pull_request' }}
build_and_test:
name: build and test
if: ${{github.event_name == 'pull_request' }}
runs-on: ubuntu-latest

defaults:
run:
working-directory: ./backend/core

steps:
- name: set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'corretto'
- uses: actions/checkout@v3
- uses: axel-op/googlejavaformat-action@v3
distribution: 'liberica'

- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
token: ${{ secrets.CI_PAT }}

- name: formatting
uses: axel-op/googlejavaformat-action@v3
with:
args: "--replace"
skip-commit: true

- name: grant execute permission for gradlew
run: chmod +x ./gradlew

- name: test
run: ./gradlew clean test

deploy-core:
name: core application deploy
needs: formatting
if: ${{ github.event_name == 'push' }}
runs-on: ubuntu-latest

Expand Down Expand Up @@ -115,8 +132,9 @@ jobs:
docker ps -q --filter "name=core" | xargs -r docker stop
docker ps -aq --filter "name=core" | xargs -r docker rm
aws ecr get-login-password --region ${{ secrets.AWS_REGION }} | docker login --username ${{ secrets.AWS_DOCKER_USER }} --password-stdin ${{ secrets.AWS_USER_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com
docker image prune -f
docker pull ${{ steps.meta.outputs.tags }}
docker run -d -p 8080:8080 --name core --network test_backend ${{ steps.meta.outputs.tags }}
docker run -d -p 8080:8080 -e ENVIRONMENT=dev --name core --network test_backend ${{ steps.meta.outputs.tags }}
- name: Remove Github Actions IP from security group
if: always()
Expand Down
40 changes: 39 additions & 1 deletion .github/workflows/notification-application-ci-cd-flow.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,49 @@
name: ci/cd
name: notification-ci/cd

on:
push:
branches:
- develop_back_notification
- 'hotfix/[0-9a-zA-z]+-B-notification-#[0-9a-zA-z]+'
pull_request:
branches:
- develop_back_notification

jobs:
build_and_test:
name: build and test
if: ${{github.event_name == 'pull_request' }}
runs-on: ubuntu-latest

defaults:
run:
working-directory: ./backend/core

steps:
- name: set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'liberica'

- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
token: ${{ secrets.CI_PAT }}

- name: formatting
uses: axel-op/googlejavaformat-action@v3
with:
args: "--replace"
skip-commit: true

- name: grant execute permission for gradlew
run: chmod +x ./gradlew

- name: test
run: ./gradlew clean test

deploy-notification:
name: notification application deploy
if: ${{ github.event_name == 'push' }}
Expand Down Expand Up @@ -95,6 +132,7 @@ jobs:
docker ps -q --filter "name=notification" | xargs -r docker stop
docker ps -aq --filter "name=notification" | xargs -r docker rm
aws ecr get-login-password --region ${{ secrets.AWS_REGION }} | docker login --username ${{ secrets.AWS_DOCKER_USER }} --password-stdin ${{ secrets.AWS_USER_ID }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com
docker image prune -f
docker pull ${{ steps.meta.outputs.tags }}
docker run -d -p 8081:8081 -e ENVIRONMENT=dev --name notification --network test_backend ${{ steps.meta.outputs.tags }}
Expand Down
2 changes: 1 addition & 1 deletion backend/core/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ COPY --from=build ${EXTRACTED}/spring-boot-loader/ ./
COPY --from=build ${EXTRACTED}/snapshot-dependencies/ ./
COPY --from=build ${EXTRACTED}/application/ ./

ENTRYPOINT ["java","-Dspring.profiles.active=dev","org.springframework.boot.loader.JarLauncher"]
ENTRYPOINT java -Dspring.profiles.active=$ENVIRONMENT org.springframework.boot.loader.JarLauncher
14 changes: 12 additions & 2 deletions backend/core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ dependencies {
implementation 'org.apache.httpcomponents.client5:httpclient5:5.3'

//flyway
implementation 'org.flywaydb:flyway-core:9.5.1'
implementation 'org.flywaydb:flyway-mysql:9.5.1'
implementation 'org.flywaydb:flyway-core:9.5.0'
implementation 'org.flywaydb:flyway-mysql:9.5.0'

//s3
implementation 'software.amazon.awssdk:s3:2.21.46'
Expand Down Expand Up @@ -71,13 +71,23 @@ dependencies {
//swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'

//aop
implementation 'org.springframework.boot:spring-boot-starter-aop'

//jnanoid
implementation 'com.aventrix.jnanoid:jnanoid:2.0.0'

compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.springframework.amqp:spring-rabbit-test'
testImplementation 'org.flywaydb.flyway-test-extensions:flyway-spring-test:9.5.0'
testImplementation 'org.testcontainers:testcontainers:1.19.1'
testImplementation 'org.testcontainers:junit-jupiter:1.19.1'
testImplementation 'org.testcontainers:mysql:1.19.1'
}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.ResponseEntity;
import site.timecapsulearchive.core.domain.auth.data.request.EmailSignInRequest;
import site.timecapsulearchive.core.domain.auth.data.request.EmailSignUpRequest;
import site.timecapsulearchive.core.domain.auth.data.request.SignInRequest;
import site.timecapsulearchive.core.domain.auth.data.request.SignUpRequest;
import site.timecapsulearchive.core.domain.auth.data.request.TemporaryTokenReIssueRequest;
Expand Down Expand Up @@ -253,5 +255,62 @@ ResponseEntity<ApiSpec<TokenResponse>> validVerificationMessage(
Long memberId,
VerificationNumberValidRequest request
);

@Operation(
summary = "이메일로 회원가입",
description = """
이메일로 회원가입 한다.
인증되지 않은 상태이므로 전화 번호 인증을 해야한다.
""",
tags = {"auth"}
)
@ApiResponses(value = {
@ApiResponse(
responseCode = "200",
description = "ok"
)
})
ResponseEntity<ApiSpec<TemporaryTokenResponse>> signUpWithEmail(EmailSignUpRequest request);

@Operation(
summary = "이메일로 로그인",
description = """
이메일로 로그인 한다.
완전히 인증된 상태의 유저만 가능하다.
""",
tags = {"auth"}
)
@ApiResponses(value = {
@ApiResponse(
responseCode = "200",
description = "ok"
),
@ApiResponse(
responseCode = "400",
description = """
요청이 잘못되어 발생하는 오류이다.
<ul>
<li>올바르지 않은 요청인 경우 예외가 발생한다.</li>
<li>인증되지 않은 사용자인 경우 예외가 발생한다.</li>
</ul>
""",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))
),
@ApiResponse(
responseCode = "401",
description = """
이메일 또는 비밀번호가 올바르지 않은 경우 발생하는 오류이다. (일치하지 않는 경우도 포함)
""",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))
),
@ApiResponse(
responseCode = "404",
description = "로그인을 요청한 멤버를 찾을 수 없는 경우 예외가 발생한다.",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))
)
})
ResponseEntity<ApiSpec<TokenResponse>> signInWithEmail(EmailSignInRequest request);
}

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import site.timecapsulearchive.core.domain.auth.data.request.EmailSignInRequest;
import site.timecapsulearchive.core.domain.auth.data.request.EmailSignUpRequest;
import site.timecapsulearchive.core.domain.auth.data.request.SignInRequest;
import site.timecapsulearchive.core.domain.auth.data.request.SignUpRequest;
import site.timecapsulearchive.core.domain.auth.data.request.TemporaryTokenReIssueRequest;
Expand Down Expand Up @@ -201,4 +203,44 @@ public ResponseEntity<ApiSpec<TokenResponse>> validVerificationMessage(
)
);
}

@PostMapping(
value = "/sign-up/email",
produces = {"application/json"},
consumes = {"application/json"}
)
@Override
public ResponseEntity<ApiSpec<TemporaryTokenResponse>> signUpWithEmail(
@Valid @RequestBody final EmailSignUpRequest request
) {
final Long id = memberService.createMemberWithEmailAndPassword(request.email(),
request.password());

return ResponseEntity.ok(
ApiSpec.success(
SuccessCode.SUCCESS,
tokenService.createTemporaryToken(id)
)
);
}

@PostMapping(
value = "/sign-in/email",
produces = {"application/json"},
consumes = {"application/json"}
)
@Override
public ResponseEntity<ApiSpec<TokenResponse>> signInWithEmail(
@Valid @RequestBody final EmailSignInRequest request
) {
final Long id = memberService.findVerifiedMemberIdByEmailAndPassword(request.email(),
request.password());

return ResponseEntity.ok(
ApiSpec.success(
SuccessCode.SUCCESS,
tokenService.createNewToken(id)
)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package site.timecapsulearchive.core.domain.auth.data.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;

@Schema(description = "이메일 로그인 요청")
public record EmailSignInRequest(

@Schema(description = "이메일")
@NotBlank
@Email
String email,

@Schema(description = "비밀번호")
@NotBlank
String password
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package site.timecapsulearchive.core.domain.auth.data.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;

@Schema(description = "이메일 회원가입 요청")
public record EmailSignUpRequest(

@Schema(description = "사용할 이메일")
@NotBlank
@Email
String email,

@Schema(description = "사용할 비밀번호")
@NotBlank
String password
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,19 @@ public class MessageAuthenticationCacheRepository {

private final StringRedisTemplate redisTemplate;

public void save(final Long memberId, final String code) {
redisTemplate.opsForValue().set(PREFIX + memberId, code, MINUTE, TimeUnit.MINUTES);
public void save(final Long memberId, final byte[] receiver, final String code) {
redisTemplate.opsForHash().put(PREFIX + memberId, receiver, code);
redisTemplate.expire(PREFIX + memberId, MINUTE, TimeUnit.MINUTES);
}

public Optional<String> findMessageAuthenticationCodeByMemberId(final Long memberId) {
return Optional.ofNullable(redisTemplate.opsForValue().get(PREFIX + memberId));
public Optional<String> findMessageAuthenticationCodeByMemberId(final Long memberId,
final byte[] encrypt) {
String code = (String) redisTemplate.opsForHash().get(PREFIX + memberId, encrypt);

if (code == null) {
return Optional.empty();
}

return Optional.of(code);
}
}
Loading

0 comments on commit 30f3696

Please sign in to comment.