-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Guard ApplicationPasswordsStore against Keystore failures #22855
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
Open
nbradbury
wants to merge
5
commits into
trunk
Choose a base branch
from
fix/play-keystore-invalidkey
base: trunk
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
c88ab2b
Guard ApplicationPasswordsStore prefs against Keystore failures
nbradbury 25b9dda
Address review: auth-header default and Unit overload
nbradbury 1ad8ad6
Report swallowed Keystore failures and self-heal on recovery
nbradbury 7cb49d6
Guard against duplicate Sentry reports on permanent init failure
nbradbury 1e8ecb3
Collapse loadEncryptedPreferences to a single return path
nbradbury File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
16 changes: 16 additions & 0 deletions
16
...va/org/wordpress/android/fluxc/applicationpasswords/ApplicationPasswordsListenerModule.kt
This file contains hidden or 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,16 @@ | ||
| package org.wordpress.android.fluxc.applicationpasswords | ||
|
|
||
| import dagger.Binds | ||
| import dagger.Module | ||
| import dagger.hilt.InstallIn | ||
| import dagger.hilt.components.SingletonComponent | ||
| import org.wordpress.android.fluxc.network.rest.wpapi.applicationpasswords.ApplicationPasswordsListener | ||
|
|
||
| @InstallIn(SingletonComponent::class) | ||
| @Module | ||
| interface ApplicationPasswordsListenerModule { | ||
| @Binds | ||
| fun bindApplicationPasswordsListener( | ||
| listener: WPApplicationPasswordsListener | ||
| ): ApplicationPasswordsListener | ||
| } |
18 changes: 18 additions & 0 deletions
18
...n/java/org/wordpress/android/fluxc/applicationpasswords/WPApplicationPasswordsListener.kt
This file contains hidden or 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,18 @@ | ||
| package org.wordpress.android.fluxc.applicationpasswords | ||
|
|
||
| import com.automattic.android.tracks.crashlogging.CrashLogging | ||
| import dagger.Lazy | ||
| import org.wordpress.android.fluxc.network.rest.wpapi.applicationpasswords.ApplicationPasswordsListener | ||
| import org.wordpress.android.util.AppLog | ||
| import org.wordpress.android.util.crashlogging.sendReportWithTag | ||
| import javax.inject.Inject | ||
| import javax.inject.Singleton | ||
|
|
||
| @Singleton | ||
| class WPApplicationPasswordsListener @Inject constructor( | ||
| private val crashLogging: Lazy<CrashLogging> | ||
| ) : ApplicationPasswordsListener { | ||
| override fun onKeystoreError(error: Throwable) { | ||
| crashLogging.get().sendReportWithTag(error, AppLog.T.MAIN) | ||
| } | ||
| } |
This file contains hidden or 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 hidden or 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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'm concerned that we're making this crash go away in Sentry at the cost of having no visibility into future keystore issues.
The right approach if the keystore is unreadable/corrupt seems to be to invalidate the contents and spin up a new one (thus requiring the user to reauthenticate everything) – that seems like a good fix. But I'd expect to then see some baseline of users who experience a failure, have their keystore reset, and carry on.
Dropping all future keystore errors on the floor doesn't seem like a good idea though, if there's suddenly an influx of issues in this area we have no way to know until users reach out?
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.
Good call — you're right that the logging doesn't make it to Sentry, so as written this would have made future Keystore issues invisible. With Claude's help I've pushed a follow-up that addresses both halves of your comment:
Visibility: added onKeystoreError(Throwable) to ApplicationPasswordsListener and wired a WordPress-side implementation (WPApplicationPasswordsListener) that forwards to CrashLogging.sendReportWithTag(...) as a non-fatal. Every catch site in ApplicationPasswordsStore (init-time and per-access) now notifies the listener before returning the safe default, so a sudden spike still shows up in Sentry.
Recovery: on a per-access keystore failure, the store now calls invalidateEncryptedPrefs() — deletes the prefs file and the keystore alias, and nulls the cached SharedPreferences reference. The next call re-runs initEncryptedPrefs(), which gets a fresh master key. So the expected steady state matches what you described: failure → keystore reset → user re-authenticates → carries on, and we see the non-fatal in Sentry.
The init-time path already had the delete+retry, but if both attempts failed it would degrade silently forever; that's now reported too.