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

Silent login: use credentials from cred store to login #139

Merged
merged 1 commit into from
Feb 27, 2018
Merged

Silent login: use credentials from cred store to login #139

merged 1 commit into from
Feb 27, 2018

Conversation

shhsu
Copy link
Contributor

@shhsu shhsu commented May 30, 2017

- What I did
As discussed in #130 (comment), Azure Container Registry wants a way for docker login <registry> to proceed to log in if the credential store returns username and password.

This is a minor behavior change for docker login command scenario. In particular: when user call docker login without -p and -u, it used to be that the user would be prompted for new username and password interactively in all situations.

The new behavior would be a lot like docker pull. docker login. With this change, docker would now try to find credentials in the cred store first and try to login with it. Only if it fails with 401 status would docker cli prompt for new username and password.

- How I did it
The surface area of this code change was a little bigger than expected because of some refactoring. Functionality changes are mostly in cli/command/registry/login.go. There are some refactoring going on mainly in cli/command/registry.go because I didn't want to call cli.CredentialsStore(serverAddress).Get(serverAddress) twice in the scenario where docker is prompting for credentials interactively and looking for existing username in the cred store as default parameters.

I actually think the refactor may be useful as I can see similar changes being done to refactor pull, push, etc to save a call to CredentialsStore.Get in similar situation.

- How to verify it

Manually ran docker login with or without -p, -u with default registry. Observed expected behavior change:

  • Login prompt occurs as normal if the user wasn't logged in.
  • Login prompt would be omitted if the user was already logged in
  • Login prompt would occur if cred store credential is incorrect (simulate a credential expired scenario)

Manually ran docker login <registry> on Azure Container Registry

  • Login prompt is shown as expected, cred store is updated only after login

Manually ran docker pull <registry> without logging in and trigger a login

  • Login prompt is shown as expected, pull proceeded only after login

@codecov-io
Copy link

codecov-io commented May 30, 2017

Codecov Report

Merging #139 into master will decrease coverage by 0.26%.
The diff coverage is 64.81%.

@@            Coverage Diff             @@
##           master     #139      +/-   ##
==========================================
- Coverage   53.26%   52.99%   -0.27%     
==========================================
  Files         258      261       +3     
  Lines       16357    16528     +171     
==========================================
+ Hits         8712     8759      +47     
- Misses       7081     7196     +115     
- Partials      564      573       +9

func TestGetDefaultAuthConfig(t *testing.T) {
testCases := []struct {
checkCredStore bool
expectErr bool
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of a boolean for the error could you use expectedErr string, and check that the error message contains that string.

expectErr bool
expectedAuthServer string
expectedUsername string
expectedPassword string
Copy link
Contributor

Choose a reason for hiding this comment

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

testify assertions can compare structs, so instead of separate fields for these I think it should be expected authConfig, that way you can just assert.Equal(t, testcase.expected, authconfig)

} else if client.IsErrUnauthorized(err) {
fmt.Println("Stored credentials invalid or expired")
} else {
fmt.Println("Login did not succeed")
Copy link
Contributor

Choose a reason for hiding this comment

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

These should print to dockerCli.Err()

@friism
Copy link
Contributor

friism commented May 31, 2017

Ping @n4ss @thaJeztah

@shhsu
Copy link
Contributor Author

shhsu commented May 31, 2017

@sajayantony @DavidObando

@DavidObando
Copy link

Hi, I see this is labeled as "design review". We'll be happy to hear of any feedback you may have to light up this scenario.

@n4ss
Copy link
Contributor

n4ss commented Jun 9, 2017

Hey, very sorry for the delayed answer!

I like the idea of automatically looking in the credstore at login by default to see if something already exists. This makes the experience way more user-friendly.

I know that this system won't be a problem for some of the credstores but I'm trying to come up with an attack scenario against this.

@DavidObando
Copy link

Hi @n4ss we'd love to hear some feedback on this when you have some.

@justincormack
Copy link
Member

I can't see any security issues with this. Needs a rebase though!

@n4ss
Copy link
Contributor

n4ss commented Feb 20, 2018

Double approval, lgtm on rebase as well.

@shhsu
Copy link
Contributor Author

shhsu commented Feb 21, 2018

Hold on, Fixing the failed tests...

@shhsu
Copy link
Contributor Author

shhsu commented Feb 21, 2018

Rebase done
Also run a couple rounds of manual testing. Seems to work.

@n4ss
Copy link
Contributor

n4ss commented Feb 21, 2018

ping @thaJeztah @vdemeester ^_^

@docker docker deleted a comment from GordonTheTurtle Feb 22, 2018
Copy link
Collaborator

@vdemeester vdemeester left a comment

Choose a reason for hiding this comment

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

LGTM 🐯

"testing"

"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"

// Prevents a circular import with "github.com/docker/cli/internal/test"

"fmt"
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: this import should be on top 👼

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

@thaJeztah
Copy link
Member

@shhsu can you address @vdemeester's nit, and squash commits (where applicable; looks like there's some "fix up" commits in there)

…d but both username and password are retrieved in cred store, docker will automatically use the credentials found in the cred store to log in

Signed-off-by: shhsu@microsoft.com <shhsu@microsoft.com>
Signed-off-by: Peter Hsu <shhsu@microsoft.com>
Signed-off-by: shhsu <shhsu@microsoft.com>
Signed-off-by: Peter Hsu <shhsu@microsoft.com>
@shhsu
Copy link
Contributor Author

shhsu commented Feb 22, 2018

Done

@thaJeztah @vdemeester

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

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

Successfully merging this pull request may close these issues.

10 participants