Skip to content

Commit

Permalink
feat: token interceptor 구현 (#18)
Browse files Browse the repository at this point in the history
* feat: AuthInterceptor 구현 중

* chore: 코드 포맷

* feat: 네트워크 통신을 위한 인터셉터 구현

* feat: 구글 로그인을 통해 access 토근을 받아오는 로직 구현

* feat: signUP 구현

* feat : navigateToLogin 로직 삭제

* feat : 테마 패키지 수정

* feat : suspendOnError를 suspendOnFailure로 수정

* feat : 구글 로그인 에러시 error메세지를 띄우도록 변경

* ci 문법 오류 수정

---------

Co-authored-by: kwakjoohyeong <[email protected]>
Co-authored-by: chws0508 <[email protected]>
  • Loading branch information
3 people authored Feb 28, 2024
1 parent 35f3db2 commit 813a5c2
Show file tree
Hide file tree
Showing 46 changed files with 460 additions and 122 deletions.
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

0 comments on commit 813a5c2

Please sign in to comment.