(ctx context.Context, ref reference.Named, version, team, username, password string, insecureSkipVerify bool)
| 423 | } |
| 424 | |
| 425 | func getDockerToken(ctx context.Context, ref reference.Named, version, team, username, password string, insecureSkipVerify bool) (string, error) { |
| 426 | // https://distribution.github.io/distribution/spec/auth/token/#how-to-authenticate |
| 427 | domain := reference.Domain(ref) |
| 428 | name := reference.Path(ref) |
| 429 | |
| 430 | customTransport := http.DefaultTransport.(*http.Transport).Clone() |
| 431 | customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: insecureSkipVerify} |
| 432 | httpClient := &http.Client{Transport: customTransport} |
| 433 | |
| 434 | challengeUrl := fmt.Sprintf("https://%[1]s/v2/%[2]s/manifests/%[3]s", domain, name, version) |
| 435 | challengeReq, err := http.NewRequestWithContext(ctx, http.MethodPut, challengeUrl, nil) |
| 436 | if err != nil { |
| 437 | return "", fmt.Errorf("client: could not create request: %s", err) |
| 438 | } |
| 439 | challengeRes, err := httpClient.Do(challengeReq) |
| 440 | if err != nil { |
| 441 | return "", fmt.Errorf("client: could not send request: %s", err) |
| 442 | } |
| 443 | defer challengeRes.Body.Close() |
| 444 | if challengeRes.StatusCode != http.StatusUnauthorized { |
| 445 | return "", fmt.Errorf("client: unexpected status code: %d", challengeRes.StatusCode) |
| 446 | } |
| 447 | challengeHeader := challengeRes.Header.Get("WWW-Authenticate") |
| 448 | if challengeHeader == "" { |
| 449 | return "", errors.New("client: missing WWW-Authenticate header") |
| 450 | } |
| 451 | challenges := challenge.ResponseChallenges(challengeRes) |
| 452 | if len(challenges) != 1 { |
| 453 | return "", fmt.Errorf("client: expected 1 challenge header, got %d. Header value %q", len(challenges), challengeHeader) |
| 454 | } |
| 455 | realm := challenges[0].Parameters["realm"] |
| 456 | service := challenges[0].Parameters["service"] |
| 457 | scope := challenges[0].Parameters["scope"] |
| 458 | if realm == "" || service == "" || scope == "" { |
| 459 | return "", fmt.Errorf("client: could not parse challenge header %q", challengeHeader) |
| 460 | } |
| 461 | |
| 462 | url := fmt.Sprintf("%[1]s?account=cli&service=%[2]s&scope=%[3]s", realm, service, scope) |
| 463 | req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) |
| 464 | basicAuth := base64.StdEncoding.EncodeToString([]byte(username + ":" + password)) |
| 465 | req.Header.Add("X-Meta-Plugin-Version", version) |
| 466 | req.Header.Add("X-Meta-User-Team-Name", team) |
| 467 | req.Header.Add("Authorization", "Basic "+basicAuth) |
| 468 | if err != nil { |
| 469 | return "", fmt.Errorf("client: could not create request: %s", err) |
| 470 | } |
| 471 | |
| 472 | res, err := httpClient.Do(req) |
| 473 | if err != nil { |
| 474 | return "", fmt.Errorf("client: could not send request: %s", err) |
| 475 | } |
| 476 | defer res.Body.Close() |
| 477 | |
| 478 | if res.StatusCode != http.StatusOK { |
| 479 | return "", fmt.Errorf("client: unexpected status code: %d", res.StatusCode) |
| 480 | } |
| 481 | |
| 482 | tokenResponse := map[string]string{} |
no test coverage detected