Skip to content

Commit

Permalink
[TNT-114] chore: conflict 해결
Browse files Browse the repository at this point in the history
  • Loading branch information
SeonJeongk committed Jan 26, 2025
2 parents 01e87e7 + 1809f19 commit a193d4e
Show file tree
Hide file tree
Showing 69 changed files with 811 additions and 147 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/android-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ jobs:
distribution: zulu
cache: gradle

- name: add local.properties
run: |
echo RELEASE_BASE_API_URL=\"${{ secrets.RELEASE_BASE_API_URL }}\" >> ./local.properties
echo DEBUG_BASE_API_URL=\"${{ secrets.DEBUG_BASE_API_URL }}\" >> ./local.properties
echo KAKAO_NATIVE_APP_KEY=${{ secrets.KAKAO_NATIVE_APP_KEY }} >> ./local.properties
- name: Grant execute permission for gradlew
run: chmod +x gradlew

Expand Down
9 changes: 9 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties

private val kakaoNativeAppKey: String =
gradleLocalProperties(rootDir, providers).getProperty("KAKAO_NATIVE_APP_KEY")

plugins {
id("tnt.android.application")
id("tnt.android.compose")
Expand All @@ -15,6 +20,8 @@ android {
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

buildConfigField("String", "KAKAO_NATIVE_APP_KEY", "\"${kakaoNativeAppKey}\"")
}

buildTypes {
Expand Down Expand Up @@ -48,6 +55,8 @@ dependencies {
implementation(projects.data.network)
implementation(projects.data.storage)
implementation(projects.data.repository)
implementation(projects.data.session)

implementation(libs.androidx.activity.compose)
implementation(libs.kakao.user)
}
4 changes: 3 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.TnT"
tools:targetApi="31" />
tools:targetApi="31" >

</application>

</manifest>
9 changes: 8 additions & 1 deletion app/src/main/java/co/kr/tnt/TnTApplication.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package co.kr.tnt

import android.app.Application
import com.kakao.sdk.common.KakaoSdk
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class TnTApplication : Application()
class TnTApplication : Application() {
override fun onCreate() {
super.onCreate()

KakaoSdk.init(this, BuildConfig.KAKAO_NATIVE_APP_KEY)
}
}
1 change: 1 addition & 0 deletions core/login/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
19 changes: 19 additions & 0 deletions core/login/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import co.kr.tnt.setNamespace
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties

plugins {
id("tnt.android.library")
}

android {
setNamespace("core.login")

defaultConfig {
manifestPlaceholders["KAKAO_NATIVE_APP_KEY"] =
gradleLocalProperties(rootDir, providers).getProperty("KAKAO_NATIVE_APP_KEY")
}
}

dependencies {
implementation(libs.kakao.user)
}
20 changes: 20 additions & 0 deletions core/login/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<application>
<activity
android:name="com.kakao.sdk.auth.AuthCodeHandlerActivity"
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data
android:host="oauth"
android:scheme="kakao${KAKAO_NATIVE_APP_KEY}" />
</intent-filter>
</activity>
</application>
</manifest>
5 changes: 5 additions & 0 deletions core/login/src/main/java/co/kr/tnt/login/LoginAccessToken.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package co.kr.tnt.login

interface LoginAccessToken {
val value: String
}
9 changes: 9 additions & 0 deletions core/login/src/main/java/co/kr/tnt/login/LoginException.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package co.kr.tnt.login

sealed class LoginException(override val message: String?) : Exception(message) {
/** 유저가 뒤로가기 동작 등으로 로그인 자체를 취소한 경우 */
data class CancelException(override val message: String?) : LoginException(message)

/** 유저가 실제 로그인을 시도하였으나 SDK의 문제로 로그인에 실패한 경우 */
data class AuthException(override val message: String?) : LoginException(message)
}
9 changes: 9 additions & 0 deletions core/login/src/main/java/co/kr/tnt/login/LoginSdk.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package co.kr.tnt.login

import android.content.Context

interface LoginSdk {
suspend fun login(context: Context): Result<LoginAccessToken>
suspend fun logout(): Result<Unit>
suspend fun unlink(): Result<Unit>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package co.kr.tnt.login.kakao

import co.kr.tnt.login.LoginAccessToken

@JvmInline
value class KakaoAccessToken(override val value: String) : LoginAccessToken
78 changes: 78 additions & 0 deletions core/login/src/main/java/co/kr/tnt/login/kakao/KakaoLoginSdk.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package co.kr.tnt.login.kakao

import android.content.Context
import co.kr.tnt.login.LoginAccessToken
import co.kr.tnt.login.LoginException.AuthException
import co.kr.tnt.login.LoginException.CancelException
import co.kr.tnt.login.LoginSdk
import com.kakao.sdk.auth.model.OAuthToken
import com.kakao.sdk.common.model.ClientError
import com.kakao.sdk.common.model.ClientErrorCause
import com.kakao.sdk.user.UserApiClient
import kotlinx.coroutines.suspendCancellableCoroutine
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException

@Singleton
class KakaoLoginSdk @Inject constructor() : LoginSdk {
override suspend fun login(context: Context): Result<LoginAccessToken> = runCatching {
suspendCancellableCoroutine { continuation ->
val callback: (OAuthToken?, Throwable?) -> Unit = callback@{ token, throwable ->
if (!continuation.isActive) {
return@callback
}

when {
throwable != null -> {
if (throwable is ClientError && throwable.reason == ClientErrorCause.Cancelled) {
continuation.resumeWithException(CancelException(throwable.message))
return@callback
}

continuation.resumeWithException(AuthException(throwable.message))
}

token != null -> continuation.resume(KakaoAccessToken(token.accessToken))
}
}

val userApiClient = UserApiClient.instance

if (userApiClient.isKakaoTalkLoginAvailable(context)) {
// 카카오톡 로그인
userApiClient.loginWithKakaoTalk(context, callback = callback)
} else {
// 카카오톡 웹 로그인
userApiClient.loginWithKakaoAccount(context, callback = callback)
}
}
}

override suspend fun logout(): Result<Unit> = runCatching {
suspendCancellableCoroutine { continuation ->
val userApiClient = UserApiClient.instance

userApiClient.logout { throwable ->
when {
throwable != null -> continuation.resumeWithException(AuthException(throwable.message))
else -> continuation.resume(Unit)
}
}
}
}

override suspend fun unlink(): Result<Unit> = runCatching {
suspendCancellableCoroutine { continuation ->
val userApiClient = UserApiClient.instance

userApiClient.unlink { throwable ->
when {
throwable != null -> continuation.resumeWithException(AuthException(throwable.message))
else -> continuation.resume(Unit)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,11 @@ sealed interface Route {

@Serializable
data class TraineeConnect(val isFromMyPage: Boolean) : Route

@Serializable
data class RoleSelection(
val authId: String,
val authType: String,
val email: String,
) : Route
}
19 changes: 19 additions & 0 deletions data/network/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import co.kr.tnt.setNamespace
import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties

plugins {
id("tnt.android.library")
Expand All @@ -12,6 +13,24 @@ android {
buildFeatures {
buildConfig = true
}

buildTypes {
debug {
buildConfigField(
"String",
"BASE_API_URL",
gradleLocalProperties(rootDir, providers).getProperty("DEBUG_BASE_API_URL"),
)
}

release {
buildConfigField(
"String",
"BASE_API_URL",
gradleLocalProperties(rootDir, providers).getProperty("RELEASE_BASE_API_URL"),
)
}
}
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package co.kr.data.network.authenticator

import co.kr.data.network.monitor.NetworkSessionMonitor
import okhttp3.Authenticator
import okhttp3.Request
import okhttp3.Response
import okhttp3.Route
import javax.inject.Inject

// 구현체 주입 여부 재검토 필요.
internal class Authenticator @Inject constructor(
private val networkSessionMonitor: NetworkSessionMonitor,
) : Authenticator {
override fun authenticate(route: Route?, response: Response): Request? {
networkSessionMonitor.sendExpired()
return null
}
}
17 changes: 17 additions & 0 deletions data/network/src/main/java/co/kr/data/network/di/MonitorModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package co.kr.data.network.di

import co.kr.data.network.monitor.NetworkSessionMonitor
import co.kr.tnt.domain.monitor.SessionMonitor
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent

@Module
@InstallIn(SingletonComponent::class)
abstract class MonitorModule {
@Binds
abstract fun bindsSessionMonitor(
monitor: NetworkSessionMonitor,
): SessionMonitor
}
17 changes: 12 additions & 5 deletions data/network/src/main/java/co/kr/data/network/di/NetworkModule.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package co.kr.data.network.di

import co.kr.data.network.service.TnTService
import co.kr.data.network.authenticator.Authenticator
import co.kr.data.network.interceptor.SessionInterceptor
import co.kr.data.network.service.ApiService
import co.kr.tnt.data.network.BuildConfig
import dagger.Module
import dagger.Provides
Expand All @@ -23,25 +25,29 @@ internal object NetworkModule {

@Provides
@Singleton
fun provideTnTService(
fun provideApiService(
okHttpClient: OkHttpClient,
converterFactory: Converter.Factory,
): TnTService {
): ApiService {
return Retrofit.Builder()
.baseUrl("https://TODO") // TODO
.baseUrl(BuildConfig.BASE_API_URL)
.addConverterFactory(converterFactory)
.client(okHttpClient).build()
.create(TnTService::class.java)
.create(ApiService::class.java)
}

@Provides
@Singleton
fun provideOkHttpClient(
sessionInterceptor: SessionInterceptor,
loggingInterceptor: HttpLoggingInterceptor,
authenticator: Authenticator,
): OkHttpClient = OkHttpClient.Builder()
.connectTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS)
.readTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS)
.addInterceptor(sessionInterceptor)
.addInterceptor(loggingInterceptor)
.authenticator(authenticator)
.build()

@Provides
Expand All @@ -55,6 +61,7 @@ internal object NetworkModule {
fun provideJson(): Json = Json {
ignoreUnknownKeys = true
coerceInputValues = true
encodeDefaults = true
}

@Provides
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package co.kr.data.network.interceptor

import co.kr.data.network.provider.SessionProvider
import kotlinx.coroutines.runBlocking
import okhttp3.Interceptor
import okhttp3.Response
import javax.inject.Inject

internal class SessionInterceptor @Inject constructor(
private val sessionProvider: SessionProvider,
) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val originRequest = chain.request()
val requestBuilder = originRequest.newBuilder()

requestBuilder.addHeader(
"AUTHORIZATION",
"SESSION-ID ${runBlocking { sessionProvider.getSessionId() }}",
)

return chain.proceed(requestBuilder.build())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package co.kr.data.network.model

import co.kr.tnt.domain.model.AuthType
import kotlinx.serialization.Serializable

// TODO fcm token
@Serializable
data class LoginRequest(
val socialType: AuthType,
val fcmToken: String = "EMPTY",
val socialAccessToken: String,
)
Loading

0 comments on commit a193d4e

Please sign in to comment.