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

feat: token interceptor 구현 #18

Merged
merged 12 commits into from
Feb 28, 2024
Merged
6 changes: 3 additions & 3 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[*.{kt,kts}]
ij_kotlin_allow_trailing_comma=true
ij_kotlin_allow_trailing_comma_on_call_site=true
ktlint_function_naming_ignore_when_annotated_with=Composable, Test
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma_on_call_site = true
ktlint_function_naming_ignore_when_annotated_with = Composable, Test
3 changes: 3 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
## 관련 이슈번호

<br/> close #

## 작업 사항

<br/>

## 기타 사항

<br/>
3 changes: 2 additions & 1 deletion .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: set up JDK 17
Expand Down Expand Up @@ -45,3 +45,4 @@ jobs:

- name: Run ktlint
run: ./gradlew ktlintCheck

5 changes: 5 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,10 @@ android {

dependencies {
implementation(project(":feature:login"))
implementation(project(":core:interceptor"))
implementation(project(":core:data"))
implementation(project(":core:network"))
implementation(project(":core:datastore"))
implementation(project(":core:domain"))
implementation(project(":core:designsystem"))
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package com.withpeace.withpeace

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.*
import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
Expand Down
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class WithPeaceApplication: Application() {
class WithPeaceApplication : Application() {
}
3 changes: 1 addition & 2 deletions app/src/test/java/com/withpeace/withpeace/ExampleUnitTest.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package com.withpeace.withpeace

import org.junit.Assert.assertEquals
import org.junit.Test

import org.junit.Assert.*

/**
* Example local unit test, which will execute on the development machine (host).
*
Expand Down
7 changes: 5 additions & 2 deletions build-logic/src/main/kotlin/convention.feature.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ plugins {
id("convention.android.compose")
id("convention.android.hilt")
}
dependencies {

dependencies{
implementation(project(":core:data"))
implementation(project(":core:domain"))
implementation(project(":core:designsystem"))
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package com.withpeace.withpeace.core.data

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.*
import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
Expand Down
2 changes: 1 addition & 1 deletion core/data/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.withpeace.withpeace.core.data.di

import com.withpeace.withpeace.core.data.repository.DefaultTokenRepository
import com.withpeace.withpeace.core.domain.repository.TokenRepository
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
interface RepositoryModule {

@Binds
@Singleton
fun bindsTokenRepository(defaultTokenRepository: DefaultTokenRepository): TokenRepository
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ import com.withpeace.withpeace.core.network.di.response.TokenResponse
fun TokenResponse.toDomain(): Token {
return Token(
accessToken = accessToken,
refreshToken = refreshToken
refreshToken = refreshToken,
)
}
Original file line number Diff line number Diff line change
@@ -1,49 +1,74 @@
package com.withpeace.withpeace.core.data.repository

import com.skydoves.sandwich.message
import com.skydoves.sandwich.messageOrNull
import com.skydoves.sandwich.suspendMapSuccess
import com.skydoves.sandwich.suspendOnError
import com.skydoves.sandwich.suspendOnFailure
import com.withpeace.withpeace.core.data.mapper.toDomain
import com.withpeace.withpeace.core.datastore.dataStore.TokenPreferenceDataSource
import com.withpeace.withpeace.core.domain.model.Token
import com.withpeace.withpeace.core.domain.repository.TokenRepository
import com.withpeace.withpeace.core.network.di.request.SignUpRequest
import com.withpeace.withpeace.core.network.di.service.AuthService
import com.withpeace.withpeace.core.network.di.service.LoginService
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import javax.inject.Inject

class DefaultTokenRepository
@Inject
constructor(
private val tokenPreferenceDataSource: TokenPreferenceDataSource,
private val loginService: LoginService,
private val authService: AuthService,
) : TokenRepository {
override fun getAccessToken(): Flow<String?> {
return tokenPreferenceDataSource.accessToken
}

class DefaultTokenRepository @Inject constructor(
private val tokenPreferenceDataSource: TokenPreferenceDataSource,
private val authService: AuthService
) : TokenRepository {
override fun getRefreshToken(): Flow<String?> {
return tokenPreferenceDataSource.refreshToken
}

override fun getAccessToken(): Flow<String?> {
return tokenPreferenceDataSource.accessToken
}
override suspend fun updateAccessToken(accessToken: String) {
tokenPreferenceDataSource.updateAccessToken(accessToken)
}

override fun getRefreshToken(): Flow<String?> {
return tokenPreferenceDataSource.refreshToken
}
override suspend fun updateRefreshToken(refreshToken: String) {
tokenPreferenceDataSource.updateRefreshToken(refreshToken)
}

override suspend fun updateAccessToken(accessToken: String) {
tokenPreferenceDataSource.updateAccessToken(accessToken)
}
override suspend fun signUp(
email: String,
nickname: String,
deviceToken: String?,
) {
authService.signUp(
SignUpRequest(
email = email,
nickname = nickname,
deviceToken = deviceToken,
),
)
}

override suspend fun updateRefreshToken(refreshToken: String) {
tokenPreferenceDataSource.updateRefreshToken(refreshToken)
}
override fun googleLogin(
idToken: String,
onError: (String?) -> Unit,
): Flow<Token> =
flow {
loginService.googleLogin(AUTHORIZATION_FORMAT.format(idToken))
.suspendMapSuccess {
emit(data.toDomain())
updateAccessToken(data.accessToken)
updateRefreshToken(data.refreshToken)
}.suspendOnFailure {
onError(messageOrNull)
}
}.flowOn(Dispatchers.IO)

override fun googleLogin(onError: (String?) -> Unit): Flow<Token> = flow {
authService.googleLogin()
.suspendMapSuccess {
emit(data.toDomain())
updateAccessToken(data.accessToken)
updateRefreshToken(data.refreshToken)
}.suspendOnError {
onError(message())
}
}.flowOn(Dispatchers.IO)
}
companion object {
private const val AUTHORIZATION_FORMAT = "Bearer %s"
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package com.withpeace.withpeace.core.data

import org.junit.Assert.assertEquals
import org.junit.Test

import org.junit.Assert.*

/**
* Example local unit test, which will execute on the development machine (host).
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package com.withpeace.withpeace.core.datastore

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.*
import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
Expand Down
2 changes: 1 addition & 1 deletion core/datastore/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,31 @@ import javax.inject.Inject
import javax.inject.Named

class DefaultTokenPreferenceDataSource @Inject constructor(
@Named("auth") private val dataStore: DataStore<Preferences>
): TokenPreferenceDataSource {
@Named("auth") private val dataStore: DataStore<Preferences>,
) : TokenPreferenceDataSource {

override val accessToken: Flow<String?> = dataStore.data.map{ preferences ->
override val accessToken: Flow<String?> = dataStore.data.map { preferences ->
preferences[ACCESS_TOKEN]
}

override val refreshToken: Flow<String?> = dataStore.data.map{preferences ->
override val refreshToken: Flow<String?> = dataStore.data.map { preferences ->
preferences[REFRESH_TOKEN]
}

override suspend fun updateAccessToken(accessToken: String) {
dataStore.edit{preferences->
override suspend fun updateAccessToken(accessToken: String) {
dataStore.edit { preferences ->
preferences[ACCESS_TOKEN] = accessToken
}
}

override suspend fun updateRefreshToken(refreshToken: String) {
dataStore.edit{preferences->
dataStore.edit { preferences ->
preferences[REFRESH_TOKEN] = refreshToken
}
}

companion object{
private val ACCESS_TOKEN= stringPreferencesKey("ACCESS_TOKEN")
private val REFRESH_TOKEN= stringPreferencesKey("REFRESH_TOKEN")
companion object {
private val ACCESS_TOKEN = stringPreferencesKey("ACCESS_TOKEN")
private val REFRESH_TOKEN = stringPreferencesKey("REFRESH_TOKEN")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ object DataStoreModule {
@Singleton
@Named("auth")
fun providesTokenDataStore(
@ApplicationContext context: Context
@ApplicationContext context: Context,
): DataStore<Preferences> = context.authDataStore
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.withpeace.withpeace.core.data.di
package com.withpeace.withpeace.core.datastore.di

import com.withpeace.withpeace.core.datastore.dataStore.DefaultTokenPreferenceDataSource
import com.withpeace.withpeace.core.datastore.dataStore.TokenPreferenceDataSource
Expand All @@ -10,9 +10,11 @@ import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
abstract class DataSourceModule {
interface PreferenceDataSourceModule {

@Binds
@Singleton
abstract fun bindsTokenDataSource(tokenPreferenceDataSource: DefaultTokenPreferenceDataSource): TokenPreferenceDataSource
fun bindsTokenPreferenceDataSource(
defaultTokenPreferenceDataSource: DefaultTokenPreferenceDataSource,
): TokenPreferenceDataSource
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package com.withpeace.withpeace.core.datastore

import org.junit.Assert.assertEquals
import org.junit.Test

import org.junit.Assert.*

/**
* Example local unit test, which will execute on the development machine (host).
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ package com.withpeace.withpeace.core.domain.model

data class Token(
val accessToken: String,
val refreshToken: String
val refreshToken: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ interface TokenRepository {

suspend fun updateRefreshToken(refreshToken: String)

fun googleLogin(onError: (message: String?) -> Unit): Flow<Token>
suspend fun signUp(email: String, nickname: String, deviceToken: String?)

fun googleLogin(idToken: String, onError: (message: String?) -> Unit): Flow<Token>
}
1 change: 1 addition & 0 deletions core/interceptor/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
Loading
Loading