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

create credential conveniences #36

Merged
merged 7 commits into from
Nov 9, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
51 changes: 50 additions & 1 deletion cmd/dependabot/internal/cmd/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,56 @@ func processInput(input *model.Input) {
// Process environment variables in the scenario file
for _, cred := range input.Credentials {
for key, value := range cred {
cred[key] = os.ExpandEnv(value)
if valueString, ok := value.(string); ok {
cred[key] = os.ExpandEnv(valueString)
}
}
}

// As a convenience, fill in a git_source if credentials are in the environment and a git_source
// doesn't already exist. This way the user doesn't run out of calls from being anonymous.
token := os.Getenv("LOCAL_GITHUB_ACCESS_TOKEN")
var isGitSourceInCreds bool
for _, cred := range input.Credentials {
if cred["type"] == "git_source" {
isGitSourceInCreds = true
break
}
}
if token != "" && !isGitSourceInCreds {
input.Credentials = append(input.Credentials, model.Credential{
"type": "git_source",
"host": "github.com",
"username": "x-access-token",
"password": token,
})
if len(input.Job.CredentialsMetadata) > 0 {
// Add the metadata since the next section will be skipped.
input.Job.CredentialsMetadata = append(input.Job.CredentialsMetadata, map[string]any{
"type": "git_source",
"host": "github.com",
})
}
}

// As a convenience, fill credentials-metadata if credentials are provided
// which is what happens in production. This way the user doesn't have to
// specify credentials-metadata in the scenario file unless they want to.
if len(input.Job.CredentialsMetadata) == 0 {
for _, credential := range input.Credentials {
entry := map[string]any{
"type": credential["type"],
}
if credential["host"] != nil {
entry["host"] = credential["host"]
}
if credential["url"] != nil {
entry["url"] = credential["url"]
}
if credential["replaces-base"] != nil {
entry["replaces-base"] = credential["replaces-base"]
}
input.Job.CredentialsMetadata = append(input.Job.CredentialsMetadata, entry)
}
}
}
Expand Down
83 changes: 83 additions & 0 deletions cmd/dependabot/internal/cmd/update_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package cmd

import (
"os"
"reflect"
"testing"

"github.com/dependabot/cli/internal/model"
)

