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 }