mirror of
https://github.com/rancher/os.git
synced 2025-09-01 14:48:55 +00:00
migrate to upstream libcompose in one and a half go
This commit is contained in:
75
vendor/github.com/docker/distribution/registry/client/auth/session.go
generated
vendored
75
vendor/github.com/docker/distribution/registry/client/auth/session.go
generated
vendored
@@ -10,6 +10,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/distribution/registry/client"
|
||||
"github.com/docker/distribution/registry/client/transport"
|
||||
)
|
||||
@@ -85,11 +86,24 @@ func (ea *endpointAuthorizer) ModifyRequest(req *http.Request) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// This is the minimum duration a token can last (in seconds).
|
||||
// A token must not live less than 60 seconds because older versions
|
||||
// of the Docker client didn't read their expiration from the token
|
||||
// response and assumed 60 seconds. So to remain compatible with
|
||||
// those implementations, a token must live at least this long.
|
||||
const minimumTokenLifetimeSeconds = 60
|
||||
|
||||
// Private interface for time used by this package to enable tests to provide their own implementation.
|
||||
type clock interface {
|
||||
Now() time.Time
|
||||
}
|
||||
|
||||
type tokenHandler struct {
|
||||
header http.Header
|
||||
creds CredentialStore
|
||||
scope tokenScope
|
||||
transport http.RoundTripper
|
||||
clock clock
|
||||
|
||||
tokenLock sync.Mutex
|
||||
tokenCache string
|
||||
@@ -108,12 +122,24 @@ func (ts tokenScope) String() string {
|
||||
return fmt.Sprintf("%s:%s:%s", ts.Resource, ts.Scope, strings.Join(ts.Actions, ","))
|
||||
}
|
||||
|
||||
// An implementation of clock for providing real time data.
|
||||
type realClock struct{}
|
||||
|
||||
// Now implements clock
|
||||
func (realClock) Now() time.Time { return time.Now() }
|
||||
|
||||
// NewTokenHandler creates a new AuthenicationHandler which supports
|
||||
// fetching tokens from a remote token server.
|
||||
func NewTokenHandler(transport http.RoundTripper, creds CredentialStore, scope string, actions ...string) AuthenticationHandler {
|
||||
return newTokenHandler(transport, creds, realClock{}, scope, actions...)
|
||||
}
|
||||
|
||||
// newTokenHandler exposes the option to provide a clock to manipulate time in unit testing.
|
||||
func newTokenHandler(transport http.RoundTripper, creds CredentialStore, c clock, scope string, actions ...string) AuthenticationHandler {
|
||||
return &tokenHandler{
|
||||
transport: transport,
|
||||
creds: creds,
|
||||
clock: c,
|
||||
scope: tokenScope{
|
||||
Resource: "repository",
|
||||
Scope: scope,
|
||||
@@ -146,40 +172,43 @@ func (th *tokenHandler) AuthorizeRequest(req *http.Request, params map[string]st
|
||||
func (th *tokenHandler) refreshToken(params map[string]string) error {
|
||||
th.tokenLock.Lock()
|
||||
defer th.tokenLock.Unlock()
|
||||
now := time.Now()
|
||||
now := th.clock.Now()
|
||||
if now.After(th.tokenExpiration) {
|
||||
token, err := th.fetchToken(params)
|
||||
tr, err := th.fetchToken(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
th.tokenCache = token
|
||||
th.tokenExpiration = now.Add(time.Minute)
|
||||
th.tokenCache = tr.Token
|
||||
th.tokenExpiration = tr.IssuedAt.Add(time.Duration(tr.ExpiresIn) * time.Second)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type tokenResponse struct {
|
||||
Token string `json:"token"`
|
||||
Token string `json:"token"`
|
||||
AccessToken string `json:"access_token"`
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
IssuedAt time.Time `json:"issued_at"`
|
||||
}
|
||||
|
||||
func (th *tokenHandler) fetchToken(params map[string]string) (token string, err error) {
|
||||
func (th *tokenHandler) fetchToken(params map[string]string) (token *tokenResponse, err error) {
|
||||
//log.Debugf("Getting bearer token with %s for %s", challenge.Parameters, ta.auth.Username)
|
||||
realm, ok := params["realm"]
|
||||
if !ok {
|
||||
return "", errors.New("no realm specified for token auth challenge")
|
||||
return nil, errors.New("no realm specified for token auth challenge")
|
||||
}
|
||||
|
||||
// TODO(dmcgowan): Handle empty scheme
|
||||
|
||||
realmURL, err := url.Parse(realm)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid token auth challenge realm: %s", err)
|
||||
return nil, fmt.Errorf("invalid token auth challenge realm: %s", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("GET", realmURL.String(), nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reqParams := req.URL.Query()
|
||||
@@ -206,26 +235,44 @@ func (th *tokenHandler) fetchToken(params map[string]string) (token string, err
|
||||
|
||||
resp, err := th.client().Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if !client.SuccessStatus(resp.StatusCode) {
|
||||
return "", fmt.Errorf("token auth attempt for registry: %s request failed with status: %d %s", req.URL, resp.StatusCode, http.StatusText(resp.StatusCode))
|
||||
return nil, fmt.Errorf("token auth attempt for registry: %s request failed with status: %d %s", req.URL, resp.StatusCode, http.StatusText(resp.StatusCode))
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(resp.Body)
|
||||
|
||||
tr := new(tokenResponse)
|
||||
if err = decoder.Decode(tr); err != nil {
|
||||
return "", fmt.Errorf("unable to decode token response: %s", err)
|
||||
return nil, fmt.Errorf("unable to decode token response: %s", err)
|
||||
}
|
||||
|
||||
// `access_token` is equivalent to `token` and if both are specified
|
||||
// the choice is undefined. Canonicalize `access_token` by sticking
|
||||
// things in `token`.
|
||||
if tr.AccessToken != "" {
|
||||
tr.Token = tr.AccessToken
|
||||
}
|
||||
|
||||
if tr.Token == "" {
|
||||
return "", errors.New("authorization server did not include a token in the response")
|
||||
return nil, errors.New("authorization server did not include a token in the response")
|
||||
}
|
||||
|
||||
return tr.Token, nil
|
||||
if tr.ExpiresIn < minimumTokenLifetimeSeconds {
|
||||
logrus.Debugf("Increasing token expiration to: %d seconds", tr.ExpiresIn)
|
||||
// The default/minimum lifetime.
|
||||
tr.ExpiresIn = minimumTokenLifetimeSeconds
|
||||
}
|
||||
|
||||
if tr.IssuedAt.IsZero() {
|
||||
// issued_at is optional in the token response.
|
||||
tr.IssuedAt = th.clock.Now()
|
||||
}
|
||||
|
||||
return tr, nil
|
||||
}
|
||||
|
||||
type basicHandler struct {
|
||||
|
Reference in New Issue
Block a user