github.com/drone/runner-go@v1.12.0/registry/auths/auth.go (about) 1 // Copyright 2019 Drone.IO Inc. All rights reserved. 2 // Use of this source code is governed by the Polyform License 3 // that can be found in the LICENSE file. 4 5 package auths 6 7 import ( 8 "bytes" 9 "encoding/base64" 10 "encoding/json" 11 "io" 12 "net/url" 13 "os" 14 "strings" 15 16 "github.com/drone/drone-go/drone" 17 ) 18 19 type ( 20 // config represents the Docker client configuration, 21 // typically located at ~/.docker/config.json 22 config struct { 23 Auths map[string]auth `json:"auths"` 24 } 25 26 // auth stores the registry authentication string. 27 auth struct { 28 Auth string `json:"auth"` 29 Username string `json:"username,omitempty"` 30 Password string `json:"password,omitempty"` 31 } 32 ) 33 34 // Parse parses the registry credential from the reader. 35 func Parse(r io.Reader) ([]*drone.Registry, error) { 36 c := new(config) 37 err := json.NewDecoder(r).Decode(c) 38 if err != nil { 39 return nil, err 40 } 41 var auths []*drone.Registry 42 for k, v := range c.Auths { 43 username, password := v.Username, v.Password 44 if v.Auth != "" { 45 username, password = decode(v.Auth) 46 } 47 auths = append(auths, &drone.Registry{ 48 Address: hostname(k), 49 Username: username, 50 Password: password, 51 }) 52 } 53 return auths, nil 54 } 55 56 // ParseFile parses the registry credential file. 57 func ParseFile(filepath string) ([]*drone.Registry, error) { 58 f, err := os.Open(filepath) 59 if err != nil { 60 return nil, err 61 } 62 defer f.Close() 63 return Parse(f) 64 } 65 66 // ParseString parses the registry credential file. 67 func ParseString(s string) ([]*drone.Registry, error) { 68 return Parse(strings.NewReader(s)) 69 } 70 71 // ParseBytes parses the registry credential file. 72 func ParseBytes(b []byte) ([]*drone.Registry, error) { 73 return Parse(bytes.NewReader(b)) 74 } 75 76 // Header returns the json marshaled, base64 encoded 77 // credential string that can be passed to the docker 78 // registry authentication header. 79 func Header(username, password string) string { 80 v := struct { 81 Username string `json:"username,omitempty"` 82 Password string `json:"password,omitempty"` 83 }{ 84 Username: username, 85 Password: password, 86 } 87 buf, _ := json.Marshal(&v) 88 return base64.URLEncoding.EncodeToString(buf) 89 } 90 91 // encode returns the encoded credentials. 92 func encode(username, password string) string { 93 return base64.StdEncoding.EncodeToString( 94 []byte(username + ":" + password), 95 ) 96 } 97 98 // decode returns the decoded credentials. 99 func decode(s string) (username, password string) { 100 d, err := base64.StdEncoding.DecodeString(s) 101 if err != nil { 102 return 103 } 104 parts := strings.SplitN(string(d), ":", 2) 105 if len(parts) > 0 { 106 username = parts[0] 107 } 108 if len(parts) > 1 { 109 password = parts[1] 110 } 111 return 112 } 113 114 // hostname returns the trimmed hostname from the 115 // registry url. 116 func hostname(s string) string { 117 uri, _ := url.Parse(s) 118 if uri != nil && uri.Host != "" { 119 s = uri.Host 120 } 121 return s 122 }