github.com/rseymour/docker@v1.5.0/registry/token.go (about)

     1  package registry
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"net/http"
     8  	"net/url"
     9  	"strings"
    10  
    11  	"github.com/docker/docker/utils"
    12  )
    13  
    14  type tokenResponse struct {
    15  	Token string `json:"token"`
    16  }
    17  
    18  func getToken(username, password string, params map[string]string, registryEndpoint *Endpoint, client *http.Client, factory *utils.HTTPRequestFactory) (token string, err error) {
    19  	realm, ok := params["realm"]
    20  	if !ok {
    21  		return "", errors.New("no realm specified for token auth challenge")
    22  	}
    23  
    24  	realmURL, err := url.Parse(realm)
    25  	if err != nil {
    26  		return "", fmt.Errorf("invalid token auth challenge realm: %s", err)
    27  	}
    28  
    29  	if realmURL.Scheme == "" {
    30  		if registryEndpoint.IsSecure {
    31  			realmURL.Scheme = "https"
    32  		} else {
    33  			realmURL.Scheme = "http"
    34  		}
    35  	}
    36  
    37  	req, err := factory.NewRequest("GET", realmURL.String(), nil)
    38  	if err != nil {
    39  		return "", err
    40  	}
    41  
    42  	reqParams := req.URL.Query()
    43  	service := params["service"]
    44  	scope := params["scope"]
    45  
    46  	if service != "" {
    47  		reqParams.Add("service", service)
    48  	}
    49  
    50  	for _, scopeField := range strings.Fields(scope) {
    51  		reqParams.Add("scope", scopeField)
    52  	}
    53  
    54  	if username != "" {
    55  		reqParams.Add("account", username)
    56  		req.SetBasicAuth(username, password)
    57  	}
    58  
    59  	req.URL.RawQuery = reqParams.Encode()
    60  
    61  	resp, err := client.Do(req)
    62  	if err != nil {
    63  		return "", err
    64  	}
    65  	defer resp.Body.Close()
    66  
    67  	if resp.StatusCode != http.StatusOK {
    68  		return "", fmt.Errorf("token auth attempt for registry %s: %s request failed with status: %d %s", registryEndpoint, req.URL, resp.StatusCode, http.StatusText(resp.StatusCode))
    69  	}
    70  
    71  	decoder := json.NewDecoder(resp.Body)
    72  
    73  	tr := new(tokenResponse)
    74  	if err = decoder.Decode(tr); err != nil {
    75  		return "", fmt.Errorf("unable to decode token response: %s", err)
    76  	}
    77  
    78  	if tr.Token == "" {
    79  		return "", errors.New("authorization server did not include a token in the response")
    80  	}
    81  
    82  	return tr.Token, nil
    83  }