-
Notifications
You must be signed in to change notification settings - Fork 160
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
Make sure to save the tokens the Client might return when its session is restored #3378
Make sure to save the tokens the Client might return when its session is restored #3378
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #3378 +/- ##
========================================
Coverage 82.59% 82.59%
========================================
Files 1693 1693
Lines 39646 39646
Branches 4822 4822
========================================
Hits 32745 32745
Misses 5216 5216
Partials 1685 1685 ☔ View full report in Codecov by Sentry. |
📱 Scan the QR code below to install the build (arm64 only) for this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but maybe a better fix is to invoke client.restoreSession(sessionData.toSession())
after creating the RustMatrixClient
instance? So move the line 67 into this also
block? So in this case, the callback didRefreshTokens()
will be invoked, since the clientDelegate
will be set?
I don't think we can because In any case, I think we'll implement a fix in the Rust SDK instead. I'm leaving the PR as a draft until either that solution is ready or we decide a client side one might be better. |
315d811
to
34846e2
Compare
private val updateTokensDispatcher = coroutineDispatchers.io.limitedParallelism(1) | ||
|
||
/** This [RustMatrixClient] needs to be set up as soon as possible so `didReceiveAuthError` can work properly. */ | ||
var client: RustMatrixClient? = null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hate that this is needed, but I don't see any better way to centralise handling the token operations in a single point without being able to access the client for a logout.
Refreshed tokens on client restoration might not have been stored to disk if the token refresh happened before `RustMatrixClient` was built and the `ClientDelegate` was set in it. Using `ClientSessionDelegate` should ensure the tokens refreshed callback is called at any point in time.
Well, this is no longer true. We saw we could reuse the same flow as iOS with |
06e1ce9
to
57b88ec
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is something missing, see the comment: #3378 (comment)
...ies/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt
Outdated
Show resolved
Hide resolved
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/MatrixClient.kt
Outdated
Show resolved
Hide resolved
...x/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustClientSessionDelegate.kt
Outdated
Show resolved
Hide resolved
...x/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustClientSessionDelegate.kt
Show resolved
Hide resolved
...x/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustClientSessionDelegate.kt
Show resolved
Hide resolved
...x/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustClientSessionDelegate.kt
Outdated
Show resolved
Hide resolved
26d81dd
to
8be90e2
Compare
Quality Gate passedIssues Measures |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update, all my tests are passing now!
Hopefully no more wild sign out!
override suspend fun logout(ignoreSdkError: Boolean, forced: Boolean): String? = simulateLongTask { | ||
return logoutLambda(ignoreSdkError, forced) | ||
override suspend fun logout(userInitiated: Boolean, ignoreSdkError: Boolean): String? = simulateLongTask { | ||
return logoutLambda(ignoreSdkError, userInitiated) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a swap in the parameters, this is not a big deal, but it can be confusing. Also when userInitiated
is false
, ignoreSdkError
does not have sense.
Maybe we should create a small sealed interface to handle this:
sealed interface LogoutParameter {
data class UserInitiated(val ignoreSdkError: Boolean) : LogoutParameter
data object ServerInitiated : LogoutParameter
}
Not a blocker for this PR though, I can do it later, just sharing the idea here :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add this in a separate PR then? So I can merge this and add it to the current release.
Content
When we're restoring a Rust
Client
object with some session data, the client might automatically refresh the tokens it uses. Usually, this would get reported by theClientDelegate
methods, but since that's only added after the session is restored, the update doesn't trigger the delegate callback and the new tokens aren't stored locally. This means next time we restore the session we'd be using discarded credentials and the server will log us out.I'm creating a new
RustClientSessionDelegate
that implements both:ClientSessionDelegate
: used by iOS mainly up until now, it's passed to theClientBuilder
so it will be able to handle token refreshes while the Client is restoring the session, solving the problem above.ClientDelegate
: what we were using for handling token refreshes and refresh errors that should end in a logout. Since the previous delegate is handling token refreshes now, we only need the logout part.Motivation and context
Found some promising explanation in a rageshake.
This might fix #3274.
Tests
This is quite difficult to test since it depends on the access token expiration time, which is different in each homeserver and also you need some luck (or bad luck) to make it fail, so even if it doesn't fail in some hours or days the fix might not do anything.
I think the best we can do is include it, then check if there haven't been any recent reports of spontaneous logouts.
When I tried to test it, I did the next:
However, I'm not 100% certain this is the right way to reproduce the previous error.
Tested devices
Checklist