Skip to content

Commit

Permalink
feat: role, id 로컬 저장 및 따라 자동로그인 로직 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
rhkrwngud445 committed Apr 3, 2024
1 parent 224a5ac commit e54db4a
Show file tree
Hide file tree
Showing 13 changed files with 102 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.withpeace.withpeace.core.data.repository

import android.content.Context
import com.skydoves.sandwich.message
import com.skydoves.sandwich.suspendMapSuccess
import com.skydoves.sandwich.suspendOnFailure
import com.withpeace.withpeace.core.data.mapper.roleToDomain
import com.withpeace.withpeace.core.datastore.dataStore.TokenPreferenceDataSource
import com.withpeace.withpeace.core.datastore.dataStore.token.TokenPreferenceDataSource
import com.withpeace.withpeace.core.datastore.dataStore.user.UserPreferenceDataSource
import com.withpeace.withpeace.core.domain.model.role.Role
import com.withpeace.withpeace.core.domain.repository.TokenRepository
import com.withpeace.withpeace.core.network.di.response.LoginResponse
import com.withpeace.withpeace.core.network.di.service.AuthService
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.firstOrNull
Expand All @@ -18,13 +18,14 @@ import kotlinx.coroutines.flow.flowOn
import javax.inject.Inject

class DefaultTokenRepository @Inject constructor(
@ApplicationContext private val context: Context,
private val tokenPreferenceDataSource: TokenPreferenceDataSource,
private val userPreferenceDataSource: UserPreferenceDataSource,
private val authService: AuthService,
) : TokenRepository {
override suspend fun isLogin(): Boolean {
val token = tokenPreferenceDataSource.accessToken.firstOrNull()
return token != null
val userRole = userPreferenceDataSource.userRole.firstOrNull()
return token != null && userRole?.roleToDomain() == Role.USER //TODO("토큰이 만료되었는지 확인 필요")
}

override fun getTokenByGoogle(
Expand All @@ -33,12 +34,18 @@ class DefaultTokenRepository @Inject constructor(
): Flow<Role> = flow {
authService.googleLogin(AUTHORIZATION_FORMAT.format(idToken)).suspendMapSuccess {
val data = this.data
tokenPreferenceDataSource.updateAccessToken(data.tokenResponse.accessToken)
tokenPreferenceDataSource.updateRefreshToken(data.tokenResponse.refreshToken)
saveLocalLoginInfo(data)
emit(data.role.roleToDomain())
}.suspendOnFailure { onError(message()) }
}.flowOn(Dispatchers.IO)

private suspend fun saveLocalLoginInfo(data: LoginResponse) {
tokenPreferenceDataSource.updateAccessToken(data.tokenResponse.accessToken)
tokenPreferenceDataSource.updateRefreshToken(data.tokenResponse.refreshToken)
userPreferenceDataSource.updateUserId(data.userId)
userPreferenceDataSource.updateUserRole(data.role)
}

companion object {
private const val AUTHORIZATION_FORMAT = "Bearer %s"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import com.skydoves.sandwich.suspendOnError
import com.skydoves.sandwich.suspendOnException
import com.withpeace.withpeace.core.data.mapper.toDomain
import com.withpeace.withpeace.core.data.util.convertToFile
import com.withpeace.withpeace.core.datastore.dataStore.TokenPreferenceDataSource
import com.withpeace.withpeace.core.datastore.dataStore.token.TokenPreferenceDataSource
import com.withpeace.withpeace.core.datastore.dataStore.user.UserPreferenceDataSource
import com.withpeace.withpeace.core.domain.model.SignUpInfo
import com.withpeace.withpeace.core.domain.model.WithPeaceError
import com.withpeace.withpeace.core.domain.model.profile.ChangedProfile
Expand All @@ -32,6 +33,7 @@ class DefaultUserRepository @Inject constructor(
@ApplicationContext private val context: Context,
private val userService: UserService,
private val tokenPreferenceDataSource: TokenPreferenceDataSource,
private val userPreferenceDataSource: UserPreferenceDataSource,
) : UserRepository {
override fun getProfile(
onError: suspend (WithPeaceError) -> Unit,
Expand Down Expand Up @@ -165,6 +167,7 @@ class DefaultUserRepository @Inject constructor(
override fun logout(onError: suspend (WithPeaceError) -> Unit): Flow<Unit> = flow {
userService.logout().suspendMapSuccess {
tokenPreferenceDataSource.removeAll()
userPreferenceDataSource.removeAll()
emit(Unit)
}.suspendOnError {
if (statusCode.code == 401) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.withpeace.withpeace.core.datastore.dataStore
package com.withpeace.withpeace.core.datastore.dataStore.token

import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.withpeace.withpeace.core.datastore.dataStore
package com.withpeace.withpeace.core.datastore.dataStore.token

import kotlinx.coroutines.flow.Flow

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.withpeace.withpeace.core.datastore.dataStore.user

import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.longPreferencesKey
import androidx.datastore.preferences.core.stringPreferencesKey
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject
import javax.inject.Named

class DefaultUserPreferenceDataSource @Inject constructor(
@Named("user") private val dataStore: DataStore<Preferences>,
) : UserPreferenceDataSource {
override val userId: Flow<Long?> = dataStore.data.map { preferences ->
preferences[USER_ID]
}
override val userRole: Flow<String?> = dataStore.data.map { preferences ->
preferences[USER_ROLE]
}

override suspend fun updateUserId(userId: Long) {
dataStore.edit { preferences ->
preferences[USER_ID] = userId
}
}

override suspend fun updateUserRole(userRole: String) {
dataStore.edit { preferences ->
preferences[USER_ROLE] = userRole
}
}

override suspend fun removeAll() {
dataStore.edit { preferences ->
preferences.clear()
}
}

companion object {
private val USER_ID = longPreferencesKey("USER_ID")
private val USER_ROLE = stringPreferencesKey("USER_ROLE")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.withpeace.withpeace.core.datastore.dataStore.user

import kotlinx.coroutines.flow.Flow

interface UserPreferenceDataSource {

val userId: Flow<Long?>

val userRole: Flow<String?>

suspend fun updateUserId(userId: Long)

suspend fun updateUserRole(userRole: String)
suspend fun removeAll()
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,22 @@ import javax.inject.Singleton
object DataStoreModule {

private const val AUTH_DATASTORE_NAME = "AUTH_PREFERENCES"
private const val USER_DATASTORE_NAME = "USER_PREFERENCES"

private val Context.authDataStore: DataStore<Preferences> by preferencesDataStore(name = AUTH_DATASTORE_NAME)
private val Context.userDataStore: DataStore<Preferences> by preferencesDataStore(name = USER_DATASTORE_NAME)

@Provides
@Singleton
@Named("auth")
fun providesTokenDataStore(
@ApplicationContext context: Context,
): DataStore<Preferences> = context.authDataStore

@Provides
@Singleton
@Named("user")
fun providesUserDataStore(
@ApplicationContext context: Context,
): DataStore<Preferences> = context.userDataStore
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.withpeace.withpeace.core.datastore.di

import com.withpeace.withpeace.core.datastore.dataStore.DefaultTokenPreferenceDataSource
import com.withpeace.withpeace.core.datastore.dataStore.TokenPreferenceDataSource
import com.withpeace.withpeace.core.datastore.dataStore.token.DefaultTokenPreferenceDataSource
import com.withpeace.withpeace.core.datastore.dataStore.token.TokenPreferenceDataSource
import com.withpeace.withpeace.core.datastore.dataStore.user.DefaultUserPreferenceDataSource
import com.withpeace.withpeace.core.datastore.dataStore.user.UserPreferenceDataSource
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
Expand All @@ -17,4 +19,10 @@ interface PreferenceDataSourceModule {
fun bindsTokenPreferenceDataSource(
defaultTokenPreferenceDataSource: DefaultTokenPreferenceDataSource,
): TokenPreferenceDataSource

@Binds
@Singleton
fun bindsUserPreferenceDataSource(
defaultUserPreferenceDataSource: DefaultUserPreferenceDataSource,
): UserPreferenceDataSource
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.withpeace.withpeace.core.domain.usecase

import com.withpeace.withpeace.core.domain.repository.TokenRepository
import kotlinx.coroutines.flow.first
import javax.inject.Inject

class IsLoginUseCase @Inject constructor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import com.google.common.truth.Truth.assertThat
import com.withpeace.withpeace.core.domain.repository.TokenRepository
import io.mockk.coEvery
import io.mockk.mockk
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.test.runTest
import org.junit.Test

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.withpeace.withpeace.core.interceptor

import com.skydoves.sandwich.suspendMapSuccess
import com.skydoves.sandwich.suspendOnError
import com.withpeace.withpeace.core.datastore.dataStore.TokenPreferenceDataSource
import com.withpeace.withpeace.core.datastore.dataStore.token.TokenPreferenceDataSource
import com.withpeace.withpeace.core.network.di.response.TokenResponse
import com.withpeace.withpeace.core.network.di.service.AuthService
import kotlinx.coroutines.flow.firstOrNull
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.withpeace.withpeace.core.interceptor

import com.withpeace.withpeace.core.datastore.dataStore.TokenPreferenceDataSource
import com.withpeace.withpeace.core.datastore.dataStore.token.TokenPreferenceDataSource
import com.withpeace.withpeace.core.network.di.service.AuthService
import dagger.Module
import dagger.Provides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ data class LoginResponse(
@SerialName("jwtTokenDto")
val tokenResponse: TokenResponse,
val role: String,
val userId: Long,
)

0 comments on commit e54db4a

Please sign in to comment.