diff --git a/go.mod b/go.mod index 95f9188ce423fd0711576b9f94e017b101eb8d37..3f935b0a12968695634ca1223ffb116631eabcda 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require github.com/stretchr/testify v1.8.4 require ( github.com/ceph/go-ceph v0.24.0 github.com/davecgh/go-spew v1.1.1 // indirect + github.com/jdxcode/netrc v1.0.0 github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.5 golang.org/x/sys v0.15.0 // indirect diff --git a/go.sum b/go.sum index b914a329e5e1bf0d890a2664e069dc760fa5fede..a4223407313c073cfc14814943562c86ba65faf3 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,11 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= +github.com/jdxcode/netrc v1.0.0 h1:tJR3fyzTcjDi22t30pCdpOT8WJ5gb32zfYE1hFNCOjk= +github.com/jdxcode/netrc v1.0.0/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -25,6 +30,7 @@ golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/http.go b/http.go index 56f6264a625d129ed2df1457b045371ffe75189b..f5ffe74da5d0b10b8393883b3e2463f25bac3a70 100644 --- a/http.go +++ b/http.go @@ -1,12 +1,18 @@ package fetch import ( + "fmt" "io" "net/http" "net/url" + "sync" "time" + + "github.com/jdxcode/netrc" ) +var defaultNetrcFinder = FindNetrc + type HTTPFetcher struct { client *http.Client } @@ -57,3 +63,26 @@ func NewHTTPFetcher(client *http.Client) *HTTPFetcher { } return &HTTPFetcher{client: client} } + +// Sets basic auth on redirect if the host is in the netrc file. +func newRedirectWithNetrcCredentials() (func(*http.Request, []*http.Request) error, error) { + fpath, err := defaultNetrcFinder() + if err != nil { + return nil, err + } + nc, err := netrc.Parse(fpath) + if err != nil { + return nil, fmt.Errorf("failed to read netrc: %w", err) + } + mu := &sync.Mutex{} + return func(req *http.Request, via []*http.Request) error { + host := req.URL.Hostname() + mu.Lock() + machine := nc.Machine(host) + mu.Unlock() + if machine != nil { + req.SetBasicAuth(machine.Get("login"), machine.Get("password")) + } + return nil + }, nil +} diff --git a/netrc.go b/netrc.go new file mode 100644 index 0000000000000000000000000000000000000000..168ee9d2b20fe44dad69662a5ab4eb3737ef2940 --- /dev/null +++ b/netrc.go @@ -0,0 +1,32 @@ +package fetch + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "runtime" +) + +// findNetrc trys to lookup .netrc(_netrc on windows) in the home dir +func FindNetrc() (string, error) { + var fpath string + if s, ok := os.LookupEnv("NETRC"); ok { + fpath = s + } else { + home, err := os.UserHomeDir() + if err != nil { + return "", fmt.Errorf("getting user home dir: %w", err) + } + name := ".netrc" + if runtime.GOOS == "windows" { + name = "_netrc" + } + fpath = filepath.Join(home, name) + } + _, err := os.Stat(fpath) + if errors.Is(err, os.ErrNotExist) { + return "", fmt.Errorf("%s: %w", fpath, err) + } + return fpath, nil +}