-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
π :: (#514) google app μν€ν
μ²λ‘ λ³κ²½
π :: (#514) google app μν€ν μ²λ‘ λ³κ²½
- Loading branch information
Showing
59 changed files
with
611 additions
and
617 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
...re/src/main/java/team/aliens/dms/android/core/datastore/exception/LoadFailureException.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package team.aliens.dms.android.core.datastore.exception | ||
|
||
open class LoadFailureException(message: String? = "Load failure") : DataStoreException(message) |
3 changes: 0 additions & 3 deletions
3
.../src/main/java/team/aliens/dms/android/core/datastore/exception/SearchFailureException.kt
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 56 additions & 6 deletions
62
core/jwt/src/main/java/team/aliens/dms/android/core/jwt/JwtProvider.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,66 @@ | ||
package team.aliens.dms.android.core.jwt | ||
|
||
import team.aliens.dms.android.core.jwt.store.JwtStore | ||
import kotlinx.coroutines.CoroutineScope | ||
import kotlinx.coroutines.Dispatchers | ||
import kotlinx.coroutines.launch | ||
import team.aliens.dms.android.core.datastore.exception.LoadFailureException | ||
import team.aliens.dms.android.core.jwt.datastore.JwtDataStoreDataSource | ||
import team.aliens.dms.android.core.jwt.exception.CannotUseTokensException | ||
import team.aliens.dms.android.core.jwt.network.TokenReissueManager | ||
import team.aliens.dms.android.shared.date.util.now | ||
import javax.inject.Inject | ||
|
||
// TODO: JWT Repository ꡬν κ³ λ―Ό | ||
object JwtProvider : JwtProviderInjectionDelegation() { | ||
/* | ||
val cachedAccessToken: AccessToken | ||
val cachedRefreshToken: RefreshToken | ||
*/ | ||
|
||
private var _cachedAccessToken: AccessToken? = null | ||
val cachedAccessToken: AccessToken | ||
get() = if (isCachedAccessTokenAvailable) { | ||
_cachedAccessToken!! | ||
} else { | ||
this.fetchTokens().accessToken | ||
} | ||
|
||
private var _cachedAccessTokenExpiration: AccessTokenExpiration? = null | ||
val cachedAccessTokenExpiration: AccessTokenExpiration | ||
get() = _cachedAccessTokenExpiration ?: this.fetchTokens().accessTokenExpiration | ||
|
||
private val isCachedAccessTokenAvailable: Boolean | ||
get() { | ||
val con1 = _cachedAccessToken != null | ||
val con2 = now.isBefore(cachedAccessTokenExpiration) | ||
return con1 && con2 | ||
} | ||
|
||
init { | ||
loadTokens() | ||
} | ||
|
||
private fun loadTokens(): Tokens = try { | ||
jwtDataStoreDataSource.loadTokens().also(::updateTokens) | ||
} catch (e: LoadFailureException) { | ||
throw CannotUseTokensException() | ||
} | ||
|
||
private fun fetchTokens(): Tokens = try { | ||
val refreshToken = jwtDataStoreDataSource.loadRefreshToken() | ||
tokenReissueManager(refreshToken).toModel().also(::updateTokens) | ||
} catch (e: LoadFailureException) { | ||
throw CannotUseTokensException() | ||
} | ||
|
||
private fun updateTokens(tokens: Tokens) { | ||
this._cachedAccessToken = tokens.accessToken | ||
this._cachedAccessTokenExpiration = tokens.accessTokenExpiration | ||
CoroutineScope(Dispatchers.IO).launch { jwtDataStoreDataSource.storeTokens(tokens) } | ||
} | ||
} | ||
|
||
abstract class JwtProviderInjectionDelegation { | ||
|
||
@Inject | ||
lateinit var jwtDataStoreDataSource: JwtDataStoreDataSource | ||
|
||
@Inject | ||
lateinit var jwtStore: JwtStore | ||
lateinit var tokenReissueManager: TokenReissueManager | ||
} |
17 changes: 17 additions & 0 deletions
17
core/jwt/src/main/java/team/aliens/dms/android/core/jwt/Tokens.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package team.aliens.dms.android.core.jwt | ||
|
||
import team.aliens.dms.android.core.jwt.network.model.TokensResponse | ||
|
||
data class Tokens( | ||
val accessToken: AccessToken, | ||
val accessTokenExpiration: AccessTokenExpiration, | ||
val refreshToken: RefreshToken, | ||
val refreshTokenExpiration: RefreshTokenExpiration, | ||
) | ||
|
||
internal fun TokensResponse.toModel(): Tokens = Tokens( | ||
accessToken = this.accessToken, | ||
accessTokenExpiration = this.accessTokenExpiration, | ||
refreshToken = this.refreshToken, | ||
refreshTokenExpiration = this.refreshTokenExpiration, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 19 additions & 83 deletions
102
...wt/src/main/java/team/aliens/dms/android/core/jwt/datastore/JwtDataStoreDataSourceImpl.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,110 +1,46 @@ | ||
package team.aliens.dms.android.core.jwt.datastore | ||
|
||
import androidx.datastore.preferences.core.edit | ||
import androidx.datastore.preferences.core.longPreferencesKey | ||
import androidx.datastore.preferences.core.stringPreferencesKey | ||
import kotlinx.coroutines.flow.first | ||
import kotlinx.coroutines.flow.map | ||
import kotlinx.coroutines.runBlocking | ||
import team.aliens.dms.android.core.datastore.PreferencesDataStore | ||
import team.aliens.dms.android.core.datastore.util.transform | ||
import team.aliens.dms.android.core.jwt.AccessToken | ||
import team.aliens.dms.android.core.jwt.AccessTokenExpiration | ||
import team.aliens.dms.android.core.jwt.RefreshToken | ||
import team.aliens.dms.android.core.jwt.RefreshTokenExpiration | ||
import team.aliens.dms.android.core.jwt.exception.AccessTokenExpirationNotFoundException | ||
import team.aliens.dms.android.core.jwt.exception.AccessTokenNotFoundException | ||
import team.aliens.dms.android.core.jwt.exception.CannotStoreAccessTokenException | ||
import team.aliens.dms.android.core.jwt.exception.CannotStoreAccessTokenExpirationException | ||
import team.aliens.dms.android.core.jwt.exception.CannotStoreRefreshTokenException | ||
import team.aliens.dms.android.core.jwt.exception.CannotStoreRefreshTokenExpirationException | ||
import team.aliens.dms.android.core.jwt.exception.RefreshTokenExpirationNotFoundException | ||
import team.aliens.dms.android.core.jwt.exception.RefreshTokenNotFoundException | ||
import team.aliens.dms.android.shared.date.extension.toEpochMilli | ||
import team.aliens.dms.android.shared.date.extension.toLocalDateTime | ||
import team.aliens.dms.android.core.jwt.Tokens | ||
import team.aliens.dms.android.core.jwt.datastore.store.JwtStore | ||
import javax.inject.Inject | ||
|
||
internal class JwtDataStoreDataSourceImpl @Inject constructor( | ||
private val preferencesDataStore: PreferencesDataStore, | ||
private val jwtStore: JwtStore, | ||
) : JwtDataStoreDataSource() { | ||
override fun loadAccessToken(): AccessToken = runBlocking { | ||
preferencesDataStore.data.map { preferences -> | ||
preferences[ACCESS_TOKEN] ?: throw AccessTokenNotFoundException() | ||
}.first() | ||
} | ||
|
||
override suspend fun storeAccessToken(token: AccessToken) { | ||
transform( | ||
job = { | ||
preferencesDataStore.edit { preferences -> | ||
preferences[ACCESS_TOKEN] = token | ||
} | ||
}, | ||
onFailure = { throw CannotStoreAccessTokenException() }, | ||
) | ||
override fun loadTokens(): Tokens = jwtStore.loadTokens() | ||
|
||
override suspend fun storeTokens(tokens: Tokens) { | ||
jwtStore.storeTokens(tokens) | ||
} | ||
|
||
override fun loadAccessTokenExpiration(): AccessTokenExpiration = runBlocking { | ||
preferencesDataStore.data.map { preferences -> | ||
val longValue = preferences[ACCESS_TOKEN_EXPIRATION] | ||
?: throw AccessTokenExpirationNotFoundException() | ||
override fun loadAccessToken(): AccessToken = jwtStore.loadAccessToken() | ||
|
||
return@map longValue.toLocalDateTime() | ||
}.first() | ||
override suspend fun storeAccessToken(token: AccessToken) { | ||
jwtStore.storeAccessToken(token) | ||
} | ||
|
||
override fun loadAccessTokenExpiration(): AccessTokenExpiration = | ||
jwtStore.loadAccessTokenExpiration() | ||
|
||
override suspend fun storeAccessTokenExpiration(expiration: AccessTokenExpiration) { | ||
transform( | ||
job = { | ||
preferencesDataStore.edit { preferences -> | ||
preferences[ACCESS_TOKEN_EXPIRATION] = expiration.toEpochMilli() | ||
} | ||
}, | ||
onFailure = { throw CannotStoreAccessTokenExpirationException() }, | ||
) | ||
jwtStore.storeAccessTokenExpiration(expiration) | ||
} | ||
|
||
override fun loadRefreshToken(): RefreshToken = runBlocking { | ||
preferencesDataStore.data.map { preferences -> | ||
preferences[REFRESH_TOKEN] ?: throw RefreshTokenNotFoundException() | ||
}.first() | ||
} | ||
override fun loadRefreshToken(): RefreshToken = jwtStore.loadRefreshToken() | ||
|
||
override suspend fun storeRefreshToken(token: RefreshToken) { | ||
transform( | ||
job = { | ||
preferencesDataStore.edit { preferences -> | ||
preferences[REFRESH_TOKEN] = token | ||
} | ||
}, | ||
onFailure = { throw CannotStoreRefreshTokenException() }, | ||
) | ||
jwtStore.storeRefreshToken(token) | ||
} | ||
|
||
override fun loadRefreshTokenExpiration(): RefreshTokenExpiration = runBlocking { | ||
preferencesDataStore.data.map { preferences -> | ||
val longValue = preferences[REFRESH_TOKEN_EXPIRATION] | ||
?: throw RefreshTokenExpirationNotFoundException() | ||
|
||
return@map longValue.toLocalDateTime() | ||
}.first() | ||
} | ||
override fun loadRefreshTokenExpiration(): RefreshTokenExpiration = | ||
jwtStore.loadRefreshTokenExpiration() | ||
|
||
override suspend fun storeRefreshTokenExpiration(expiration: RefreshTokenExpiration) { | ||
transform( | ||
job = { | ||
preferencesDataStore.edit { preferences -> | ||
preferences[REFRESH_TOKEN_EXPIRATION] = expiration.toEpochMilli() | ||
} | ||
}, | ||
onFailure = { throw CannotStoreRefreshTokenExpirationException() }, | ||
) | ||
} | ||
|
||
private companion object { | ||
val ACCESS_TOKEN = stringPreferencesKey("access-token") | ||
val ACCESS_TOKEN_EXPIRATION = longPreferencesKey("access-token-expiration") | ||
val REFRESH_TOKEN = stringPreferencesKey("refresh-token") | ||
val REFRESH_TOKEN_EXPIRATION = longPreferencesKey("refresh-token-expiration") | ||
jwtStore.storeRefreshTokenExpiration(expiration) | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
core/jwt/src/main/java/team/aliens/dms/android/core/jwt/datastore/store/JwtStore.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package team.aliens.dms.android.core.jwt.datastore.store | ||
|
||
import team.aliens.dms.android.core.jwt.AccessToken | ||
import team.aliens.dms.android.core.jwt.AccessTokenExpiration | ||
import team.aliens.dms.android.core.jwt.RefreshToken | ||
import team.aliens.dms.android.core.jwt.RefreshTokenExpiration | ||
import team.aliens.dms.android.core.jwt.Tokens | ||
|
||
internal abstract class JwtStore { | ||
|
||
abstract fun loadTokens(): Tokens | ||
|
||
abstract suspend fun storeTokens(tokens: Tokens) | ||
|
||
abstract fun loadAccessToken(): AccessToken | ||
|
||
abstract suspend fun storeAccessToken(token: AccessToken) | ||
|
||
abstract fun loadAccessTokenExpiration(): AccessTokenExpiration | ||
|
||
abstract suspend fun storeAccessTokenExpiration(expiration: AccessTokenExpiration) | ||
|
||
abstract fun loadRefreshToken(): RefreshToken | ||
|
||
abstract suspend fun storeRefreshToken(token: RefreshToken) | ||
|
||
abstract fun loadRefreshTokenExpiration(): RefreshTokenExpiration | ||
|
||
abstract suspend fun storeRefreshTokenExpiration(expiration: RefreshTokenExpiration) | ||
} |
Oops, something went wrong.