-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from ASAP-Lettering/ASAP-60
ASAP-60 feat: 소셜 로그인 및 회원가입 추가
- Loading branch information
Showing
44 changed files
with
1,092 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# Application 모듈 | ||
|
||
## 역할 | ||
|
||
* `Lettering` 서비스의 핵심 비즈니스 로직을 처리한다. | ||
|
||
|
||
## 패키지 구조 | ||
|
||
```markdown | ||
. | ||
└── {domain}/ | ||
├── port/ | ||
│ ├── in | ||
│ └── out | ||
├── service | ||
├── vo | ||
└── exception | ||
``` | ||
|
||
* `{domain}`: 도메인 이름을 의미합니다. 예를 들어, `user` 등이 될 수 있습니다. | ||
* `port`: 외부와의 통신을 위한 인터페이스를 정의합니다. | ||
* `in`: 외부에서 들어오는 요청을 처리하는 인터페이스를 정의합니다. | ||
* `out`: 외부로 나가는 응답을 처리하는 인터페이스를 정의합니다. | ||
* `service`: 비즈니스 로직을 처리하는 구현체입니다. | ||
* `exception`: 비즈니스 로직에서 발생하는 예외를 정의합니다. | ||
* `vo`: 비즈니스 로직에서 사용되는 값 객체를 정의합니다. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
dependencies{ | ||
implementation(project(":Domain-Module")) | ||
implementation(project(":Common-Module")) | ||
} |
10 changes: 10 additions & 0 deletions
10
Application-Module/src/main/kotlin/com/asap/application/ApplicationConfig.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.asap.application | ||
|
||
import org.springframework.context.annotation.ComponentScan | ||
import org.springframework.context.annotation.Configuration | ||
|
||
|
||
@Configuration | ||
@ComponentScan("com.asap.application") | ||
class ApplicationConfig { | ||
} |
33 changes: 33 additions & 0 deletions
33
Application-Module/src/main/kotlin/com/asap/application/user/exception/UserException.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.asap.application.user.exception | ||
|
||
import com.asap.common.exception.BusinessException | ||
|
||
sealed class UserException( | ||
codePrefix: String = CODE_PREFIX, | ||
errorCode: Int, | ||
httpStatus: Int = 400, | ||
message: String = DEFAULT_ERROR_MESSAGE | ||
): BusinessException(codePrefix, errorCode, httpStatus, message) { | ||
|
||
class UserAlreadyRegisteredException: UserException( | ||
errorCode = 1, | ||
message = "이미 가입된 사용자입니다." | ||
) | ||
|
||
|
||
class UserAuthNotFoundException: UserException( | ||
errorCode = 2, | ||
message = "사용자 인증 정보를 찾을 수 없습니다." | ||
) | ||
|
||
class UserNotFoundException: UserException( | ||
errorCode = 3, | ||
message = "사용자를 찾을 수 없습니다." | ||
) | ||
|
||
|
||
companion object{ | ||
const val CODE_PREFIX = "USER" | ||
const val DEFAULT_ERROR_MESSAGE = "사용자와 관련된 예외가 발생했습니다." | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
Application-Module/src/main/kotlin/com/asap/application/user/port/in/RegisterUserUsecase.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.asap.application.user.port.`in` | ||
|
||
import java.time.LocalDate | ||
|
||
interface RegisterUserUsecase { | ||
|
||
fun registerUser(command: Command): Response | ||
|
||
|
||
data class Command( | ||
val registerToken: String, | ||
val servicePermission: Boolean, | ||
val privatePermission: Boolean, | ||
val marketingPermission: Boolean, | ||
val birthday: LocalDate? | ||
) | ||
|
||
data class Response( | ||
val accessToken: String, | ||
val refreshToken: String | ||
) | ||
} |
22 changes: 22 additions & 0 deletions
22
Application-Module/src/main/kotlin/com/asap/application/user/port/in/SocialLoginUsecase.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.asap.application.user.port.`in` | ||
|
||
interface SocialLoginUsecase { | ||
|
||
fun login(command: Command): Response | ||
|
||
data class Command( | ||
val provider: String, | ||
val accessToken: String, | ||
) | ||
|
||
sealed class Response { | ||
} | ||
data class Success( | ||
val accessToken: String, | ||
val refreshToken: String | ||
) : Response() | ||
|
||
data class NonRegistered( | ||
val registerToken: String | ||
) : Response() | ||
} |
11 changes: 11 additions & 0 deletions
11
...ication-Module/src/main/kotlin/com/asap/application/user/port/out/AuthInfoRetrievePort.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.asap.application.user.port.out | ||
|
||
import com.asap.application.user.exception.UserException | ||
import com.asap.application.user.vo.AuthInfo | ||
import com.asap.domain.user.enums.SocialLoginProvider | ||
|
||
interface AuthInfoRetrievePort { | ||
|
||
@Throws(UserException.UserAuthNotFoundException::class) | ||
fun getAuthInfo(provider: SocialLoginProvider, accessToken: String): AuthInfo | ||
} |
24 changes: 24 additions & 0 deletions
24
...ation-Module/src/main/kotlin/com/asap/application/user/port/out/UserAuthManagementPort.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.asap.application.user.port.out | ||
|
||
import com.asap.domain.user.entity.UserAuth | ||
import com.asap.domain.user.enums.SocialLoginProvider | ||
|
||
interface UserAuthManagementPort { | ||
|
||
fun getUserAuth( | ||
socialId: String, | ||
socialLoginProvider: SocialLoginProvider | ||
): UserAuth? | ||
|
||
|
||
fun isExistsUserAuth( | ||
socialId: String, | ||
socialLoginProvider: SocialLoginProvider | ||
): Boolean | ||
|
||
|
||
fun saveUserAuth( | ||
userAuth: UserAuth | ||
): UserAuth | ||
|
||
} |
10 changes: 10 additions & 0 deletions
10
Application-Module/src/main/kotlin/com/asap/application/user/port/out/UserManagementPort.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.asap.application.user.port.out | ||
|
||
import com.asap.domain.common.DomainId | ||
import com.asap.domain.user.entity.User | ||
|
||
interface UserManagementPort { | ||
fun saveUser(user: User): User | ||
|
||
fun getUser(userId: DomainId): User? | ||
} |
18 changes: 18 additions & 0 deletions
18
...tion-Module/src/main/kotlin/com/asap/application/user/port/out/UserTokenManagementPort.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.asap.application.user.port.out | ||
|
||
import com.asap.application.user.vo.UserClaims | ||
import com.asap.domain.user.entity.User | ||
|
||
interface UserTokenManagementPort { | ||
fun resolveRegisterToken(token: String): UserClaims.Register | ||
|
||
fun generateRegisterToken( | ||
socialId: String, | ||
socialLoginProvider: String, | ||
username: String | ||
): String | ||
|
||
fun generateAccessToken(user: User): String | ||
|
||
fun generateRefreshToken(user: User): String | ||
} |
22 changes: 22 additions & 0 deletions
22
...rc/main/kotlin/com/asap/application/user/port/out/memory/MemoryAuthInfoRetrieveAdapter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.asap.application.user.port.out.memory | ||
|
||
import com.asap.application.user.exception.UserException | ||
import com.asap.application.user.port.out.AuthInfoRetrievePort | ||
import com.asap.application.user.vo.AuthInfo | ||
import com.asap.domain.user.enums.SocialLoginProvider | ||
import org.springframework.context.annotation.Primary | ||
import org.springframework.stereotype.Component | ||
|
||
@Component | ||
@Primary | ||
class MemoryAuthInfoRetrieveAdapter: AuthInfoRetrievePort { | ||
|
||
private val authInfos = mutableMapOf<Pair<String, SocialLoginProvider>, AuthInfo>().apply { | ||
put(Pair("registered", SocialLoginProvider.KAKAO), AuthInfo(SocialLoginProvider.KAKAO, "socialId", "username")) | ||
put(Pair("nonRegistered", SocialLoginProvider.KAKAO), AuthInfo(SocialLoginProvider.KAKAO, "nonRegisteredId", "username")) | ||
} | ||
|
||
override fun getAuthInfo(provider: SocialLoginProvider, accessToken: String): AuthInfo { | ||
return authInfos[Pair(accessToken, provider)] ?: throw UserException.UserAuthNotFoundException() | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
.../src/main/kotlin/com/asap/application/user/port/out/memory/MemoryAuthManagementAdapter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.asap.application.user.port.out.memory | ||
|
||
import com.asap.application.user.port.out.UserAuthManagementPort | ||
import com.asap.domain.common.DomainId | ||
import com.asap.domain.user.entity.UserAuth | ||
import com.asap.domain.user.enums.SocialLoginProvider | ||
import org.springframework.context.annotation.Primary | ||
import org.springframework.stereotype.Component | ||
|
||
@Component | ||
@Primary | ||
class MemoryAuthManagementAdapter: UserAuthManagementPort{ | ||
|
||
private val userAuths = mutableMapOf<Pair<String, SocialLoginProvider>, UserAuth>().apply { | ||
put(Pair("socialId", SocialLoginProvider.KAKAO), UserAuth(userId = DomainId("registered"), socialId = "socialId", socialLoginProvider = SocialLoginProvider.KAKAO)) | ||
} | ||
|
||
override fun getUserAuth(socialId: String, socialLoginProvider: SocialLoginProvider): UserAuth? { | ||
return userAuths[Pair(socialId, socialLoginProvider)] | ||
} | ||
|
||
override fun isExistsUserAuth(socialId: String, socialLoginProvider: SocialLoginProvider): Boolean { | ||
return socialId == "duplicate" | ||
} | ||
|
||
override fun saveUserAuth(userAuth: UserAuth): UserAuth { | ||
userAuths[Pair(userAuth.socialId, userAuth.socialLoginProvider)] = userAuth | ||
return userAuth | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
.../src/main/kotlin/com/asap/application/user/port/out/memory/MemoryUserManagementAdapter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.asap.application.user.port.out.memory | ||
|
||
import com.asap.application.user.port.out.UserManagementPort | ||
import com.asap.domain.common.DomainId | ||
import com.asap.domain.user.entity.User | ||
import com.asap.domain.user.vo.UserPermission | ||
import org.springframework.context.annotation.Primary | ||
import org.springframework.stereotype.Component | ||
|
||
@Component | ||
@Primary | ||
class MemoryUserManagementAdapter: UserManagementPort { | ||
private val users = mutableMapOf<DomainId, User>().apply { | ||
put(DomainId("registered"), User(DomainId("registered"), "username", UserPermission(true,true,true))) | ||
} | ||
|
||
override fun saveUser(user: User): User { | ||
users[user.id] = user | ||
return user | ||
} | ||
|
||
override fun getUser(userId: DomainId): User? { | ||
return users[userId] | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
...main/kotlin/com/asap/application/user/port/out/memory/MemoryUserTokenManagementAdapter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package com.asap.application.user.port.out.memory | ||
|
||
import com.asap.application.user.port.out.UserTokenManagementPort | ||
import com.asap.application.user.vo.UserClaims | ||
import com.asap.common.exception.DefaultException | ||
import com.asap.domain.user.entity.User | ||
import com.asap.domain.user.enums.SocialLoginProvider | ||
import org.springframework.context.annotation.Primary | ||
import org.springframework.stereotype.Component | ||
|
||
@Component | ||
@Primary | ||
class MemoryUserTokenManagementAdapter( | ||
|
||
) : UserTokenManagementPort{ | ||
override fun resolveRegisterToken(token: String): UserClaims.Register { | ||
return when(token){ | ||
"valid" -> UserClaims.Register( | ||
socialId = "123", | ||
socialLoginProvider = SocialLoginProvider.KAKAO, | ||
username = "test" | ||
) | ||
"duplicate" -> UserClaims.Register( | ||
socialId = "duplicate", | ||
socialLoginProvider = SocialLoginProvider.KAKAO, | ||
username = "test" | ||
) | ||
else -> throw DefaultException.InvalidArgumentException() // TODO: jwt 구현할 때 수정 | ||
} | ||
} | ||
|
||
override fun generateRegisterToken(socialId: String, socialLoginProvider: String, username: String): String { | ||
return "registerToken" | ||
} | ||
|
||
override fun generateAccessToken(user: User): String { | ||
return "accessToken" | ||
} | ||
|
||
override fun generateRefreshToken(user: User): String { | ||
return "refreshToken" | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
Application-Module/src/main/kotlin/com/asap/application/user/service/RegisterUserService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package com.asap.application.user.service | ||
|
||
import com.asap.application.user.exception.UserException | ||
import com.asap.application.user.port.`in`.RegisterUserUsecase | ||
import com.asap.application.user.port.out.UserAuthManagementPort | ||
import com.asap.application.user.port.out.UserManagementPort | ||
import com.asap.application.user.port.out.UserTokenManagementPort | ||
import com.asap.domain.user.entity.User | ||
import com.asap.domain.user.entity.UserAuth | ||
import com.asap.domain.user.vo.UserPermission | ||
import org.springframework.stereotype.Service | ||
|
||
@Service | ||
class RegisterUserService( | ||
private val userTokenManagementPort: UserTokenManagementPort, | ||
private val userAuthManagementPort: UserAuthManagementPort, | ||
private val userManagementPort: UserManagementPort | ||
) : RegisterUserUsecase { | ||
|
||
/** | ||
* 1. register token으로부터 사용자 정보 추출 -> 토큰이 이미 사용됐으면 에러 | ||
* 2. 추출한 사용자가 이미 존재하는지 확인 -> 이미 존재하면 에러 | ||
* 3. 추출한 사용자 정보와 함께 사용자 동의 검증 -> 동의하지 않으면 에러 | ||
* 4. 사용자 정보 저장 및 jwt 토큰 반환 | ||
*/ | ||
|
||
override fun registerUser(command: RegisterUserUsecase.Command): RegisterUserUsecase.Response { | ||
val userClaims = userTokenManagementPort.resolveRegisterToken(command.registerToken) | ||
if (userAuthManagementPort.isExistsUserAuth(userClaims.socialId, userClaims.socialLoginProvider)) { | ||
throw UserException.UserAlreadyRegisteredException() | ||
} | ||
val registerUser = User( | ||
nickname = userClaims.username, | ||
permission = UserPermission( | ||
command.servicePermission, | ||
command.privatePermission, | ||
command.marketingPermission | ||
) | ||
) | ||
val userAuth = UserAuth( | ||
userId = registerUser.id, | ||
socialId = userClaims.socialId, | ||
socialLoginProvider = userClaims.socialLoginProvider | ||
) | ||
|
||
userManagementPort.saveUser(registerUser) | ||
userAuthManagementPort.saveUserAuth(userAuth) | ||
|
||
return RegisterUserUsecase.Response( | ||
userTokenManagementPort.generateAccessToken(registerUser), | ||
userTokenManagementPort.generateRefreshToken(registerUser) | ||
) | ||
} | ||
} |
Oops, something went wrong.