Skip to content
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

Reset corrupted credentials storage when applicable #2504

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

marcosnav
Copy link
Collaborator

Intent

This PR introduces a new reset step for credentials storage, both keyring and file based, when the data gets into a bad or unrecognizable state.

A warning will be shown if the IDE is already open, if a new Positron or VSCode session is open, we won't show a warning, since the early stages of initialization of the extension do not communicate status with the extension.

Warning message screenshot
Screen Shot 2024-12-21 at 2 57 32

Output logged warning
Screen Shot 2024-12-21 at 2 56 33

Fixes #2491 #2492

Type of Change

    • Bug Fix
    • New Feature
    • Breaking Change
    • Documentation
    • Refactor
    • Tooling

Approach

If we detect a malformed state of the credentials data, we proceed to reset it.

User Impact

There were a couple reported cases internally in which the Publisher extension wouldn't finish loadind and didn't provide much details other than some hints in the output logs.

This due to a corrupted or old and unsupported credentials data.

With this fix, the unusable credentials data will be reset and the user will be able to continue using Publisher.

Automated Tests

Updated and added tests accordingly.

Directions for Reviewers

Here is an example of malformed data that can be used to update the keychain record. This when keyring is supported, Desktop version of Positron or VSCode.

go-keyring-base64:eyI1ZjRmMjI4Ni00MjUzLTRjMTYtYWU1OS0yMDU5MjgyMmUyOWEiOnsiZ3VpZCI6IjVmNGYyMjg2LTQyNTMtNGMxNi1hZTU5LTIwNTkyODIyZTI5YSIsInZlcnNpb24iOjAsImRhdGEiOiJub3QtYS1qc29uIn19

For testing workbench, update the .connect-credentials file with an unrecognizable schema, e.g:

unrecognizable_key = "this will trigger a reset"

Checklist

);
export const errCredentialsResetMessage = () => {
return "Stored credentials for Posit Publisher found in an unrecognizable state. A reset was required in order to proceed.";
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current wording might leave the user trying to figure out how to reset the credentials even though we have already done it for them. It's long and could use some further refinement, but how about something like this?

Unable to use existing stored credentials for Posit Publisher (reason: unrecognizable state). The existing credentials have been deleted. Recreate them using the Credentials section or the Command Pallet's "Posit Publisher: New Credential" command.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it should be very clear that something has already been done. Another suggestion for the re-word:

Unrecognizable credentials for Posit Publisher were found and removed. Credentials may need to be recreated.

I went with "removed" instead of "deleted" to be a bit softer but still clear that they are no longer on the system. I left the recreation message at the end since it will be collapsed most of the time, and since they have already made credentials (we know this because they needed a reset) did not include instructions.

@sagerb
Copy link
Collaborator

sagerb commented Dec 20, 2024

Could you expand a little bit on your statement:

A warning will be shown if the IDE is already open, if a new Positron or VSCode session is open, we won't show a warning, since the early stages of initialization of the extension do not communicate status with the extension.

Isn't the reason why we won't show a warning is because the storage would have already been reset?

Copy link
Collaborator

@dotNomad dotNomad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is an example of malformed data that can be used to update the keychain record. This when keyring is supported, Desktop version of Positron or VSCode.

Is there a good way for me to reproduce malformed data in my keychain record?

For testing workbench, update the .connect-credentials file with an unrecognizable schema

Testing on Workbench this works, but I am not getting the notification of the reset when reloading the page / accessing the session for the first time. If I set .connect-credentials to something invalid and refresh the home view I see the notification, but we will need to look at this flow to ensure that notification is shown.

That may be what you were talking about here:

A warning will be shown if the IDE is already open, if a new Positron or VSCode session is open, we won't show a warning, since the early stages of initialization of the extension do not communicate status with the extension.

But like @sagerb I think I need some more details on this, and what we could possibly do to get around it.


func enforceFilecredsIntegrity(fc *fileCredentialsService, err error, log logging.Logger) error {
if errors.Is(err, &LoadError{}) {
log.Warn("Corrupted credentials data found. A reset was applied to stored data to be able to proceed")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we have two separate logs so we know which credential data we are resetting between the keyring and the file?

Comment on lines +99 to +106
err := enforceKeyringIntegrity(krService, log)
return krService, err
}

log.Debug("Fallback to file managed credentials service due to unavailable system keyring")
fcService, err := NewFileCredentialsService(log)
if err != nil {
return nil, types.NewAgentError(types.ErrorCredentialServiceUnavailable, err, nil)
return fcService, enforceFilecredsIntegrity(fcService, err, log)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was a bit confused how the credentials were being reset right when the extension activated, but if I'm understanding correctly the enforcement happens before the APIs are even called since it occurs during the setup of the Credentials Service.

Perhaps we can do something with a different flow to ensure that notifications are always present?

Some potential ideas (these are really quick so take with a large grain of salt):

  • have a POST /api/credentials/reset endpoint that we can call when we get certain errors
  • only call the enforcement when the APIs are actually called

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

File credentials - failure to read file not clear for the user
3 participants