@@ -141,7 +141,8 @@ const (
141
141
noAuth
142
142
)
143
143
144
- func newBearerTokenFromJSONBlob (blob []byte ) (* bearerToken , error ) {
144
+ // readFromJSONBlob sets token data in dest from the provided JSON.
145
+ func (bt * bearerToken ) readFromJSONBlob (blob []byte ) error {
145
146
var token struct {
146
147
Token string `json:"token"`
147
148
AccessToken string `json:"access_token"`
@@ -150,14 +151,12 @@ func newBearerTokenFromJSONBlob(blob []byte) (*bearerToken, error) {
150
151
expirationTime time.Time
151
152
}
152
153
if err := json .Unmarshal (blob , & token ); err != nil {
153
- return nil , err
154
+ return err
154
155
}
155
156
156
- res := & bearerToken {
157
- token : token .Token ,
158
- }
159
- if res .token == "" {
160
- res .token = token .AccessToken
157
+ bt .token = token .Token
158
+ if bt .token == "" {
159
+ bt .token = token .AccessToken
161
160
}
162
161
163
162
if token .ExpiresIn < minimumTokenLifetimeSeconds {
@@ -167,8 +166,8 @@ func newBearerTokenFromJSONBlob(blob []byte) (*bearerToken, error) {
167
166
if token .IssuedAt .IsZero () {
168
167
token .IssuedAt = time .Now ().UTC ()
169
168
}
170
- res .expirationTime = token .IssuedAt .Add (time .Duration (token .ExpiresIn ) * time .Second )
171
- return res , nil
169
+ bt .expirationTime = token .IssuedAt .Add (time .Duration (token .ExpiresIn ) * time .Second )
170
+ return nil
172
171
}
173
172
174
173
// this is cloned from docker/go-connections because upstream docker has changed
@@ -712,20 +711,18 @@ func (c *dockerClient) obtainBearerToken(ctx context.Context, challenge challeng
712
711
token , inCache = c .tokenCache [cacheKey ]
713
712
}()
714
713
if ! inCache || time .Now ().After (token .expirationTime ) {
715
- var (
716
- t * bearerToken
717
- err error
718
- )
714
+ token = & bearerToken {}
715
+
716
+ var err error
719
717
if c .auth .IdentityToken != "" {
720
- t , err = c .getBearerTokenOAuth2 (ctx , challenge , scopes )
718
+ err = c .getBearerTokenOAuth2 (ctx , token , challenge , scopes )
721
719
} else {
722
- t , err = c .getBearerToken (ctx , challenge , scopes )
720
+ err = c .getBearerToken (ctx , token , challenge , scopes )
723
721
}
724
722
if err != nil {
725
723
return "" , err
726
724
}
727
725
728
- token = t
729
726
func () { // A scope for defer
730
727
c .tokenCacheLock .Lock ()
731
728
defer c .tokenCacheLock .Unlock ()
@@ -735,16 +732,19 @@ func (c *dockerClient) obtainBearerToken(ctx context.Context, challenge challeng
735
732
return token .token , nil
736
733
}
737
734
738
- func (c * dockerClient ) getBearerTokenOAuth2 (ctx context.Context , challenge challenge ,
739
- scopes []authScope ) (* bearerToken , error ) {
735
+ // getBearerTokenOAuth2 obtains an "Authorization: Bearer" token using a pre-existing identity token per
736
+ // https://github.com/distribution/distribution/blob/main/docs/spec/auth/oauth.md for challenge and scopes,
737
+ // and writes it into dest.
738
+ func (c * dockerClient ) getBearerTokenOAuth2 (ctx context.Context , dest * bearerToken , challenge challenge ,
739
+ scopes []authScope ) error {
740
740
realm , ok := challenge .Parameters ["realm" ]
741
741
if ! ok {
742
- return nil , errors .New ("missing realm in bearer auth challenge" )
742
+ return errors .New ("missing realm in bearer auth challenge" )
743
743
}
744
744
745
745
authReq , err := http .NewRequestWithContext (ctx , http .MethodPost , realm , nil )
746
746
if err != nil {
747
- return nil , err
747
+ return err
748
748
}
749
749
750
750
// Make the form data required against the oauth2 authentication
@@ -769,31 +769,34 @@ func (c *dockerClient) getBearerTokenOAuth2(ctx context.Context, challenge chall
769
769
logrus .Debugf ("%s %s" , authReq .Method , authReq .URL .Redacted ())
770
770
res , err := c .client .Do (authReq )
771
771
if err != nil {
772
- return nil , err
772
+ return err
773
773
}
774
774
defer res .Body .Close ()
775
775
if err := httpResponseToError (res , "Trying to obtain access token" ); err != nil {
776
- return nil , err
776
+ return err
777
777
}
778
778
779
779
tokenBlob , err := iolimits .ReadAtMost (res .Body , iolimits .MaxAuthTokenBodySize )
780
780
if err != nil {
781
- return nil , err
781
+ return err
782
782
}
783
783
784
- return newBearerTokenFromJSONBlob (tokenBlob )
784
+ return dest . readFromJSONBlob (tokenBlob )
785
785
}
786
786
787
- func (c * dockerClient ) getBearerToken (ctx context.Context , challenge challenge ,
788
- scopes []authScope ) (* bearerToken , error ) {
787
+ // getBearerToken obtains an "Authorization: Bearer" token using a GET request, per
788
+ // https://github.com/distribution/distribution/blob/main/docs/spec/auth/token.md for challenge and scopes,
789
+ // and writes it into dest.
790
+ func (c * dockerClient ) getBearerToken (ctx context.Context , dest * bearerToken , challenge challenge ,
791
+ scopes []authScope ) error {
789
792
realm , ok := challenge .Parameters ["realm" ]
790
793
if ! ok {
791
- return nil , errors .New ("missing realm in bearer auth challenge" )
794
+ return errors .New ("missing realm in bearer auth challenge" )
792
795
}
793
796
794
797
authReq , err := http .NewRequestWithContext (ctx , http .MethodGet , realm , nil )
795
798
if err != nil {
796
- return nil , err
799
+ return err
797
800
}
798
801
799
802
params := authReq .URL .Query ()
@@ -821,18 +824,18 @@ func (c *dockerClient) getBearerToken(ctx context.Context, challenge challenge,
821
824
logrus .Debugf ("%s %s" , authReq .Method , authReq .URL .Redacted ())
822
825
res , err := c .client .Do (authReq )
823
826
if err != nil {
824
- return nil , err
827
+ return err
825
828
}
826
829
defer res .Body .Close ()
827
830
if err := httpResponseToError (res , "Requesting bearer token" ); err != nil {
828
- return nil , err
831
+ return err
829
832
}
830
833
tokenBlob , err := iolimits .ReadAtMost (res .Body , iolimits .MaxAuthTokenBodySize )
831
834
if err != nil {
832
- return nil , err
835
+ return err
833
836
}
834
837
835
- return newBearerTokenFromJSONBlob (tokenBlob )
838
+ return dest . readFromJSONBlob (tokenBlob )
836
839
}
837
840
838
841
// detectPropertiesHelper performs the work of detectProperties which executes
0 commit comments