diff --git a/.github/workflows/develop_server_deployer.yaml b/.github/workflows/develop_server_deployer.yaml index 27d73e67..cec989cc 100644 --- a/.github/workflows/develop_server_deployer.yaml +++ b/.github/workflows/develop_server_deployer.yaml @@ -1,22 +1,48 @@ name: Develop Server Deployer (CD) on: + workflow_run: + workflows: ["Develop Server Integrator (CI)"] + branches: [main] + types: + - completed workflow_dispatch: inputs: version: description: 'Image version tag (e.g., 0.2411.135 or latest)' required: true default: 'latest' + workflow_run: + workflows: ["Develop Server Integrator (CI)"] + types: + - completed jobs: deploy: - needs: validate_version + needs: [validate_version, check_ci_success] runs-on: ubuntu-latest environment: DEV steps: - name: Checkout repository uses: actions/checkout@v2 + - name: Get triggered workflow run + uses: actions/github-script@v6 + id: triggered_workflow_run + with: + script: | + const eventPayload = require(process.env.GITHUB_EVENT_PATH); + const workflowRun = eventPayload.workflow_run; + return { + head_branch: workflowRun.head_branch, + head_sha: workflowRun.head_sha, + version: `${workflowRun.head_branch}.${workflowRun.id}` + }; + + - name: Set version from triggered workflow + if: github.event_name == 'workflow_run' + run: echo "version=${{ steps.triggered_workflow_run.outputs.version }}" >> $GITHUB_OUTPUT + - name: Send discord notification (develop server deploy start) uses: appleboy/discord-action@master with: @@ -27,7 +53,7 @@ jobs: > > πŸ›’οΈ Repository : ${{ github.repository }} > πŸŽ‹ Branch : ${{ github.ref }} - > πŸ“ Version : ${{ github.event.inputs.version }} + > πŸ“ Version : ${{ steps.triggered_workflow_run.outputs.version || github.event.inputs.version }} > πŸ” Run Attempt : ${{ github.run_attempt }} > πŸ€— Actor : ${{ github.triggering_actor }} @@ -149,6 +175,7 @@ jobs: validate_version: runs-on: ubuntu-latest + if: github.event_name == 'workflow_dispatch' steps: - name: Validate version format run: | @@ -158,3 +185,13 @@ jobs: echo "Invalid version format. Use 'latest' or semver format (e.g., 0.2411.135)" exit 1 fi + + check_ci_success: + needs: validate_version + runs-on: ubuntu-latest + steps: + - name: Check CI + if: ${{ github.event.workflow_run != null && github.event.workflow_run.conclusion != 'success' }} + run: | + echo "CI failed" + exit 1 diff --git a/application/src/main/kotlin/com/studentcenter/weave/application/user/port/outbound/UserRefreshTokenRepository.kt b/application/src/main/kotlin/com/studentcenter/weave/application/user/port/outbound/UserRefreshTokenRepository.kt index 12f2a3bb..d8708279 100644 --- a/application/src/main/kotlin/com/studentcenter/weave/application/user/port/outbound/UserRefreshTokenRepository.kt +++ b/application/src/main/kotlin/com/studentcenter/weave/application/user/port/outbound/UserRefreshTokenRepository.kt @@ -10,7 +10,7 @@ interface UserRefreshTokenRepository { expirationSeconds: Long ) - fun findByUserId(userId: UUID): String? + fun existsByUserId(userId: UUID): Boolean fun deleteByUserId(userId: UUID) diff --git a/application/src/main/kotlin/com/studentcenter/weave/application/user/service/application/RefreshTokenService.kt b/application/src/main/kotlin/com/studentcenter/weave/application/user/service/application/RefreshTokenService.kt index 3c0514d1..b5882a31 100644 --- a/application/src/main/kotlin/com/studentcenter/weave/application/user/service/application/RefreshTokenService.kt +++ b/application/src/main/kotlin/com/studentcenter/weave/application/user/service/application/RefreshTokenService.kt @@ -5,10 +5,11 @@ import com.studentcenter.weave.application.user.port.inbound.RefreshToken import com.studentcenter.weave.application.user.port.outbound.UserRefreshTokenRepository import com.studentcenter.weave.application.user.service.domain.UserDomainService import com.studentcenter.weave.application.user.service.util.UserTokenService +import com.studentcenter.weave.application.user.vo.UserTokenClaims import com.studentcenter.weave.domain.user.entity.User +import com.studentcenter.weave.support.security.jwt.exception.JwtException import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional -import java.util.* @Service class RefreshTokenService( @@ -19,15 +20,16 @@ class RefreshTokenService( @Transactional override fun invoke(command: RefreshToken.Command): RefreshToken.Result { - val refreshToken: String = command.refreshToken - val refreshTokenUserId: UUID = userTokenService - .resolveRefreshToken(refreshToken) - .userId - - val s = userRefreshTokenRepository.findByUserId(refreshTokenUserId) - validateRefreshTokenExists(s) - - val user: User = userDomainService.getById(refreshTokenUserId) + // TODO(dojin): Result ν˜•νƒœλ‘œ resolveμͺ½μ„ λ¦¬νŒ©ν† λ§ν•˜λ©΄μ„œ try-catch μ—†μ• κΈ° + lateinit var refreshToken: UserTokenClaims.RefreshToken + try { + refreshToken = userTokenService.resolveRefreshToken(command.refreshToken) + } catch (e: JwtException.Expired) { + throw AuthException.RefreshTokenNotFound() + } + validateRefreshToken(refreshToken) + + val user: User = userDomainService.getById(refreshToken.userId) val accessToken: String = userTokenService.generateAccessToken(user) val newRefreshToken: String = userTokenService.generateRefreshToken(user) @@ -37,8 +39,10 @@ class RefreshTokenService( ) } - private fun validateRefreshTokenExists(refreshToken: String?): String { - return refreshToken ?: throw AuthException.RefreshTokenNotFound() + private fun validateRefreshToken(refreshToken: UserTokenClaims.RefreshToken) { + if (userRefreshTokenRepository.existsByUserId(refreshToken.userId).not()) { + throw AuthException.RefreshTokenNotFound() + } } } diff --git a/application/src/test/kotlin/com/studentcenter/weave/application/user/service/application/LogoutTest.kt b/application/src/test/kotlin/com/studentcenter/weave/application/user/service/application/LogoutTest.kt index b402142f..641dac45 100644 --- a/application/src/test/kotlin/com/studentcenter/weave/application/user/service/application/LogoutTest.kt +++ b/application/src/test/kotlin/com/studentcenter/weave/application/user/service/application/LogoutTest.kt @@ -37,7 +37,7 @@ class LogoutTest : DescribeSpec({ sut.invoke() // assert - userRefreshTokenRepositorySpy.findByUserId(user.id) shouldBe null + userRefreshTokenRepositorySpy.existsByUserId(user.id) shouldBe false } } diff --git a/application/src/testFixtures/kotlin/com/studentcenter/weave/application/user/port/outbound/UserRefreshTokenRepositorySpy.kt b/application/src/testFixtures/kotlin/com/studentcenter/weave/application/user/port/outbound/UserRefreshTokenRepositorySpy.kt index 4f29231d..6a846ab1 100644 --- a/application/src/testFixtures/kotlin/com/studentcenter/weave/application/user/port/outbound/UserRefreshTokenRepositorySpy.kt +++ b/application/src/testFixtures/kotlin/com/studentcenter/weave/application/user/port/outbound/UserRefreshTokenRepositorySpy.kt @@ -3,8 +3,7 @@ package com.studentcenter.weave.application.user.port.outbound import java.util.* import java.util.concurrent.ConcurrentHashMap -class UserRefreshTokenRepositorySpy : - com.studentcenter.weave.application.user.port.outbound.UserRefreshTokenRepository { +class UserRefreshTokenRepositorySpy : UserRefreshTokenRepository { private val bucket = ConcurrentHashMap() @@ -16,8 +15,8 @@ class UserRefreshTokenRepositorySpy : bucket[userId] = refreshToken } - override fun findByUserId(userId: UUID): String? { - return bucket[userId] + override fun existsByUserId(userId: UUID): Boolean { + return bucket[userId] != null } override fun deleteByUserId(userId: UUID) { diff --git a/infrastructure/redis/src/main/kotlin/com/studentcenter/weave/infrastructure/redis/user/adapter/UserRefreshTokenRedisAdapter.kt b/infrastructure/redis/src/main/kotlin/com/studentcenter/weave/infrastructure/redis/user/adapter/UserRefreshTokenRedisAdapter.kt index 280d6572..6ed751fe 100644 --- a/infrastructure/redis/src/main/kotlin/com/studentcenter/weave/infrastructure/redis/user/adapter/UserRefreshTokenRedisAdapter.kt +++ b/infrastructure/redis/src/main/kotlin/com/studentcenter/weave/infrastructure/redis/user/adapter/UserRefreshTokenRedisAdapter.kt @@ -24,11 +24,8 @@ class UserRefreshTokenRedisAdapter( userRefreshTokenRedisRepository.save(userRefreshTokenRedisHash) } - override fun findByUserId(userId: UUID): String? { - return userRefreshTokenRedisRepository - .findById(userId) - .map { it.refreshToken } - .orElse(null) + override fun existsByUserId(userId: UUID): Boolean { + return userRefreshTokenRedisRepository.existsById(userId) } override fun deleteByUserId(userId: UUID) {