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

Make OAuth prefix used for storing credentials configurable; use port… #15114

Draft
wants to merge 19 commits into
base: master
Choose a base branch
from

Conversation

chenkins
Copy link
Contributor

Resolves #15113

@chenkins chenkins requested a review from a team as a code owner September 12, 2023 16:32
@chenkins chenkins self-assigned this Sep 12, 2023
@chenkins chenkins requested a review from dkocher September 12, 2023 16:32
@AliveDevil
Copy link
Contributor

AliveDevil commented Sep 13, 2023

On Windows the OAuth Token is attached to the Credential Manager entry for a host in an additional "page"/attribute.

Basically:

protocol://user@hostname:port/
|- username: user
|- password: …
\  Metadata
    |-  OAuth Access Token: …
    |- OAuth Refresh Token: …
    \  OAuth Expiry: …

Thus the configurable oauth prefix isn't used there.
To make this work an additional credential manager entry for the OAuth connection has to be created.

https://github.com/iterate-ch/cyberduck/blob/master/core/src/main/csharp/ch/cyberduck/core/CredentialManagerPasswordStore.cs#L115

@dkocher dkocher marked this pull request as draft September 13, 2023 07:55
@chenkins chenkins force-pushed the feature/GH-15113-oauth-prefix-factory branch 2 times, most recently from ac17560 to ec72ed9 Compare September 26, 2023 13:11
if (protocol.isPortConfigurable() && !Equals(protocol.getDefaultPort(), bookmark.getPort()))
isOAuth = true;
OAuthPrefixService oAuthPrefix = new OAuthPrefixServiceFactory().create(bookmark);
hostname = oAuthPrefix.getIdentifier();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@AliveDevil looks dodgy to assign identifier to hostname

Copy link
Contributor

Choose a reason for hiding this comment

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

Well, that's what I called the field, could change that to identifier, which holds either OAuthPrefix.getIdentifier() or bookmark.getHostname() (in non-OAuth path).
Which is then built to duck:identifier:port?user= (OAuth) or duck:fqdn:port?user= (Default).

Copy link
Contributor

Choose a reason for hiding this comment

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

This causes a regression as previously entries were saved using bookmark.getProtocol().getOAuthTokenUrl() when available.

Copy link
Contributor

Choose a reason for hiding this comment

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

Only using the protocol identifier and no token URL will cause entries to be saved with the same key for bookmarks using same protocol but different OAuth endpoint.

Copy link
Contributor

Choose a reason for hiding this comment

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

@AliveDevil The previous default was duck:identifier:fqdn:port?user= , not duck:fqdn:port?user= ?

@chenkins chenkins marked this pull request as ready for review October 20, 2023 20:54
@chenkins chenkins requested a review from dkocher October 20, 2023 20:54
@dkocher dkocher marked this pull request as draft October 23, 2023 07:23
@chenkins chenkins force-pushed the feature/GH-15113-oauth-prefix-factory branch from ec72ed9 to 10c08c1 Compare October 23, 2023 11:59
@dkocher dkocher force-pushed the feature/GH-15113-oauth-prefix-factory branch from 247781e to fb98028 Compare October 27, 2023 08:42
@dkocher dkocher assigned dkocher and unassigned chenkins Oct 27, 2023
@dkocher dkocher force-pushed the feature/GH-15113-oauth-prefix-factory branch from fb98028 to 507c612 Compare October 27, 2023 18:25
@dkocher dkocher modified the milestones: 8.7.1, 9.0 Oct 27, 2023
@dkocher dkocher marked this pull request as ready for review October 27, 2023 18:41
@dkocher dkocher force-pushed the feature/GH-15113-oauth-prefix-factory branch 3 times, most recently from 6b5dbe3 to f311e4f Compare October 29, 2023 19:55
@dkocher
Copy link
Contributor

dkocher commented Oct 30, 2023

Refactored to protocol service PasswordStorePrefixService

  • Default implementation implements current behaviour of DefaultHostPasswordStore
  • New specific implementation for Windows implements current behaviour of CredentialManagerPasswordStore

@dkocher dkocher linked an issue Nov 1, 2023 that may be closed by this pull request
@dkocher dkocher force-pushed the feature/GH-15113-oauth-prefix-factory branch from a30e21e to fe35500 Compare November 22, 2023 16:26
if (!string.IsNullOrWhiteSpace(cred.Password))
{
return cred.Password;
}

return base.findLoginPassword(bookmark);
Copy link
Contributor

Choose a reason for hiding this comment

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

Because the base implementation will load the platform specific implementation of the prefix service this will cause a regression in failure finding deprecated store entries.

@dkocher dkocher force-pushed the feature/GH-15113-oauth-prefix-factory branch from 23accf1 to 8650ca9 Compare November 22, 2023 20:24
return null;
}
final PasswordStoreDescriptorService service = bookmark.getProtocol().getFeature(PasswordStoreDescriptorService.class);
final String prefix = service.getDescriptor(bookmark);
Copy link
Contributor

Choose a reason for hiding this comment

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

Unused.

final Credentials credentials = bookmark.getCredentials();
if(StringUtils.isEmpty(credentials.getUsername())) {
Copy link
Contributor

Choose a reason for hiding this comment

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

How is this case handled in the new implementation?

Copy link
Contributor

Choose a reason for hiding this comment

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

Introduce variables, e.g. URI.create(bookmark.getProtocol().getOAuthTokenUrl()) to avoid duplicate code which is not very readable as you always have to check if there is any difference to the previous usage.

var credentials = bookmark.getCredentials();

var targetBuilder = new UriBuilder(PreferencesFactory.get().getProperty("application.container.name"), string.Empty);
PasswordStoreDescriptorService service = (PasswordStoreDescriptorService)bookmark.getProtocol().getFeature(typeof(PasswordStorePrefixService));
Copy link
Contributor

Choose a reason for hiding this comment

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

Wrong type PasswordStorePrefixService.

string hostname = service.getHostname(bookmark);
if (!string.IsNullOrWhiteSpace(hostname))
{
pathBuilder.Append(hostname);
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing : between prefix and hostname?

@@ -211,27 +221,37 @@ public override void save(Host bookmark)

private static Uri ToUri(Host bookmark)
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing test coverage for such methods.

var pathBuilder = new StringBuilder();
pathBuilder.Append(protocol.getIdentifier());
if (protocol.isHostnameConfigurable() || !(protocol.isTokenConfigurable() || protocol.isOAuthConfigurable()))
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this equivalent to the new checks in CredentialManagerPasswordStoreDescriptorService which are different.

@dkocher dkocher modified the milestones: 8.7.2, 9.0 Nov 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants