Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#30: 회원가입 서버와 연동을 해요 #35

Merged
merged 16 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package com.bff.wespot.model.auth.request

import com.bff.wespot.model.auth.response.Consents

data class SignUp(
val name: String,
val schoolId: Int,
val grade: Int,
val group: Int,
val classNumber: Int,
val gender: String,
val consents: Consents
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ package com.bff.wespot.model.auth.response
data class AuthToken(
val accessToken: String,
val refreshToken: String,
val refreshTokenExpiredAt: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.bff.wespot.model.auth.response


data class SignUpToken(
val signUpToken: String,
)
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
package com.bff.wespot.network.di

import com.bff.wespot.network.BuildConfig
import com.bff.wespot.network.model.auth.response.AuthTokenDto
import com.bff.wespot.network.model.auth.response.SignUpTokenDto
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.engine.cio.CIO
import io.ktor.client.plugins.HttpResponseValidator
import io.ktor.client.plugins.HttpTimeout
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.plugins.defaultRequest
import io.ktor.client.plugins.logging.LogLevel
import io.ktor.client.plugins.logging.Logger
import io.ktor.client.plugins.logging.Logging
import io.ktor.client.request.header
import io.ktor.client.statement.request
import io.ktor.http.ContentType
import io.ktor.http.HttpHeaders
import io.ktor.serialization.kotlinx.json.json
import io.ktor.util.AttributeKey
import kotlinx.serialization.json.Json
import timber.log.Timber
import javax.inject.Singleton
Expand Down Expand Up @@ -46,6 +52,24 @@ object ClientModule {
}
}*/

HttpResponseValidator {
this.
validateResponse {
if(it.request.url.toString().contains("api/v1/auth/login")) {
when(it.status.value) {
200 -> {
val parsedBody = it.body<AuthTokenDto>()
it.call.attributes.put(AttributeKey("parsedBody"), parsedBody)
}
202 -> {
val parsedBody = it.body<SignUpTokenDto>()
it.call.attributes.put(AttributeKey("parsedBody"), parsedBody)
}
}
}
flash159483 marked this conversation as resolved.
Show resolved Hide resolved
}
}

install(HttpTimeout) {
requestTimeoutMillis = REQUEST_TIMEOUT_MILLIS
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.bff.wespot.network.extensions

import com.bff.wespot.network.model.exception.NetworkException
import io.ktor.client.*
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.request.*
import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.request.request
import io.ktor.http.isSuccess
import io.ktor.util.AttributeKey
import io.ktor.util.network.UnresolvedAddressException
import kotlinx.serialization.SerializationException
import timber.log.Timber
Expand All @@ -17,8 +19,9 @@ suspend inline fun <reified T> HttpClient.safeRequest(
block()
}
return if (response.status.isSuccess()) {
val parsedBody = response.call.attributes.getOrNull(AttributeKey("parsedBody"))
val responseBody = response.body<T>()
Result.success(responseBody)
Result.success(parsedBody as? T ?: responseBody)
} else {
flash159483 marked this conversation as resolved.
Show resolved Hide resolved
val errorBody = response.body<NetworkException>()
Result.failure(errorBody)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import kotlinx.serialization.Serializable

@Serializable
data class SignUpDto(
val name: String,
val schoolId: Int,
val grade: Int,
val group: Int,
val classNumber: Int,
val gender: String,
val userToken: String,
val signUpToken: String,
val consents: ConsentsDto,
)
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import kotlinx.serialization.Serializable
data class AuthTokenDto(
val accessToken: String,
val refreshToken: String,
val refreshTokenExpiredAt: String,
) {
fun toAuthToken() = AuthToken(
accessToken = accessToken,
refreshToken = refreshToken,
refreshTokenExpiredAt = refreshTokenExpiredAt,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.bff.wespot.network.model.auth.response

import com.bff.wespot.model.auth.response.SignUpToken
import kotlinx.serialization.Serializable

@Serializable
data class SignUpTokenDto(
val signUpToken: String,
) {
fun toSignUpToken() = SignUpToken(
signUpToken = signUpToken,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ import com.bff.wespot.network.model.auth.response.SchoolListDto

interface AuthDataSource {
suspend fun getSchoolList(search: String): Result<SchoolListDto>
suspend fun sendKakaoToken(token: KakaoAuthTokenDto): Result<AuthTokenDto>
suspend fun sendKakaoToken(token: KakaoAuthTokenDto): Result<Any>
suspend fun signUp(signUp: SignUpDto): Result<AuthTokenDto>
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class AuthDataSourceImpl @Inject constructor(
}
}

override suspend fun sendKakaoToken(token: KakaoAuthTokenDto): Result<AuthTokenDto> =
override suspend fun sendKakaoToken(token: KakaoAuthTokenDto): Result<Any> =
httpClient.safeRequest {
url {
method = HttpMethod.Post
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import com.bff.wespot.domain.repository.auth.AuthRepository
import com.bff.wespot.domain.util.DataStoreKey
import com.bff.wespot.model.auth.request.KakaoAuthToken
import com.bff.wespot.model.auth.request.SignUp
import com.bff.wespot.model.auth.response.AuthToken
import com.bff.wespot.model.auth.response.School
import com.bff.wespot.network.model.auth.response.AuthTokenDto
import com.bff.wespot.network.model.auth.response.SchoolDto
import com.bff.wespot.network.model.auth.response.SignUpTokenDto
import com.bff.wespot.network.source.auth.AuthDataSource
import kotlinx.coroutines.flow.first
import javax.inject.Inject
Expand All @@ -22,18 +23,29 @@ class AuthRepositoryImpl @Inject constructor(
.getSchoolList(search)
.map { it.schools.map(SchoolDto::toSchool) }

override suspend fun sendKakaoToken(token: KakaoAuthToken): Result<AuthToken> =
override suspend fun sendKakaoToken(token: KakaoAuthToken): Result<Any> =
authDataSource
.sendKakaoToken(token.toDto())
.map { it.toAuthToken() }
.map {
when (it) {
is AuthTokenDto -> {
it.toAuthToken()
}

is SignUpTokenDto -> {
it.toSignUpToken()
}

else -> throw IllegalArgumentException("Unknown token type")
}
}

override suspend fun signUp(signUp: SignUp): Boolean {
return authDataSource
.signUp(
signUp.toDto(
dataStore.getString(DataStoreKey.ACCESS_TOKEN).first()
dataStore.getString(DataStoreKey.SIGN_UP_TOKEN).first()
)
).isSuccess
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ package com.bff.wespot.domain.repository.auth

import com.bff.wespot.model.auth.request.KakaoAuthToken
import com.bff.wespot.model.auth.request.SignUp
import com.bff.wespot.model.auth.response.AuthToken
import com.bff.wespot.model.auth.response.School

interface AuthRepository {
suspend fun getSchoolList(search: String): Result<List<School>>
suspend fun sendKakaoToken(token: KakaoAuthToken): Result<AuthToken>
suspend fun sendKakaoToken(token: KakaoAuthToken): Result<Any>
suspend fun signUp(signUp: SignUp): Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,40 @@ import com.bff.wespot.domain.repository.DataStoreRepository
import com.bff.wespot.domain.repository.auth.AuthRepository
import com.bff.wespot.domain.repository.auth.KakaoLoginManager
import com.bff.wespot.domain.util.DataStoreKey
import com.bff.wespot.model.auth.response.AuthToken
import com.bff.wespot.model.auth.response.SignUpToken
import com.bff.wespot.model.constants.LoginState
import javax.inject.Inject

class KakaoLoginUseCase @Inject constructor(
val kakaoLoginManager: KakaoLoginManager,
val authRepository: AuthRepository,
val dataStoreRepository: DataStoreRepository,
private val kakaoLoginManager: KakaoLoginManager,
private val authRepository: AuthRepository,
private val dataStoreRepository: DataStoreRepository,
) {
suspend inline fun invoke() {
suspend operator fun invoke(): Result<LoginState> {
val result = kakaoLoginManager.loginWithKakao()
authRepository.sendKakaoToken(result)
.onSuccess {
dataStoreRepository.saveString(DataStoreKey.ACCESS_TOKEN, it.accessToken)
dataStoreRepository.saveString(DataStoreKey.REFRESH_TOKEN, it.refreshToken)
}
.onFailure {
throw(it)
return authRepository.sendKakaoToken(result)
.map {
when (it) {
is AuthToken -> {
dataStoreRepository.saveString(DataStoreKey.ACCESS_TOKEN, it.accessToken)
dataStoreRepository.saveString(DataStoreKey.REFRESH_TOKEN, it.refreshToken)
dataStoreRepository.saveString(
DataStoreKey.REFRESH_TOKEN_EXPIRED_AT,
it.refreshTokenExpiredAt
)
LoginState.LOGIN_SUCCESS
}

is SignUpToken -> {
dataStoreRepository.saveString(DataStoreKey.SIGN_UP_TOKEN, it.signUpToken)
LoginState.LOGIN_FAILURE
}

else -> {
LoginState.LOGIN_FAILURE
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ package com.bff.wespot.domain.util
object DataStoreKey {
const val ACCESS_TOKEN = "access_token"
const val REFRESH_TOKEN = "refresh_token"
const val REFRESH_TOKEN_EXPIRED_AT = "refresh_token_expired_date"
const val SIGN_UP_TOKEN = "signup_token"
}