func Test_processInput(t *testing.T) {
t.Run("initializes some fields", func(t *testing.T) {
var input model.Input
processInput(&input)

if input.Job.ExistingPullRequests == nil {
t.Error("expected existing pull requests to be initialized")
}
if input.Job.IgnoreConditions == nil {
t.Error("expected ignore conditions to be initialized")
}
if input.Job.SecurityAdvisories == nil {
t.Error("expected security advisories to be initialized")
}
})

t.Run("injects environment variables", func(t *testing.T) {
var input model.Input
input.Credentials = []model.Credential{{
"type": "any",
"host": "host",
"url": "url",
"username": "$ENV1",
"pass": "$ENV2",
}}
os.Setenv("ENV1", "value1")
os.Setenv("ENV2", "value2")
os.Setenv("LOCAL_GITHUB_ACCESS_TOKEN", "") // fixes test while running locally

processInput(&input)

if input.Credentials[0]["username"] != "value1" {
t.Error("expected username to be injected")
}
if input.Credentials[0]["pass"] != "value2" {
t.Error("expected pass to be injected")
}
if !reflect.DeepEqual(input.Job.CredentialsMetadata, []model.Credential{{
"type": "any",
"host": "host",
"url": "url",
}}) {
t.Error("expected credentials metadata to be to", input.Job.CredentialsMetadata)
}
})

t.Run("adds git_source to credentials", func(t *testing.T) {
var input model.Input
os.Setenv("LOCAL_GITHUB_ACCESS_TOKEN", "token")
// Adding a dummy metadata to test the inner if
input.Job.CredentialsMetadata = []model.Credential{{}}

processInput(&input)

if len(input.Credentials) != 1 {
t.Fatal("expected credentials to be added")
}
if !reflect.DeepEqual(input.Credentials[0], model.Credential{
"type": "git_source",
"host": "github.com",
"username": "x-access-token",
"password": "token",
}) {
t.Error("expected credentials to be added")
}
if !reflect.DeepEqual(input.Job.CredentialsMetadata[1], model.Credential{
"type": "git_source",
"host": "github.com",
}) {
t.Error("expected credentials metadata to be added")
}
})
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ require (
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/testify v1.8.0 // indirect
golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 // indirect
golang.org/x/sys v0.1.0 // indirect
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect
gotest.tools/v3 v3.3.0 // indirect
)
3 changes: 2 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,9 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 h1:2B5p2L5IfGiD7+b9BOoRMC6DgObAVZV+Fsp050NqXik=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U=
Expand Down
4 changes: 3 additions & 1 deletion internal/infra/config.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package infra

import "github.com/dependabot/cli/internal/model"

// ConfigFilePath is the path to proxy config file.
const ConfigFilePath = "/config.json"

// Config is the structure of the proxy's config file
type Config struct {
Credentials []map[string]string `json:"all_credentials"`
Credentials []model.Credential `json:"all_credentials"`
CA CertificateAuthority `json:"ca"`
}

Expand Down
12 changes: 1 addition & 11 deletions internal/infra/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type RunParams struct {
// expectations asserted at the end of a test
Expected []model.Output
// credentials passed to the proxy
Creds []map[string]string
Creds []model.Credential
// local directory used for caching
CacheDir string
// write output to a file
Expand Down Expand Up @@ -63,16 +63,6 @@ func Run(params RunParams) error {
api := server.NewAPI(params.Expected)
defer api.Stop()

token := os.Getenv("LOCAL_GITHUB_ACCESS_TOKEN")
if token != "" {
params.Creds = append(params.Creds, map[string]string{
"type": "git_source",
"host": "github.com",
"username": "x-access-token",
"password": token,
})
}

var outFile *os.File
if params.Output != "" {
var err error
Expand Down
38 changes: 20 additions & 18 deletions internal/model/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@ package model

// Job is the data that is passed to the updater.
type Job struct {
PackageManager string `json:"package-manager" yaml:"package-manager"`
AllowedUpdates []Allowed `json:"allowed-updates" yaml:"allowed-updates,omitempty"`
Dependencies []string `json:"dependencies" yaml:"dependencies,omitempty"`
ExistingPullRequests [][]ExistingPR `json:"existing-pull-requests" yaml:"existing-pull-requests,omitempty"`
Experiments Experiment `json:"experiments" yaml:"experiments,omitempty"`
IgnoreConditions []Condition `json:"ignore-conditions" yaml:"ignore-conditions,omitempty"`
LockfileOnly bool `json:"lockfile-only" yaml:"lockfile-only,omitempty"`
RequirementsUpdateStrategy *string `json:"requirements-update-strategy" yaml:"requirements-update-strategy,omitempty"`
SecurityAdvisories []Advisory `json:"security-advisories" yaml:"security-advisories,omitempty"`
SecurityUpdatesOnly bool `json:"security-updates-only" yaml:"security-updates-only,omitempty"`
Source Source `json:"source" yaml:"source"`
UpdateSubdependencies bool `json:"update-subdependencies" yaml:"update-subdependencies,omitempty"`
UpdatingAPullRequest bool `json:"updating-a-pull-request" yaml:"updating-a-pull-request,omitempty"`
VendorDependencies bool `json:"vendor-dependencies" yaml:"vendor-dependencies,omitempty"`
RejectExternalCode bool `json:"reject-external-code" yaml:"reject-external-code,omitempty"`
CommitMessageOptions *CommitOptions `json:"commit-message-options" yaml:"commit-message-options,omitempty"`
CredentialsMetadata []map[string]any `json:"credentials-metadata" yaml:"credentials-metadata,omitempty"`
MaxUpdaterRunTime int `json:"max-updater-run-time" yaml:"max-updater-run-time,omitempty"`
PackageManager string `json:"package-manager" yaml:"package-manager"`
AllowedUpdates []Allowed `json:"allowed-updates" yaml:"allowed-updates,omitempty"`
Dependencies []string `json:"dependencies" yaml:"dependencies,omitempty"`
ExistingPullRequests [][]ExistingPR `json:"existing-pull-requests" yaml:"existing-pull-requests,omitempty"`
Experiments Experiment `json:"experiments" yaml:"experiments,omitempty"`
IgnoreConditions []Condition `json:"ignore-conditions" yaml:"ignore-conditions,omitempty"`
LockfileOnly bool `json:"lockfile-only" yaml:"lockfile-only,omitempty"`
RequirementsUpdateStrategy *string `json:"requirements-update-strategy" yaml:"requirements-update-strategy,omitempty"`
SecurityAdvisories []Advisory `json:"security-advisories" yaml:"security-advisories,omitempty"`
SecurityUpdatesOnly bool `json:"security-updates-only" yaml:"security-updates-only,omitempty"`
Source Source `json:"source" yaml:"source"`
UpdateSubdependencies bool `json:"update-subdependencies" yaml:"update-subdependencies,omitempty"`
UpdatingAPullRequest bool `json:"updating-a-pull-request" yaml:"updating-a-pull-request,omitempty"`
VendorDependencies bool `json:"vendor-dependencies" yaml:"vendor-dependencies,omitempty"`
RejectExternalCode bool `json:"reject-external-code" yaml:"reject-external-code,omitempty"`
CommitMessageOptions *CommitOptions `json:"commit-message-options" yaml:"commit-message-options,omitempty"`
CredentialsMetadata []Credential `json:"credentials-metadata" yaml:"credentials-metadata,omitempty"`
MaxUpdaterRunTime int `json:"max-updater-run-time" yaml:"max-updater-run-time,omitempty"`
}

// Source is a reference to some source code
Expand Down Expand Up @@ -86,3 +86,5 @@ type CommitOptions struct {
PrefixDevelopment string `json:"prefix-development,omitempty" yaml:"prefix-development,omitempty"`
IncludeScope *string `json:"include-scope,omitempty" yaml:"include-scope,omitempty"`
}

type Credential map[string]any
2 changes: 1 addition & 1 deletion internal/model/scenario.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type Input struct {
// Job is the data given to the updater
Job Job `yaml:"job"`
// Credentials is the registry info and tokens to pass to the Proxy
Credentials []map[string]string `yaml:"credentials,omitempty"`
Credentials []Credential `yaml:"credentials,omitempty"`
}

// Output is the expected output given the inputs
Expand Down