Skip to content

Third party hosted pub registry authentication #3007

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

Merged
merged 83 commits into from
Sep 14, 2021
Merged

Third party hosted pub registry authentication #3007

merged 83 commits into from
Sep 14, 2021

Conversation

themisir
Copy link
Contributor

@themisir themisir commented May 20, 2021

Closes #1381

This PR adds support to pub CLI to authenticate with third party hosted pub servers. Before that only official pub servers: pub.dev (aka: pub.dartlang.org) could be authenticated and the authentication was only applied when publishing packages. We usually need to share some pieces of code across company projects. In other ecosystems like npm, nuget, docker this could be done using private repositories / servers. Private repositories does needs authentication for both pulling and pushing data to it - unlike pub's current behavior which only does authenticates requests for pushing new packages.

CLI Interface

dart pub login                      # Will initiate login-flow for pub.dev
dart pub logout                     # Will delete credential.json

dart pub token list                # Will list servers for which a token exists
dart pub token add <hosted_url>    # Will prompt for a token for <hosted_url> and store both
dart pub token remove <hosted_url> # Will remove token for <hosted_url>
dart pub token remove --all        # Will delete all tokens stored

@google-cla google-cla bot added the cla: yes label May 20, 2021
Copy link
Contributor

@sigurdm sigurdm left a comment

Choose a reason for hiding this comment

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

I think this starts looking good.
LGTM assuming the last comments are addressed

@themisir
Copy link
Contributor Author

themisir commented Sep 10, 2021

fyi @sigurdm adding limitation to use OAuth credentials only for pub.dev official servers caused some tests to fail (probably because they're using localhost server to test the feature).

Should I revert those changes back or what would you suggest?

Maybe we could override "official pub server" url using environment variable for the sake of tests. Any suggestions?

Copy link
Member

@jonasfj jonasfj left a comment

Choose a reason for hiding this comment

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

Just a few nits... the part about truncatedMessage is probably important.

An attacker could otherwise make some very confusing output in the terminal 🙈

}

final hostedUrl = validateAndNormalizeHostedUrl(json['url'] as String);
final token = json['token'] is String ? json['token'] as String : null;
Copy link
Member

Choose a reason for hiding this comment

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

Let's throw a FormatException if token == null, then we can remove the nullability...

And if we throw FormatException here, that's fine, because in List<Credential> _loadCredentials() { we will appropriately log: Failed to load credentials for ${element['url']}:

Comment on lines +78 to +81
throw DataException(
'Saved credential for $url pub repository is not supported by current '
'version of Dart SDK.',
);
Copy link
Member

Choose a reason for hiding this comment

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

Let's make this a format exception when loading. Then it'll get logged as a warning every time the user uses an old pub version with a newer config file.

Hmm, I can see that being less smart, but I also don't like dragging around nullability.

@sigurdm any thoughts here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The issue is current saving mechanism will remove entries that doesn't contains 'token' property because it'll not be able to deserialize it. So they'll not added to the credential list and when saving those entries will be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wanted to encapsulate json serialization part to Credential class itself to reduce code duplication for serialization & validation, otherwise the code would look like much confusing I think.

@sigurdm
Copy link
Contributor

sigurdm commented Sep 13, 2021

fyi @sigurdm adding limitation to use OAuth credentials only for pub.dev official servers caused some tests to fail (probably because they're using localhost server to test the feature).

Should I revert those changes back or what would you suggest?

Maybe we could override "official pub server" url using environment variable for the sake of tests. Any suggestions?

Yes - I think that is the way to go!
We have runningFromTest in lib/src/io.dart - I suggest if that is true then we consider the host of PUB_HOSTED_URL to be the "official" host that gets the credentials.

(PS When landing: https://github.com/dart-lang/pub/pull/3092this will be more safe, because runningFromTest will no longer only depend on the environment.)

@themisir
Copy link
Contributor Author

We have runningFromTest in lib/src/io.dart - I suggest if that is true then we consider the host of PUB_HOSTED_URL to be the "official" host that gets the credentials.

Yes, used this method - it works. In future when we create integration tests for using token authentication for publishing we might want to declare another environment variable to provide whether given PUB_HOSTED_URL should use oauth2 authentication (or: considered as an official pub server) or uses token authentication. But for now it works and aside from testing I don't think this might cause any issue for production.

@themisir
Copy link
Contributor Author

Do I have to write integration tests for server integration or we could do that in a separate PR later?

@sigurdm
Copy link
Contributor

sigurdm commented Sep 14, 2021

Thanks @themisir for all the hard work on this!

@sigurdm sigurdm merged commit bbdac80 into dart-lang:master Sep 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support authenticating pub against 3rd-party servers
5 participants