Signed-off-by: Derek McGowan <derek@mcgstyle.net>
| ... | ... |
@@ -38,56 +38,70 @@ type ConfigFile struct {
|
| 38 | 38 |
} |
| 39 | 39 |
|
| 40 | 40 |
type RequestAuthorization struct {
|
| 41 |
- Token string |
|
| 42 |
- Username string |
|
| 43 |
- Password string |
|
| 41 |
+ authConfig *AuthConfig |
|
| 42 |
+ registryEndpoint *Endpoint |
|
| 43 |
+ resource string |
|
| 44 |
+ scope string |
|
| 45 |
+ actions []string |
|
| 44 | 46 |
} |
| 45 | 47 |
|
| 46 |
-func NewRequestAuthorization(authConfig *AuthConfig, registryEndpoint *Endpoint, resource, scope string, actions []string) (*RequestAuthorization, error) {
|
|
| 47 |
- var auth RequestAuthorization |
|
| 48 |
+func NewRequestAuthorization(authConfig *AuthConfig, registryEndpoint *Endpoint, resource, scope string, actions []string) *RequestAuthorization {
|
|
| 49 |
+ return &RequestAuthorization{
|
|
| 50 |
+ authConfig: authConfig, |
|
| 51 |
+ registryEndpoint: registryEndpoint, |
|
| 52 |
+ resource: resource, |
|
| 53 |
+ scope: scope, |
|
| 54 |
+ actions: actions, |
|
| 55 |
+ } |
|
| 56 |
+} |
|
| 48 | 57 |
|
| 58 |
+func (auth *RequestAuthorization) getToken() (string, error) {
|
|
| 59 |
+ // TODO check if already has token and before expiration |
|
| 49 | 60 |
client := &http.Client{
|
| 50 | 61 |
Transport: &http.Transport{
|
| 51 | 62 |
DisableKeepAlives: true, |
| 52 |
- Proxy: http.ProxyFromEnvironment, |
|
| 53 |
- }, |
|
| 63 |
+ Proxy: http.ProxyFromEnvironment}, |
|
| 54 | 64 |
CheckRedirect: AddRequiredHeadersToRedirectedRequests, |
| 55 | 65 |
} |
| 56 | 66 |
factory := HTTPRequestFactory(nil) |
| 57 | 67 |
|
| 58 |
- for _, challenge := range registryEndpoint.AuthChallenges {
|
|
| 59 |
- log.Debugf("Using %q auth challenge with params %s for %s", challenge.Scheme, challenge.Parameters, authConfig.Username)
|
|
| 60 |
- |
|
| 68 |
+ for _, challenge := range auth.registryEndpoint.AuthChallenges {
|
|
| 61 | 69 |
switch strings.ToLower(challenge.Scheme) {
|
| 62 | 70 |
case "basic": |
| 63 |
- auth.Username = authConfig.Username |
|
| 64 |
- auth.Password = authConfig.Password |
|
| 71 |
+ // no token necessary |
|
| 65 | 72 |
case "bearer": |
| 73 |
+ log.Debugf("Getting bearer token with %s for %s", challenge.Parameters, auth.authConfig.Username)
|
|
| 66 | 74 |
params := map[string]string{}
|
| 67 | 75 |
for k, v := range challenge.Parameters {
|
| 68 | 76 |
params[k] = v |
| 69 | 77 |
} |
| 70 |
- params["scope"] = fmt.Sprintf("%s:%s:%s", resource, scope, strings.Join(actions, ","))
|
|
| 71 |
- token, err := getToken(authConfig.Username, authConfig.Password, params, registryEndpoint, client, factory) |
|
| 78 |
+ params["scope"] = fmt.Sprintf("%s:%s:%s", auth.resource, auth.scope, strings.Join(auth.actions, ","))
|
|
| 79 |
+ token, err := getToken(auth.authConfig.Username, auth.authConfig.Password, params, auth.registryEndpoint, client, factory) |
|
| 72 | 80 |
if err != nil {
|
| 73 |
- return nil, err |
|
| 81 |
+ return "", err |
|
| 74 | 82 |
} |
| 83 |
+ // TODO cache token and set expiration to one minute from now |
|
| 75 | 84 |
|
| 76 |
- auth.Token = token |
|
| 85 |
+ return token, nil |
|
| 77 | 86 |
default: |
| 78 | 87 |
log.Infof("Unsupported auth scheme: %q", challenge.Scheme)
|
| 79 | 88 |
} |
| 80 | 89 |
} |
| 81 |
- |
|
| 82 |
- return &auth, nil |
|
| 90 |
+ // TODO no expiration, do not reattempt to get a token |
|
| 91 |
+ return "", nil |
|
| 83 | 92 |
} |
| 84 | 93 |
|
| 85 |
-func (auth *RequestAuthorization) Authorize(req *http.Request) {
|
|
| 86 |
- if auth.Token != "" {
|
|
| 87 |
- req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", auth.Token))
|
|
| 88 |
- } else if auth.Username != "" && auth.Password != "" {
|
|
| 89 |
- req.SetBasicAuth(auth.Username, auth.Password) |
|
| 94 |
+func (auth *RequestAuthorization) Authorize(req *http.Request) error {
|
|
| 95 |
+ token, err := auth.getToken() |
|
| 96 |
+ if err != nil {
|
|
| 97 |
+ return err |
|
| 98 |
+ } |
|
| 99 |
+ if token != "" {
|
|
| 100 |
+ req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
|
|
| 101 |
+ } else if auth.authConfig.Username != "" && auth.authConfig.Password != "" {
|
|
| 102 |
+ req.SetBasicAuth(auth.authConfig.Username, auth.authConfig.Password) |
|
| 90 | 103 |
} |
| 104 |
+ return nil |
|
| 91 | 105 |
} |
| 92 | 106 |
|
| 93 | 107 |
// create a base64 encoded auth string to store in config |
| ... | ... |
@@ -42,7 +42,7 @@ func (r *Session) GetV2Authorization(imageName string, readOnly bool) (auth *Req |
| 42 | 42 |
r.indexEndpoint = registry |
| 43 | 43 |
|
| 44 | 44 |
log.Debugf("Getting authorization for %s %s", imageName, scopes)
|
| 45 |
- return NewRequestAuthorization(r.GetAuthConfig(true), registry, "repository", imageName, scopes) |
|
| 45 |
+ return NewRequestAuthorization(r.GetAuthConfig(true), registry, "repository", imageName, scopes), nil |
|
| 46 | 46 |
} |
| 47 | 47 |
|
| 48 | 48 |
// |
| ... | ... |
@@ -65,7 +65,9 @@ func (r *Session) GetV2ImageManifest(imageName, tagName string, auth *RequestAut |
| 65 | 65 |
if err != nil {
|
| 66 | 66 |
return nil, err |
| 67 | 67 |
} |
| 68 |
- auth.Authorize(req) |
|
| 68 |
+ if err := auth.Authorize(req) {
|
|
| 69 |
+ return nil, err |
|
| 70 |
+ } |
|
| 69 | 71 |
res, _, err := r.doRequest(req) |
| 70 | 72 |
if err != nil {
|
| 71 | 73 |
return nil, err |
| ... | ... |
@@ -103,7 +105,9 @@ func (r *Session) PostV2ImageMountBlob(imageName, sumType, sum string, auth *Req |
| 103 | 103 |
if err != nil {
|
| 104 | 104 |
return false, err |
| 105 | 105 |
} |
| 106 |
- auth.Authorize(req) |
|
| 106 |
+ if err := auth.Authorize(req) {
|
|
| 107 |
+ return nil, err |
|
| 108 |
+ } |
|
| 107 | 109 |
res, _, err := r.doRequest(req) |
| 108 | 110 |
if err != nil {
|
| 109 | 111 |
return false, err |
| ... | ... |
@@ -132,7 +136,9 @@ func (r *Session) GetV2ImageBlob(imageName, sumType, sum string, blobWrtr io.Wri |
| 132 | 132 |
if err != nil {
|
| 133 | 133 |
return err |
| 134 | 134 |
} |
| 135 |
- auth.Authorize(req) |
|
| 135 |
+ if err := auth.Authorize(req) {
|
|
| 136 |
+ return nil, err |
|
| 137 |
+ } |
|
| 136 | 138 |
res, _, err := r.doRequest(req) |
| 137 | 139 |
if err != nil {
|
| 138 | 140 |
return err |
| ... | ... |
@@ -161,7 +167,9 @@ func (r *Session) GetV2ImageBlobReader(imageName, sumType, sum string, auth *Req |
| 161 | 161 |
if err != nil {
|
| 162 | 162 |
return nil, 0, err |
| 163 | 163 |
} |
| 164 |
- auth.Authorize(req) |
|
| 164 |
+ if err := auth.Authorize(req) {
|
|
| 165 |
+ return nil, err |
|
| 166 |
+ } |
|
| 165 | 167 |
res, _, err := r.doRequest(req) |
| 166 | 168 |
if err != nil {
|
| 167 | 169 |
return nil, 0, err |
| ... | ... |
@@ -196,7 +204,9 @@ func (r *Session) PutV2ImageBlob(imageName, sumType, sumStr string, blobRdr io.R |
| 196 | 196 |
return err |
| 197 | 197 |
} |
| 198 | 198 |
|
| 199 |
- auth.Authorize(req) |
|
| 199 |
+ if err := auth.Authorize(req) {
|
|
| 200 |
+ return nil, err |
|
| 201 |
+ } |
|
| 200 | 202 |
res, _, err := r.doRequest(req) |
| 201 | 203 |
if err != nil {
|
| 202 | 204 |
return err |
| ... | ... |
@@ -212,7 +222,9 @@ func (r *Session) PutV2ImageBlob(imageName, sumType, sumStr string, blobRdr io.R |
| 212 | 212 |
queryParams := url.Values{}
|
| 213 | 213 |
queryParams.Add("digest", sumType+":"+sumStr)
|
| 214 | 214 |
req.URL.RawQuery = queryParams.Encode() |
| 215 |
- auth.Authorize(req) |
|
| 215 |
+ if err := auth.Authorize(req) {
|
|
| 216 |
+ return nil, err |
|
| 217 |
+ } |
|
| 216 | 218 |
res, _, err = r.doRequest(req) |
| 217 | 219 |
if err != nil {
|
| 218 | 220 |
return err |
| ... | ... |
@@ -242,7 +254,9 @@ func (r *Session) PutV2ImageManifest(imageName, tagName string, manifestRdr io.R |
| 242 | 242 |
if err != nil {
|
| 243 | 243 |
return err |
| 244 | 244 |
} |
| 245 |
- auth.Authorize(req) |
|
| 245 |
+ if err := auth.Authorize(req) {
|
|
| 246 |
+ return nil, err |
|
| 247 |
+ } |
|
| 246 | 248 |
res, _, err := r.doRequest(req) |
| 247 | 249 |
if err != nil {
|
| 248 | 250 |
return err |
| ... | ... |
@@ -274,7 +288,9 @@ func (r *Session) GetV2RemoteTags(imageName string, auth *RequestAuthorization) |
| 274 | 274 |
if err != nil {
|
| 275 | 275 |
return nil, err |
| 276 | 276 |
} |
| 277 |
- auth.Authorize(req) |
|
| 277 |
+ if err := auth.Authorize(req) {
|
|
| 278 |
+ return nil, err |
|
| 279 |
+ } |
|
| 278 | 280 |
res, _, err := r.doRequest(req) |
| 279 | 281 |
if err != nil {
|
| 280 | 282 |
return nil, err |