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  }