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

Add support for scopes to terraform login #26239

Merged
merged 4 commits into from
Sep 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions command/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@ func (c *LoginCommand) interactiveGetTokenByCode(hostname svchost.Hostname, cred
ClientID: clientConfig.ID,
Endpoint: clientConfig.Endpoint(),
RedirectURL: callbackURL,
Scopes: clientConfig.Scopes,
}

authCodeURL := oauthConfig.AuthCodeURL(
Expand Down Expand Up @@ -475,6 +476,7 @@ func (c *LoginCommand) interactiveGetTokenByPassword(hostname svchost.Hostname,
oauthConfig := &oauth2.Config{
ClientID: clientConfig.ID,
Endpoint: clientConfig.Endpoint(),
Scopes: clientConfig.Scopes,
}
token, err := oauthConfig.PasswordCredentialsToken(context.Background(), username, password)
if err != nil {
Expand Down
56 changes: 56 additions & 0 deletions command/login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@ func TestLogin(t *testing.T) {
"token": s.URL + "/token",
},
})
svcs.ForceHostServices(svchost.Hostname("with-scopes.example.com"), map[string]interface{}{
"login.v1": map[string]interface{}{
// with scopes
// mock browser launcher below.
"client": "scopes_test",
"authz": s.URL + "/authz",
"token": s.URL + "/token",
"scopes": []interface{}{"app1.full_access", "app2.read_only"},
},
})
svcs.ForceHostServices(svchost.Hostname("tfe.acme.com"), map[string]interface{}{
// This represents a Terraform Enterprise instance which does not
// yet support the login API, but does support the TFE tokens API.
Expand Down Expand Up @@ -140,6 +150,52 @@ func TestLogin(t *testing.T) {
}
}))

t.Run("example.com results in no scopes", loginTestCase(func(t *testing.T, c *LoginCommand, ui *cli.MockUi) {

host, _ := c.Services.Discover("example.com")
client, _ := host.ServiceOAuthClient("login.v1")
if len(client.Scopes) != 0 {
t.Errorf("unexpected scopes %q; expected none", client.Scopes)
}
}))

t.Run("with-scopes.example.com with authorization code flow and scopes", loginTestCase(func(t *testing.T, c *LoginCommand, ui *cli.MockUi) {
// Enter "yes" at the consent prompt.
defer testInputMap(t, map[string]string{
"approve": "yes",
})()
status := c.Run([]string{"with-scopes.example.com"})
if status != 0 {
t.Fatalf("unexpected error code %d\nstderr:\n%s", status, ui.ErrorWriter.String())
}

credsSrc := c.Services.CredentialsSource()
creds, err := credsSrc.ForHost(svchost.Hostname("with-scopes.example.com"))

if err != nil {
t.Errorf("failed to retrieve credentials: %s", err)
}

if got, want := creds.Token(), "good-token"; got != want {
t.Errorf("wrong token %q; want %q", got, want)
}
}))

t.Run("with-scopes.example.com results in expected scopes", loginTestCase(func(t *testing.T, c *LoginCommand, ui *cli.MockUi) {

host, _ := c.Services.Discover("with-scopes.example.com")
client, _ := host.ServiceOAuthClient("login.v1")

expectedScopes := [2]string{"app1.full_access", "app2.read_only"}

var foundScopes [2]string
copy(foundScopes[:], client.Scopes)

if foundScopes != expectedScopes || len(client.Scopes) != len(expectedScopes) {
t.Errorf("unexpected scopes %q; want %q", client.Scopes, expectedScopes)
}
}))

t.Run("TFE host without login support", loginTestCase(func(t *testing.T, c *LoginCommand, ui *cli.MockUi) {
// Enter "yes" at the consent prompt, then paste a token with some
// accidental whitespace.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ require (
github.com/hashicorp/memberlist v0.1.0 // indirect
github.com/hashicorp/serf v0.0.0-20160124182025-e4ec8cc423bb // indirect
github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7
github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734
github.com/hashicorp/vault v0.10.4
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect
github.com/imdario/mergo v0.3.9 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7
github.com/hashicorp/terraform-config-inspect v0.0.0-20191212124732-c6ae6269b9d7/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A=
github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596 h1:hjyO2JsNZUKT1ym+FAdlBEkGPevazYsmVgIMw7dVELg=
github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg=
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 h1:HKLsbzeOsfXmKNpr3GiT18XAblV0BjCbzL8KQAMZGa0=
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734/go.mod h1:kNDNcF7sN4DocDLBkQYz73HGKwN1ANB1blq4lIYLYvg=
github.com/hashicorp/vault v0.10.4 h1:4x0lHxui/ZRp/B3E0Auv1QNBJpzETqHR2kQD3mHSBJU=
github.com/hashicorp/vault v0.10.4/go.mod h1:KfSyffbKxoVyspOdlaGVjIuwLobi07qD1bAbosPMpP0=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
Expand Down
Loading