From 8d4754e7a52ca6ac97930071a84d45dc2a42f9e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=98=84=EC=84=9C?= Date: Mon, 15 Jan 2024 19:55:56 +0900 Subject: [PATCH 01/16] :fire: :: Remove file --- core/model/src/main/java/com/goms/model/Ci.kt | 4 ---- .../model/src/main/java/com/goms/model/request/login/.gitkeep | 0 .../src/main/java/com/goms/model/response/login/.gitkeep | 0 3 files changed, 4 deletions(-) delete mode 100644 core/model/src/main/java/com/goms/model/Ci.kt delete mode 100644 core/model/src/main/java/com/goms/model/request/login/.gitkeep delete mode 100644 core/model/src/main/java/com/goms/model/response/login/.gitkeep diff --git a/core/model/src/main/java/com/goms/model/Ci.kt b/core/model/src/main/java/com/goms/model/Ci.kt deleted file mode 100644 index e91acb9d..00000000 --- a/core/model/src/main/java/com/goms/model/Ci.kt +++ /dev/null @@ -1,4 +0,0 @@ -package com.goms.model - -class Ci { -} \ No newline at end of file diff --git a/core/model/src/main/java/com/goms/model/request/login/.gitkeep b/core/model/src/main/java/com/goms/model/request/login/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/core/model/src/main/java/com/goms/model/response/login/.gitkeep b/core/model/src/main/java/com/goms/model/response/login/.gitkeep deleted file mode 100644 index e69de29b..00000000 From 4d18899e3ec1984fd8994d59a76df06557ae2d8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=98=84=EC=84=9C?= Date: Mon, 15 Jan 2024 21:41:37 +0900 Subject: [PATCH 02/16] :sparkles: :: Add exception --- .../goms/network/exception/HttpException.kt | 59 +++++++++++++++++++ .../network/exception/InternetException.kt | 6 ++ .../exception/TokenExpirationException.kt | 8 +++ 3 files changed, 73 insertions(+) create mode 100644 core/network/src/main/java/com/goms/network/exception/HttpException.kt create mode 100644 core/network/src/main/java/com/goms/network/exception/InternetException.kt create mode 100644 core/network/src/main/java/com/goms/network/exception/TokenExpirationException.kt diff --git a/core/network/src/main/java/com/goms/network/exception/HttpException.kt b/core/network/src/main/java/com/goms/network/exception/HttpException.kt new file mode 100644 index 00000000..2271fc89 --- /dev/null +++ b/core/network/src/main/java/com/goms/network/exception/HttpException.kt @@ -0,0 +1,59 @@ +package com.goms.network.exception + +// 400: 올바르지 않은 요청 +class BadRequestException( + override val message: String? +) : RuntimeException() + + +// 401: 비인증 상태 +class UnauthorizedException( + override val message: String? +) : RuntimeException() + + +// 403: 권한이 없음 +class ForBiddenException( + override val message: String? +) : RuntimeException() + + +// 404: 요청한 리소스를 찾을 수 없음 +class NotFoundException( + override val message: String? +) : RuntimeException() + + +// 406: 클라이언트가 허용되지 않는 규격을 요청 +class NotAcceptableException( + override val message: String? +) : RuntimeException() + +// 408: 요청시간초과 +class TimeOutException( + override val message: String? +) : RuntimeException() + + +// 409: 충돌발생 +class ConflictException( + override val message: String? +) : RuntimeException() + + +// 50X: 서버에러 +class ServerException( + override val message: String? +) : RuntimeException() + + +// 정의되지 않은 HTTP 상태 코드나 사용자 정의 상태 코드 +class OtherHttpException( + val code: Int, + override val message: String? +) : RuntimeException() + +// 예상하지 못한 에러 +class UnKnownException( + override val message: String? +) : RuntimeException() \ No newline at end of file diff --git a/core/network/src/main/java/com/goms/network/exception/InternetException.kt b/core/network/src/main/java/com/goms/network/exception/InternetException.kt new file mode 100644 index 00000000..ff3aba9c --- /dev/null +++ b/core/network/src/main/java/com/goms/network/exception/InternetException.kt @@ -0,0 +1,6 @@ +package com.goms.network.exception + +class NoInternetException : RuntimeException() { + override val message: String + get() = "네트워크가 불안정합니다, 데이터나 와이파이 연결 상태를 확인해주세요." +} \ No newline at end of file diff --git a/core/network/src/main/java/com/goms/network/exception/TokenExpirationException.kt b/core/network/src/main/java/com/goms/network/exception/TokenExpirationException.kt new file mode 100644 index 00000000..8d3f27e9 --- /dev/null +++ b/core/network/src/main/java/com/goms/network/exception/TokenExpirationException.kt @@ -0,0 +1,8 @@ +package com.goms.network.exception + +import java.io.IOException + +class TokenExpirationException : IOException() { + override val message: String + get() = "토큰이 만료되었습니다. 다시 로그인 해주세요" +} \ No newline at end of file From 0a86c3860104d0177bdc795c6f3d3e033e9a3b84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=98=84=EC=84=9C?= Date: Mon, 15 Jan 2024 21:42:05 +0900 Subject: [PATCH 03/16] :sparkles: :: Add GomsApiHandler --- .../main/java/com/goms/network/util/.gitkeep | 0 .../com/goms/network/util/GomsApiHandler.kt | 66 +++++++++++++++++++ 2 files changed, 66 insertions(+) delete mode 100644 core/network/src/main/java/com/goms/network/util/.gitkeep create mode 100644 core/network/src/main/java/com/goms/network/util/GomsApiHandler.kt diff --git a/core/network/src/main/java/com/goms/network/util/.gitkeep b/core/network/src/main/java/com/goms/network/util/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/core/network/src/main/java/com/goms/network/util/GomsApiHandler.kt b/core/network/src/main/java/com/goms/network/util/GomsApiHandler.kt new file mode 100644 index 00000000..d8ad9832 --- /dev/null +++ b/core/network/src/main/java/com/goms/network/util/GomsApiHandler.kt @@ -0,0 +1,66 @@ +package com.goms.network.util + +import android.util.Log +import com.goms.network.exception.* +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import retrofit2.HttpException +import java.net.SocketTimeoutException +import java.net.UnknownHostException + +class GomsApiHandler { + private lateinit var httpRequest: suspend () -> T + + fun httpRequest(httpRequest: suspend () -> T) = + this.apply { this.httpRequest = httpRequest } + + suspend fun sendRequest(): T { + return try { + Log.d("ApiHandler", "Success") + withContext(Dispatchers.IO) { + httpRequest.invoke() + } + } catch (e: HttpException) { + val message = e.message + Log.d("ApiHandler", message.toString()) + throw when (e.code()) { + 400 -> BadRequestException( + message = message + ) + + 401 -> UnauthorizedException( + message = message, + ) + + 403 -> ForBiddenException( + message = message, + ) + + 404 -> NotFoundException( + message = message, + ) + + 409 -> ConflictException( + message = message, + ) + + 500, 501, 502, 503 -> ServerException( + message = message, + ) + + else -> OtherHttpException( + message = message, + code = e.code() + ) + } + } catch (e: SocketTimeoutException) { + throw TimeOutException(message = e.message) + } catch (e: UnknownHostException) { + throw NoInternetException() + } catch (e: TokenExpirationException) { + throw TokenExpirationException() + } catch (e: Exception) { + throw UnKnownException(message = e.message) + } + } +} \ No newline at end of file From 318d429d16aea99f7ba591bf4de6f66efb51d0a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=98=84=EC=84=9C?= Date: Mon, 15 Jan 2024 21:42:34 +0900 Subject: [PATCH 04/16] :sparkles: :: Add login model --- .../src/main/java/com/goms/domain/exception/.gitkeep | 0 .../src/main/java/com/goms/domain/usecase/login/.gitkeep | 0 .../java/com/goms/model/request/auth/LoginRequest.kt | 5 +++++ .../java/com/goms/model/response/auth/LoginResponse.kt | 9 +++++++++ 4 files changed, 14 insertions(+) delete mode 100644 core/domain/src/main/java/com/goms/domain/exception/.gitkeep delete mode 100644 core/domain/src/main/java/com/goms/domain/usecase/login/.gitkeep create mode 100644 core/model/src/main/java/com/goms/model/request/auth/LoginRequest.kt create mode 100644 core/model/src/main/java/com/goms/model/response/auth/LoginResponse.kt diff --git a/core/domain/src/main/java/com/goms/domain/exception/.gitkeep b/core/domain/src/main/java/com/goms/domain/exception/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/core/domain/src/main/java/com/goms/domain/usecase/login/.gitkeep b/core/domain/src/main/java/com/goms/domain/usecase/login/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/core/model/src/main/java/com/goms/model/request/auth/LoginRequest.kt b/core/model/src/main/java/com/goms/model/request/auth/LoginRequest.kt new file mode 100644 index 00000000..1082dd00 --- /dev/null +++ b/core/model/src/main/java/com/goms/model/request/auth/LoginRequest.kt @@ -0,0 +1,5 @@ +package com.goms.model.request.auth + +data class LoginRequest( + val code: String +) \ No newline at end of file diff --git a/core/model/src/main/java/com/goms/model/response/auth/LoginResponse.kt b/core/model/src/main/java/com/goms/model/response/auth/LoginResponse.kt new file mode 100644 index 00000000..fe9f39f4 --- /dev/null +++ b/core/model/src/main/java/com/goms/model/response/auth/LoginResponse.kt @@ -0,0 +1,9 @@ +package com.goms.model.response.auth + +data class LoginResponse( + val accessToken: String, + val refreshToken: String, + val accessTokenExp: String, + val refreshTokenExp: String, + val authority: String +) \ No newline at end of file From df82b2a1908f5b4964c9a73804bf1aae87c89b71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=98=84=EC=84=9C?= Date: Mon, 15 Jan 2024 21:42:54 +0900 Subject: [PATCH 05/16] :sparkles: :: Add login to AuthAPI --- .../src/main/java/com/goms/network/api/AuthAPI.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 core/network/src/main/java/com/goms/network/api/AuthAPI.kt diff --git a/core/network/src/main/java/com/goms/network/api/AuthAPI.kt b/core/network/src/main/java/com/goms/network/api/AuthAPI.kt new file mode 100644 index 00000000..7be273e3 --- /dev/null +++ b/core/network/src/main/java/com/goms/network/api/AuthAPI.kt @@ -0,0 +1,13 @@ +package com.goms.network.api + +import com.goms.model.request.auth.LoginRequest +import com.goms.model.response.auth.LoginResponse +import retrofit2.http.Body +import retrofit2.http.POST + +interface AuthAPI { + @POST("signin") + suspend fun login( + @Body body: LoginRequest + ): LoginResponse +} \ No newline at end of file From 6d61247a6c043a18d5113b51ba636d4a4487e4f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=98=84=EC=84=9C?= Date: Mon, 15 Jan 2024 21:43:05 +0900 Subject: [PATCH 06/16] :sparkles: :: Add login to AuthDataSource --- .../network/datasource/auth/AuthDataSource.kt | 9 ++++++++ .../datasource/auth/AuthDataSourceImpl.kt | 23 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 core/network/src/main/java/com/goms/network/datasource/auth/AuthDataSource.kt create mode 100644 core/network/src/main/java/com/goms/network/datasource/auth/AuthDataSourceImpl.kt diff --git a/core/network/src/main/java/com/goms/network/datasource/auth/AuthDataSource.kt b/core/network/src/main/java/com/goms/network/datasource/auth/AuthDataSource.kt new file mode 100644 index 00000000..452ed2d2 --- /dev/null +++ b/core/network/src/main/java/com/goms/network/datasource/auth/AuthDataSource.kt @@ -0,0 +1,9 @@ +package com.goms.network.datasource.auth + +import com.goms.model.request.auth.LoginRequest +import com.goms.model.response.auth.LoginResponse +import kotlinx.coroutines.flow.Flow + +interface AuthDataSource { + suspend fun login(body: LoginRequest): Flow +} \ No newline at end of file diff --git a/core/network/src/main/java/com/goms/network/datasource/auth/AuthDataSourceImpl.kt b/core/network/src/main/java/com/goms/network/datasource/auth/AuthDataSourceImpl.kt new file mode 100644 index 00000000..b2a1af98 --- /dev/null +++ b/core/network/src/main/java/com/goms/network/datasource/auth/AuthDataSourceImpl.kt @@ -0,0 +1,23 @@ +package com.goms.network.datasource.auth + +import com.goms.model.request.auth.LoginRequest +import com.goms.model.response.auth.LoginResponse +import com.goms.network.api.AuthAPI +import com.goms.network.util.GomsApiHandler +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.flowOn +import javax.inject.Inject + +class AuthDataSourceImpl @Inject constructor( + private val authAPI: AuthAPI +) : AuthDataSource { + override suspend fun login(body: LoginRequest): Flow = flow { + emit( + GomsApiHandler() + .httpRequest { authAPI.login(body = body) } + .sendRequest() + ) + }.flowOn(Dispatchers.IO) +} \ No newline at end of file From 9ad73c2744ce979f2f587e63541532ab0da6bf57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=98=84=EC=84=9C?= Date: Mon, 15 Jan 2024 21:43:13 +0900 Subject: [PATCH 07/16] :sparkles: :: Add login to AuthRepository --- .../goms/data/repository/auth/AuthRepository.kt | 9 +++++++++ .../data/repository/auth/AuthRepositoryImpl.kt | 15 +++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 core/data/src/main/java/com/goms/data/repository/auth/AuthRepository.kt create mode 100644 core/data/src/main/java/com/goms/data/repository/auth/AuthRepositoryImpl.kt diff --git a/core/data/src/main/java/com/goms/data/repository/auth/AuthRepository.kt b/core/data/src/main/java/com/goms/data/repository/auth/AuthRepository.kt new file mode 100644 index 00000000..d5c876fe --- /dev/null +++ b/core/data/src/main/java/com/goms/data/repository/auth/AuthRepository.kt @@ -0,0 +1,9 @@ +package com.goms.data.repository.auth + +import com.goms.model.request.auth.LoginRequest +import com.goms.model.response.auth.LoginResponse +import kotlinx.coroutines.flow.Flow + +interface AuthRepository { + suspend fun login(body: LoginRequest): Flow +} \ No newline at end of file diff --git a/core/data/src/main/java/com/goms/data/repository/auth/AuthRepositoryImpl.kt b/core/data/src/main/java/com/goms/data/repository/auth/AuthRepositoryImpl.kt new file mode 100644 index 00000000..2778e6e9 --- /dev/null +++ b/core/data/src/main/java/com/goms/data/repository/auth/AuthRepositoryImpl.kt @@ -0,0 +1,15 @@ +package com.goms.data.repository.auth + +import com.goms.model.request.auth.LoginRequest +import com.goms.model.response.auth.LoginResponse +import com.goms.network.datasource.auth.AuthDataSource +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject + +class AuthRepositoryImpl @Inject constructor( + private val remoteAuthDataSource: AuthDataSource +) : AuthRepository { + override suspend fun login(body: LoginRequest): Flow { + return remoteAuthDataSource.login(body = body) + } +} \ No newline at end of file From 69d0ef7a4d1d7ebe3ae6910aa7561cc374e1043f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=98=84=EC=84=9C?= Date: Mon, 15 Jan 2024 21:43:24 +0900 Subject: [PATCH 08/16] :sparkles: :: Add LoginUseCase --- .../main/java/com/goms/domain/auth/LoginUseCase.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 core/domain/src/main/java/com/goms/domain/auth/LoginUseCase.kt diff --git a/core/domain/src/main/java/com/goms/domain/auth/LoginUseCase.kt b/core/domain/src/main/java/com/goms/domain/auth/LoginUseCase.kt new file mode 100644 index 00000000..fecf6290 --- /dev/null +++ b/core/domain/src/main/java/com/goms/domain/auth/LoginUseCase.kt @@ -0,0 +1,13 @@ +package com.goms.domain.auth + +import com.goms.data.repository.auth.AuthRepository +import com.goms.model.request.auth.LoginRequest +import javax.inject.Inject + +class LoginUseCase @Inject constructor( + private val authRepository: AuthRepository +) { + suspend operator fun invoke(body: LoginRequest) = kotlin.runCatching { + authRepository.login(body = body) + } +} \ No newline at end of file From 743b821378ca53bae3a3476bc4685440edf1b360 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=98=84=EC=84=9C?= Date: Mon, 15 Jan 2024 21:43:35 +0900 Subject: [PATCH 09/16] :sparkles: :: Add base url --- core/network/build.gradle.kts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/core/network/build.gradle.kts b/core/network/build.gradle.kts index 296ace45..0d597640 100644 --- a/core/network/build.gradle.kts +++ b/core/network/build.gradle.kts @@ -1,3 +1,6 @@ +import java.io.FileInputStream +import java.util.Properties + @Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed plugins { id("goms.android.core") @@ -5,6 +8,14 @@ plugins { } android { + buildFeatures { + buildConfig = true + } + + defaultConfig { + buildConfigField("String", "BASE_URL", getApiKey("BASE_URL")) + } + namespace = "com.goms.network" } @@ -19,4 +30,11 @@ dependencies { implementation(libs.retrofit.core) implementation(libs.retrofit.kotlin.serialization) implementation(libs.retrofit.moshi.converter) +} + +fun getApiKey(propertyKey: String): String { + val propFile = rootProject.file("./local.properties") + val properties = Properties() + properties.load(FileInputStream(propFile)) + return properties.getProperty(propertyKey) } \ No newline at end of file From 4978585de914b358857c821d653cde519c925a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=98=84=EC=84=9C?= Date: Mon, 15 Jan 2024 21:44:15 +0900 Subject: [PATCH 10/16] :sparkles: :: Add login to module --- .../java/com/goms/data/di/RepositoryModule.kt | 17 +++++ .../java/com/goms/data/repository/.gitkeep | 0 .../com/goms/domain/usecase/sign_up/.gitkeep | 0 .../main/java/com/goms/network/api/.gitkeep | 0 .../java/com/goms/network/datasource/.gitkeep | 0 .../java/com/goms/network/di/NetworkModule.kt | 64 +++++++++++++++++++ .../goms/network/di/RemoteDataSourceModule.kt | 17 +++++ 7 files changed, 98 insertions(+) create mode 100644 core/data/src/main/java/com/goms/data/di/RepositoryModule.kt delete mode 100644 core/data/src/main/java/com/goms/data/repository/.gitkeep delete mode 100644 core/domain/src/main/java/com/goms/domain/usecase/sign_up/.gitkeep delete mode 100644 core/network/src/main/java/com/goms/network/api/.gitkeep delete mode 100644 core/network/src/main/java/com/goms/network/datasource/.gitkeep create mode 100644 core/network/src/main/java/com/goms/network/di/NetworkModule.kt create mode 100644 core/network/src/main/java/com/goms/network/di/RemoteDataSourceModule.kt diff --git a/core/data/src/main/java/com/goms/data/di/RepositoryModule.kt b/core/data/src/main/java/com/goms/data/di/RepositoryModule.kt new file mode 100644 index 00000000..661a6c85 --- /dev/null +++ b/core/data/src/main/java/com/goms/data/di/RepositoryModule.kt @@ -0,0 +1,17 @@ +package com.goms.data.di + +import com.goms.data.repository.auth.AuthRepository +import com.goms.data.repository.auth.AuthRepositoryImpl +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent + +@Module +@InstallIn(SingletonComponent::class) +abstract class RepositoryModule { + @Binds + abstract fun bindAuthRepository( + authRepositoryImpl: AuthRepositoryImpl + ): AuthRepository +} \ No newline at end of file diff --git a/core/data/src/main/java/com/goms/data/repository/.gitkeep b/core/data/src/main/java/com/goms/data/repository/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/core/domain/src/main/java/com/goms/domain/usecase/sign_up/.gitkeep b/core/domain/src/main/java/com/goms/domain/usecase/sign_up/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/core/network/src/main/java/com/goms/network/api/.gitkeep b/core/network/src/main/java/com/goms/network/api/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/core/network/src/main/java/com/goms/network/datasource/.gitkeep b/core/network/src/main/java/com/goms/network/datasource/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/core/network/src/main/java/com/goms/network/di/NetworkModule.kt b/core/network/src/main/java/com/goms/network/di/NetworkModule.kt new file mode 100644 index 00000000..98543334 --- /dev/null +++ b/core/network/src/main/java/com/goms/network/di/NetworkModule.kt @@ -0,0 +1,64 @@ +package com.goms.network.di + +import android.util.Log +import com.goms.network.BuildConfig +import com.goms.network.api.AuthAPI +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import okhttp3.CookieJar +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import retrofit2.Retrofit +import retrofit2.converter.moshi.MoshiConverterFactory +import java.util.concurrent.TimeUnit +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +object NetworkModule { + @Provides + fun provideHttpLoggingInterceptor(): HttpLoggingInterceptor = + HttpLoggingInterceptor { message -> Log.v("HTTP", message) } + .setLevel(HttpLoggingInterceptor.Level.BODY) + + @Provides + @Singleton + fun provideOkhttpClient( + httpLoggingInterceptor: HttpLoggingInterceptor + ): OkHttpClient { + return OkHttpClient.Builder() + .cookieJar(CookieJar.NO_COOKIES) + .connectTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .writeTimeout(30, TimeUnit.SECONDS) + .addInterceptor(httpLoggingInterceptor) + .build() + } + + @Provides + @Singleton + fun provideConverterFactory(): MoshiConverterFactory { + return MoshiConverterFactory.create() + } + + @Provides + @Singleton + fun provideRetrofitInstance( + okHttpClient: OkHttpClient, + gsonConverterFactory: MoshiConverterFactory, + ): Retrofit { + return Retrofit.Builder() + .baseUrl(BuildConfig.BASE_URL) + .client(okHttpClient) + .addConverterFactory(gsonConverterFactory) + .build() + } + + @Provides + @Singleton + fun provideAuthAPI(retrofit: Retrofit): AuthAPI { + return retrofit.create(AuthAPI::class.java) + } +} \ No newline at end of file diff --git a/core/network/src/main/java/com/goms/network/di/RemoteDataSourceModule.kt b/core/network/src/main/java/com/goms/network/di/RemoteDataSourceModule.kt new file mode 100644 index 00000000..b6b2bd64 --- /dev/null +++ b/core/network/src/main/java/com/goms/network/di/RemoteDataSourceModule.kt @@ -0,0 +1,17 @@ +package com.goms.network.di + +import com.goms.network.datasource.auth.AuthDataSource +import com.goms.network.datasource.auth.AuthDataSourceImpl +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent + +@Module +@InstallIn(SingletonComponent::class) +abstract class RemoteDataSourceModule { + @Binds + abstract fun bindAuthDataSource( + authDataSourceImpl: AuthDataSourceImpl + ): AuthDataSource +} \ No newline at end of file From 12c781eafba7bd35aeab641f9e7d98f0b5241fcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=98=84=EC=84=9C?= Date: Mon, 15 Jan 2024 22:22:06 +0900 Subject: [PATCH 11/16] :truck: :: Move exception --- .../src/main/java/com/goms/common}/exception/HttpException.kt | 2 +- .../main/java/com/goms/common}/exception/InternetException.kt | 2 +- .../java/com/goms/common}/exception/TokenExpirationException.kt | 2 +- .../src/main/java/com/goms/network/util/GomsApiHandler.kt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename core/{network/src/main/java/com/goms/network => common/src/main/java/com/goms/common}/exception/HttpException.kt (97%) rename core/{network/src/main/java/com/goms/network => common/src/main/java/com/goms/common}/exception/InternetException.kt (85%) rename core/{network/src/main/java/com/goms/network => common/src/main/java/com/goms/common}/exception/TokenExpirationException.kt (84%) diff --git a/core/network/src/main/java/com/goms/network/exception/HttpException.kt b/core/common/src/main/java/com/goms/common/exception/HttpException.kt similarity index 97% rename from core/network/src/main/java/com/goms/network/exception/HttpException.kt rename to core/common/src/main/java/com/goms/common/exception/HttpException.kt index 2271fc89..90eae77e 100644 --- a/core/network/src/main/java/com/goms/network/exception/HttpException.kt +++ b/core/common/src/main/java/com/goms/common/exception/HttpException.kt @@ -1,4 +1,4 @@ -package com.goms.network.exception +package com.goms.common.exception // 400: 올바르지 않은 요청 class BadRequestException( diff --git a/core/network/src/main/java/com/goms/network/exception/InternetException.kt b/core/common/src/main/java/com/goms/common/exception/InternetException.kt similarity index 85% rename from core/network/src/main/java/com/goms/network/exception/InternetException.kt rename to core/common/src/main/java/com/goms/common/exception/InternetException.kt index ff3aba9c..7de35e6b 100644 --- a/core/network/src/main/java/com/goms/network/exception/InternetException.kt +++ b/core/common/src/main/java/com/goms/common/exception/InternetException.kt @@ -1,4 +1,4 @@ -package com.goms.network.exception +package com.goms.common.exception class NoInternetException : RuntimeException() { override val message: String diff --git a/core/network/src/main/java/com/goms/network/exception/TokenExpirationException.kt b/core/common/src/main/java/com/goms/common/exception/TokenExpirationException.kt similarity index 84% rename from core/network/src/main/java/com/goms/network/exception/TokenExpirationException.kt rename to core/common/src/main/java/com/goms/common/exception/TokenExpirationException.kt index 8d3f27e9..129b2efd 100644 --- a/core/network/src/main/java/com/goms/network/exception/TokenExpirationException.kt +++ b/core/common/src/main/java/com/goms/common/exception/TokenExpirationException.kt @@ -1,4 +1,4 @@ -package com.goms.network.exception +package com.goms.common.exception import java.io.IOException diff --git a/core/network/src/main/java/com/goms/network/util/GomsApiHandler.kt b/core/network/src/main/java/com/goms/network/util/GomsApiHandler.kt index d8ad9832..1cc000e5 100644 --- a/core/network/src/main/java/com/goms/network/util/GomsApiHandler.kt +++ b/core/network/src/main/java/com/goms/network/util/GomsApiHandler.kt @@ -1,7 +1,7 @@ package com.goms.network.util import android.util.Log -import com.goms.network.exception.* +import com.goms.common.exception.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import retrofit2.HttpException From 386b9865cee841ccf0b391c7657dd15865688685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=98=84=EC=84=9C?= Date: Mon, 15 Jan 2024 22:23:57 +0900 Subject: [PATCH 12/16] :sparkles: :: Add Event --- .../src/main/java/com/goms/common/Event.kt | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 core/common/src/main/java/com/goms/common/Event.kt diff --git a/core/common/src/main/java/com/goms/common/Event.kt b/core/common/src/main/java/com/goms/common/Event.kt new file mode 100644 index 00000000..6bb81fc3 --- /dev/null +++ b/core/common/src/main/java/com/goms/common/Event.kt @@ -0,0 +1,38 @@ +package com.goms.common + +sealed class Event( + val data: T? = null +) { + + object Loading : Event() + + // 20X: 성공 + class Success(data: T? = null) : Event(data = data) + + // 400: 올바르지 않은 요청 + object BadRequest : Event() + + // 401: 비인증 상태 + object Unauthorized : Event() + + // 403: 권한이 없음 + object ForBidden : Event() + + // 404: 요청한 리소스를 찾을 수 없음 + object NotFound : Event() + + // 406: 클라이언트가 허용되지 않는 규격을 요청 + object NotAcceptable : Event() + + // 408: 요청시간초과 + object TimeOut : Event() + + // 409: 충돌발생 + object Conflict : Event() + + // 50X: 서버에러 + object Server : Event() + + // 예상하지 못한 에러 + object UnKnown : Event() +} \ No newline at end of file From 7546777205f30605e51a7515a51405fcf2f9311a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=98=84=EC=84=9C?= Date: Mon, 15 Jan 2024 22:24:09 +0900 Subject: [PATCH 13/16] :sparkles: :: Add errorHandling --- .../java/com/goms/common/errorHandling.kt | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 core/common/src/main/java/com/goms/common/errorHandling.kt diff --git a/core/common/src/main/java/com/goms/common/errorHandling.kt b/core/common/src/main/java/com/goms/common/errorHandling.kt new file mode 100644 index 00000000..e24bacdd --- /dev/null +++ b/core/common/src/main/java/com/goms/common/errorHandling.kt @@ -0,0 +1,67 @@ +package com.goms.common + +import android.util.Log +import com.goms.common.exception.* + +suspend fun Throwable.errorHandling( + badRequestAction: suspend () -> Unit = {}, + unauthorizedAction: suspend () -> Unit = {}, + forBiddenAction: suspend () -> Unit = {}, + notFoundAction: suspend () -> Unit = {}, + notAcceptableAction: suspend () -> Unit = {}, + timeOutAction: suspend () -> Unit = {}, + conflictAction: suspend () -> Unit = {}, + serverAction: suspend () -> Unit = {}, + unknownAction: suspend () -> Unit = {}, +): Event = + when (this) { + is BadRequestException -> { + errorLog("BadRequestException", message) + badRequestAction() + Event.BadRequest + } + is UnauthorizedException, is TokenExpirationException -> { + errorLog("UnauthorizedException", message) + unauthorizedAction() + Event.Unauthorized + } + is ForBiddenException -> { + errorLog("ForBiddenException", message) + forBiddenAction() + Event.ForBidden + } + is NotFoundException -> { + errorLog("NotFoundException", message) + notFoundAction() + Event.NotFound + } + is NotAcceptableException -> { + errorLog("NotAcceptableException", message) + notAcceptableAction() + Event.NotAcceptable + } + is TimeOutException -> { + errorLog("TimeOutException", message) + timeOutAction() + Event.TimeOut + } + is ConflictException -> { + errorLog("ConflictException", message) + conflictAction() + Event.Conflict + } + is ServerException -> { + errorLog("ServerException", message) + serverAction() + Event.Server + } + else -> { + errorLog("UnKnownException", message) + unknownAction() + Event.UnKnown + } + } + +private fun errorLog(tag: String, msg: String?) { + Log.d("ErrorHandling-$tag", msg ?: "알 수 없는 오류") +} \ No newline at end of file From 9f9364c2c5d52e1fc040219fde9c519ba410d75a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=98=84=EC=84=9C?= Date: Mon, 15 Jan 2024 23:51:22 +0900 Subject: [PATCH 14/16] :bug: :: Fix url --- core/network/src/main/java/com/goms/network/api/AuthAPI.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/network/src/main/java/com/goms/network/api/AuthAPI.kt b/core/network/src/main/java/com/goms/network/api/AuthAPI.kt index 7be273e3..e61ed829 100644 --- a/core/network/src/main/java/com/goms/network/api/AuthAPI.kt +++ b/core/network/src/main/java/com/goms/network/api/AuthAPI.kt @@ -6,7 +6,7 @@ import retrofit2.http.Body import retrofit2.http.POST interface AuthAPI { - @POST("signin") + @POST("/api/v2/auth/signin") suspend fun login( @Body body: LoginRequest ): LoginResponse From 73f04be98da5d8ec2c5d93d8bc007db6bd00501c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=98=84=EC=84=9C?= Date: Mon, 15 Jan 2024 23:56:14 +0900 Subject: [PATCH 15/16] :sparkles: :: Add login to AuthViewModel --- .../com/goms/login/viewmodel/AuthViewModel.kt | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 feature/login/src/main/java/com/goms/login/viewmodel/AuthViewModel.kt diff --git a/feature/login/src/main/java/com/goms/login/viewmodel/AuthViewModel.kt b/feature/login/src/main/java/com/goms/login/viewmodel/AuthViewModel.kt new file mode 100644 index 00000000..d160cb63 --- /dev/null +++ b/feature/login/src/main/java/com/goms/login/viewmodel/AuthViewModel.kt @@ -0,0 +1,37 @@ +package com.goms.login.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.goms.common.Event +import com.goms.common.errorHandling +import com.goms.domain.auth.LoginUseCase +import com.goms.model.request.auth.LoginRequest +import com.goms.model.response.auth.LoginResponse +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class AuthViewModel @Inject constructor( + private val loginUseCase: LoginUseCase +) : ViewModel() { + private val _loginResponse = MutableStateFlow>(Event.Loading) + val loginResponse = _loginResponse.asStateFlow() + + fun login(body: LoginRequest) = viewModelScope.launch { + loginUseCase( + body = body + ).onSuccess { + it.catch { remoteError -> + _loginResponse.value = remoteError.errorHandling() + }.collect { response -> + _loginResponse.value = Event.Success(data = response) + } + }.onFailure { + _loginResponse.value = it.errorHandling() + } + } +} \ No newline at end of file From 6db8e6d46437b5f3a132d1fa0ab5b57960f344b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=ED=98=84=EC=84=9C?= Date: Mon, 15 Jan 2024 23:56:44 +0900 Subject: [PATCH 16/16] :sparkles: :: Write the logic login --- .../main/java/com/goms/login/LoginScreen.kt | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/feature/login/src/main/java/com/goms/login/LoginScreen.kt b/feature/login/src/main/java/com/goms/login/LoginScreen.kt index a6a2c887..89f69a2a 100644 --- a/feature/login/src/main/java/com/goms/login/LoginScreen.kt +++ b/feature/login/src/main/java/com/goms/login/LoginScreen.kt @@ -17,6 +17,8 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import com.goms.common.Event import com.goms.design_system.component.button.AuthButton import com.goms.design_system.component.text.LinkText import com.goms.design_system.component.view.GAuthWebView @@ -24,17 +26,31 @@ import com.goms.design_system.icon.GomsIcon import com.goms.design_system.theme.GomsTheme import com.goms.design_system.util.lockScreenOrientation import com.goms.login.component.LoginText +import com.goms.login.viewmodel.AuthViewModel +import com.goms.model.request.auth.LoginRequest @Composable fun LoginRoute( - onEmailLoginClick: () -> Unit + onEmailLoginClick: () -> Unit, + viewModel: AuthViewModel = hiltViewModel() ) { LoginScreen( onEmailLoginClick = onEmailLoginClick, - loginCallBack = {} + loginCallBack = { code -> + viewModel.login(body = LoginRequest(code)) + } ) } +suspend fun login(viewModel: AuthViewModel) { + viewModel.loginResponse.collect { + when (it) { + is Event.Success -> {} + else -> {} + } + } +} + @Composable fun LoginScreen( onEmailLoginClick: () -> Unit,