mirror of
https://github.com/element-hq/element-android
synced 2024-11-25 02:45:37 +03:00
SoftLogout: Store the info that the token is not valid anymore for a faster startup
This commit is contained in:
parent
261b4be287
commit
a5af949c15
10 changed files with 77 additions and 10 deletions
|
@ -22,5 +22,6 @@ package im.vector.matrix.android.api.auth.data
|
|||
*/
|
||||
data class SessionParams(
|
||||
val credentials: Credentials,
|
||||
val homeServerConnectionConfig: HomeServerConnectionConfig
|
||||
val homeServerConnectionConfig: HomeServerConnectionConfig,
|
||||
val isTokenValid: Boolean
|
||||
)
|
||||
|
|
|
@ -62,6 +62,11 @@ interface Session :
|
|||
*/
|
||||
val sessionParams: SessionParams
|
||||
|
||||
/**
|
||||
* The session is valid, i.e. it has a valid token so far
|
||||
*/
|
||||
val isOpenable: Boolean
|
||||
|
||||
/**
|
||||
* Useful shortcut to get access to the userId
|
||||
*/
|
||||
|
|
|
@ -60,7 +60,8 @@ internal class DefaultSessionCreator @Inject constructor(
|
|||
?.also { Timber.d("Overriding identity server url to $it") }
|
||||
?.let { Uri.parse(it) }
|
||||
?: homeServerConnectionConfig.identityServerUri
|
||||
))
|
||||
),
|
||||
isTokenValid = true)
|
||||
|
||||
sessionParamsStore.save(sessionParams)
|
||||
return sessionManager.getOrCreateSession(sessionParams)
|
||||
|
|
|
@ -29,6 +29,8 @@ internal interface SessionParamsStore {
|
|||
|
||||
suspend fun save(sessionParams: SessionParams)
|
||||
|
||||
suspend fun setTokenInvalid(userId: String)
|
||||
|
||||
suspend fun updateCredentials(newCredentials: Credentials)
|
||||
|
||||
suspend fun delete(userId: String)
|
||||
|
|
|
@ -24,7 +24,7 @@ internal class AuthRealmMigration : RealmMigration {
|
|||
|
||||
companion object {
|
||||
// Current schema version
|
||||
const val SCHEMA_VERSION = 1L
|
||||
const val SCHEMA_VERSION = 2L
|
||||
}
|
||||
|
||||
override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
|
||||
|
@ -46,5 +46,14 @@ internal class AuthRealmMigration : RealmMigration {
|
|||
.addField(PendingSessionEntityFields.IS_REGISTRATION_STARTED, Boolean::class.java)
|
||||
.addField(PendingSessionEntityFields.CURRENT_THREE_PID_DATA_JSON, String::class.java)
|
||||
}
|
||||
|
||||
if (oldVersion <= 1) {
|
||||
Timber.d("Step 1 -> 2")
|
||||
Timber.d("Add boolean isTokenValid in SessionParamsEntity, with value true")
|
||||
|
||||
realm.schema.get("SessionParamsEntity")
|
||||
?.addField(SessionParamsEntityFields.IS_TOKEN_VALID, Boolean::class.java)
|
||||
?.transform { it.set(SessionParamsEntityFields.IS_TOKEN_VALID, true) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,6 +76,26 @@ internal class RealmSessionParamsStore @Inject constructor(private val mapper: S
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun setTokenInvalid(userId: String) {
|
||||
awaitTransaction(realmConfiguration) { realm ->
|
||||
val currentSessionParams = realm
|
||||
.where(SessionParamsEntity::class.java)
|
||||
.equalTo(SessionParamsEntityFields.USER_ID, userId)
|
||||
.findAll()
|
||||
.firstOrNull()
|
||||
|
||||
if (currentSessionParams == null) {
|
||||
// Should not happen
|
||||
"Session param not found for user $userId"
|
||||
.let { Timber.w(it) }
|
||||
.also { error(it) }
|
||||
} else {
|
||||
currentSessionParams.isTokenValid = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override suspend fun updateCredentials(newCredentials: Credentials) {
|
||||
awaitTransaction(realmConfiguration) { realm ->
|
||||
val currentSessionParams = realm
|
||||
|
@ -92,7 +112,8 @@ internal class RealmSessionParamsStore @Inject constructor(private val mapper: S
|
|||
.also { error(it) }
|
||||
} else {
|
||||
val newSessionParams = currentSessionParams.copy(
|
||||
credentials = newCredentials
|
||||
credentials = newCredentials,
|
||||
isTokenValid = true
|
||||
)
|
||||
|
||||
val entity = mapper.map(newSessionParams)
|
||||
|
|
|
@ -22,5 +22,8 @@ import io.realm.annotations.PrimaryKey
|
|||
internal open class SessionParamsEntity(
|
||||
@PrimaryKey var userId: String = "",
|
||||
var credentialsJson: String = "",
|
||||
var homeServerConnectionConfigJson: String = ""
|
||||
var homeServerConnectionConfigJson: String = "",
|
||||
// Set to false when the token is invalid and the user has been soft logged out
|
||||
// In case of hard logout, this object in deleted from DB
|
||||
var isTokenValid: Boolean = true
|
||||
) : RealmObject()
|
||||
|
|
|
@ -36,7 +36,7 @@ internal class SessionParamsMapper @Inject constructor(moshi: Moshi) {
|
|||
if (credentials == null || homeServerConnectionConfig == null) {
|
||||
return null
|
||||
}
|
||||
return SessionParams(credentials, homeServerConnectionConfig)
|
||||
return SessionParams(credentials, homeServerConnectionConfig, entity.isTokenValid)
|
||||
}
|
||||
|
||||
fun map(sessionParams: SessionParams?): SessionParamsEntity? {
|
||||
|
@ -48,6 +48,10 @@ internal class SessionParamsMapper @Inject constructor(moshi: Moshi) {
|
|||
if (credentialsJson == null || homeServerConnectionConfigJson == null) {
|
||||
return null
|
||||
}
|
||||
return SessionParamsEntity(sessionParams.credentials.userId, credentialsJson, homeServerConnectionConfigJson)
|
||||
return SessionParamsEntity(
|
||||
sessionParams.credentials.userId,
|
||||
credentialsJson,
|
||||
homeServerConnectionConfigJson,
|
||||
sessionParams.isTokenValid)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,10 +42,14 @@ import im.vector.matrix.android.api.session.signout.SignOutService
|
|||
import im.vector.matrix.android.api.session.sync.FilterService
|
||||
import im.vector.matrix.android.api.session.sync.SyncState
|
||||
import im.vector.matrix.android.api.session.user.UserService
|
||||
import im.vector.matrix.android.internal.auth.SessionParamsStore
|
||||
import im.vector.matrix.android.internal.crypto.DefaultCryptoService
|
||||
import im.vector.matrix.android.internal.database.LiveEntityObserver
|
||||
import im.vector.matrix.android.internal.session.sync.job.SyncThread
|
||||
import im.vector.matrix.android.internal.session.sync.job.SyncWorker
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
|
@ -72,6 +76,7 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se
|
|||
private val secureStorageService: Lazy<SecureStorageService>,
|
||||
private val syncThreadProvider: Provider<SyncThread>,
|
||||
private val contentUrlResolver: ContentUrlResolver,
|
||||
private val sessionParamsStore: SessionParamsStore,
|
||||
private val contentUploadProgressTracker: ContentUploadStateTracker,
|
||||
private val initialSyncProgressService: Lazy<InitialSyncProgressService>,
|
||||
private val homeServerCapabilitiesService: Lazy<HomeServerCapabilitiesService>)
|
||||
|
@ -94,6 +99,9 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se
|
|||
|
||||
private var syncThread: SyncThread? = null
|
||||
|
||||
override val isOpenable: Boolean
|
||||
get() = sessionParamsStore.get(myUserId)?.isTokenValid ?: false
|
||||
|
||||
@MainThread
|
||||
override fun open() {
|
||||
assertMainThread()
|
||||
|
@ -171,6 +179,14 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se
|
|||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onGlobalError(globalError: GlobalError) {
|
||||
if (globalError is GlobalError.InvalidToken
|
||||
&& globalError.softLogout) {
|
||||
// Mark the token has invalid
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
sessionParamsStore.setTokenInvalid(myUserId)
|
||||
}
|
||||
}
|
||||
|
||||
sessionListeners.dispatchGlobalError(globalError)
|
||||
}
|
||||
|
||||
|
|
|
@ -169,9 +169,14 @@ class MainActivity : VectorBaseActivity() {
|
|||
// the homeserver has invalidated the token (password changed, device deleted, other security reason
|
||||
SignedOutActivity.newIntent(this)
|
||||
sessionHolder.hasActiveSession() ->
|
||||
// We have a session. In case of soft logout (i.e. restart of the app after a soft logout)
|
||||
// the app will try to sync and will reenter the soft logout use case
|
||||
HomeActivity.newIntent(this)
|
||||
// We have a session.
|
||||
// Check it can be opened
|
||||
if(sessionHolder.getActiveSession().isOpenable) {
|
||||
HomeActivity.newIntent(this)
|
||||
} else {
|
||||
// The token is still invalid
|
||||
SoftLogoutActivity.newIntent(this)
|
||||
}
|
||||
else ->
|
||||
// First start, or no active session
|
||||
LoginActivity.newIntent(this, null)
|
||||
|
|
Loading…
Reference in a new issue