diff --git a/.travis.yml b/.travis.yml index 3d87c74..fa8851a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ --- + # See appveyor.yml for windows build. sudo: false language: go os: @@ -6,7 +7,7 @@ notifications: email: false go: - - 1.5 + - 1.6 install: make deps before_script: make validate script: make test diff --git a/Makefile b/Makefile index 7ca9899..e2e465b 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,10 @@ osxkeychain: mkdir -p bin go build -o bin/docker-credential-osxkeychain osxkeychain/cmd/main_darwin.go +wincred: + mkdir -p bin + go build -o bin/docker-credential-wincred wincred/cmd/main_windows.go + test: go test -v ./... diff --git a/README.md b/README.md index b6f5627..9251f47 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ Set the `credsStore` option in your `.docker/config.json` file with the suffix o ### Available programs 1. osxkeychain: Provides a helper to use the OS X keychain as credentials store. +2. wincred: Provides a helper to use Windows credentials manager as store. ## Development diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..9dd4afd --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,48 @@ +version: "{build}" + +# Source Config +clone_folder: c:\gopath\src\github.com\docker\docker-credential-helpers + +# Build host + +os: Windows Server 2012 R2 + +environment: + GOPATH: c:\gopath + CGO_ENABLED: 1 + GOVERSION: 1.6 + +init: + - git config --global core.autocrlf input + +# Build + +install: + # Install Go 1.6. + - rmdir c:\go /s /q + - appveyor DownloadFile https://storage.googleapis.com/golang/go%GOVERSION%.windows-amd64.msi + - msiexec /i go%GOVERSION%.windows-amd64.msi /q + # Install MinGW. + - ps: | + $url = "https://bintray.com/artifact/download/drewwells/generic/x86_64-5.1.0-release-win32-seh-rt_v4-rev0.7z" + $strFileName="C:\mingw64\bin\mingw32-make.exe" + If (Test-Path $strFileName){ + Write-Host "Using cached mingw64" + }Else{ + Write-Host "Fetching mingw64" + Invoke-WebRequest -UserAgent wget -Uri $url -OutFile ming32-64.7z + &7z x -oC:\ ming32-64.7z > $null + } + - set Path=c:\mingw64\bin;c:\go\bin;%Path% + - go version + - go env + - go get -v -t ./... + +build_script: + - go test -v github.com/docker/docker-credential-helpers/wincred + +# Disable automatic tests +test: off + +# Disable deployment +deploy: off diff --git a/wincred/cmd/main_windows.go b/wincred/cmd/main_windows.go new file mode 100644 index 0000000..6113445 --- /dev/null +++ b/wincred/cmd/main_windows.go @@ -0,0 +1,10 @@ +package main + +import ( + "github.com/docker/docker-credential-helpers/credentials" + "github.com/docker/docker-credential-helpers/wincred" +) + +func main() { + credentials.Serve(wincred.New()) +} diff --git a/wincred/wincred_windows.go b/wincred/wincred_windows.go new file mode 100644 index 0000000..1cecf33 --- /dev/null +++ b/wincred/wincred_windows.go @@ -0,0 +1,43 @@ +package wincred + +import ( + winc "github.com/danieljoos/wincred" + "github.com/docker/docker-credential-helpers/credentials" +) + +type wincred struct{} + +// New creates a new wincred. +func New() credentials.Helper { + return wincred{} +} + +// Add adds new credentials to the windows credentials manager. +func (h wincred) Add(creds *credentials.Credentials) error { + g := winc.NewGenericCredential(creds.ServerURL) + g.UserName = creds.Username + g.CredentialBlob = []byte(creds.Password) + g.Persist = winc.PersistLocalMachine + return g.Write() +} + +// Delete removes credentials from the windows credentials manager. +func (h wincred) Delete(serverURL string) error { + g, err := winc.GetGenericCredential(serverURL) + if g == nil { + return nil + } + if err != nil { + return err + } + return g.Delete() +} + +// Get retrieves credentials from the windows credentials manager. +func (h wincred) Get(serverURL string) (string, string, error) { + g, _ := winc.GetGenericCredential(serverURL) + if g == nil { + return "", "", credentials.ErrCredentialsNotFound + } + return g.UserName, string(g.CredentialBlob), nil +} diff --git a/wincred/wincred_windows_test.go b/wincred/wincred_windows_test.go new file mode 100644 index 0000000..79d0453 --- /dev/null +++ b/wincred/wincred_windows_test.go @@ -0,0 +1,45 @@ +package wincred + +import ( + "testing" + + "github.com/docker/docker-credential-helpers/credentials" +) + +func TestWinCredHelper(t *testing.T) { + creds := &credentials.Credentials{ + ServerURL: "https://foobar.docker.io:2376/v1", + Username: "foobar", + Password: "foobarbaz", + } + + helper := New() + if err := helper.Add(creds); err != nil { + t.Fatal(err) + } + + username, password, err := helper.Get(creds.ServerURL) + if err != nil { + t.Fatal(err) + } + + if username != "foobar" { + t.Fatalf("expected %s, got %s\n", "foobar", username) + } + + if password != "foobarbaz" { + t.Fatalf("expected %s, got %s\n", "foobarbaz", password) + } + + if err := helper.Delete(creds.ServerURL); err != nil { + t.Fatal(err) + } +} + +func TestMissingCredentials(t *testing.T) { + helper := New() + _, _, err := helper.Get("https://adsfasdf.wrewerwer.com/asdfsdddd") + if err != credentials.ErrCredentialsNotFound { + t.Fatalf("exptected ErrCredentialsNotFound, got %v", err) + } +}