build(deps): bump github.com/openshift-online/ocm-sdk-go
Bumps [github.com/openshift-online/ocm-sdk-go](https://github.com/openshift-online/ocm-sdk-go) from 0.1.204 to 0.1.208. - [Release notes](https://github.com/openshift-online/ocm-sdk-go/releases) - [Changelog](https://github.com/openshift-online/ocm-sdk-go/blob/master/CHANGES.adoc) - [Commits](https://github.com/openshift-online/ocm-sdk-go/compare/v0.1.204...v0.1.208) --- updated-dependencies: - dependency-name: github.com/openshift-online/ocm-sdk-go dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
parent
aa08e29243
commit
ebe3567aeb
9 changed files with 207 additions and 149 deletions
65
vendor/github.com/openshift-online/ocm-sdk-go/authentication/handler.go
generated
vendored
65
vendor/github.com/openshift-online/ocm-sdk-go/authentication/handler.go
generated
vendored
|
|
@ -505,7 +505,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
// Add the token to the context:
|
||||
ctx = ContextWithToken(ctx, token)
|
||||
ctx = ContextWithToken(ctx, token.object)
|
||||
r = r.WithContext(ctx)
|
||||
|
||||
// Call the next handler:
|
||||
|
|
@ -728,18 +728,22 @@ func (h *Handler) parseKey(data keyData) (key interface{}, err error) {
|
|||
// checkToken checks if the token is valid. If it is valid it returns the parsed token, the
|
||||
// claims and true. If it isn't valid it sends an error response to the client and returns false.
|
||||
func (h *Handler) checkToken(w http.ResponseWriter, r *http.Request,
|
||||
bearer string) (token *jwt.Token, claims jwt.MapClaims, ok bool) {
|
||||
bearer string) (token *tokenInfo, claims jwt.MapClaims, ok bool) {
|
||||
// Get the context:
|
||||
ctx := r.Context()
|
||||
|
||||
// Parse the token:
|
||||
claims = jwt.MapClaims{}
|
||||
token, err := h.tokenParser.ParseWithClaims(
|
||||
object, err := h.tokenParser.ParseWithClaims(
|
||||
bearer, claims,
|
||||
func(token *jwt.Token) (key interface{}, err error) {
|
||||
return h.selectKey(ctx, token)
|
||||
},
|
||||
)
|
||||
token = &tokenInfo{
|
||||
text: bearer,
|
||||
object: object,
|
||||
}
|
||||
if err != nil {
|
||||
switch typed := err.(type) {
|
||||
case *jwt.ValidationError:
|
||||
|
|
@ -828,18 +832,26 @@ func (h *Handler) checkToken(w http.ResponseWriter, r *http.Request,
|
|||
// something is wrong it sends an error response to the client and returns false.
|
||||
func (h *Handler) checkClaims(w http.ResponseWriter, r *http.Request,
|
||||
claims jwt.MapClaims) bool {
|
||||
// Check the token type:
|
||||
typ, ok := h.checkStringClaim(w, r, claims, "typ")
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if !strings.EqualFold(typ, "Bearer") {
|
||||
h.sendError(
|
||||
w, r,
|
||||
"Bearer token type '%s' isn't supported",
|
||||
typ,
|
||||
)
|
||||
return false
|
||||
// The `typ` claim is optional, but if it exists the value must be `Bearer`:
|
||||
value, ok := claims["typ"]
|
||||
if ok {
|
||||
typ, ok := value.(string)
|
||||
if !ok {
|
||||
h.sendError(
|
||||
w, r,
|
||||
"Bearer token type claim contains incorrect string value '%v'",
|
||||
value,
|
||||
)
|
||||
return false
|
||||
}
|
||||
if !strings.EqualFold(typ, "Bearer") {
|
||||
h.sendError(
|
||||
w, r,
|
||||
"Bearer token type '%s' isn't allowed",
|
||||
typ,
|
||||
)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Check the format of the issue and expiration date claims:
|
||||
|
|
@ -853,7 +865,7 @@ func (h *Handler) checkClaims(w http.ResponseWriter, r *http.Request,
|
|||
}
|
||||
|
||||
// Make sure that the impersonation flag claim doesn't exist, or is `false`:
|
||||
value, ok := claims["impersonated"]
|
||||
value, ok = claims["impersonated"]
|
||||
if ok {
|
||||
flag, ok := value.(bool)
|
||||
if !ok {
|
||||
|
|
@ -897,27 +909,6 @@ func (h *Handler) checkTimeClaim(w http.ResponseWriter, r *http.Request,
|
|||
return
|
||||
}
|
||||
|
||||
// checkStringClaim checks that the given claim exists and that the value is a string. If it doesn't
|
||||
// exist or it has a wrong type it sends an error response to the client and returns false. If it
|
||||
// exists it returns its value and true.
|
||||
func (h *Handler) checkStringClaim(w http.ResponseWriter, r *http.Request,
|
||||
claims jwt.MapClaims, name string) (result string, ok bool) {
|
||||
value, ok := h.checkClaim(w, r, claims, name)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
result, ok = value.(string)
|
||||
if !ok {
|
||||
h.sendError(
|
||||
w, r,
|
||||
"Bearer token claim '%s' contains incorrect text value '%v'",
|
||||
name, value,
|
||||
)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// checkClaim checks that the given claim exists. If it doesn't exist it sends an error response to
|
||||
// the client and returns false. If it exists it returns its value and true.
|
||||
func (h *Handler) checkClaim(w http.ResponseWriter, r *http.Request, claims jwt.MapClaims,
|
||||
|
|
|
|||
17
vendor/github.com/openshift-online/ocm-sdk-go/authentication/helpers.go
generated
vendored
17
vendor/github.com/openshift-online/ocm-sdk-go/authentication/helpers.go
generated
vendored
|
|
@ -25,15 +25,22 @@ import (
|
|||
"github.com/golang-jwt/jwt"
|
||||
)
|
||||
|
||||
// tokenRemaining determines if the given token will eventually expire (offile access tokens, for
|
||||
// example, never expire) and the time till it expires. That time will be positive if the token
|
||||
// isn't expired, and negative if the token has already expired.
|
||||
// tokenRemaining determines if the given token will eventually expire (offile access tokens and
|
||||
// opaque tokens, for example, never expire) and the time till it expires. That time will be
|
||||
// positive if the token isn't expired, and negative if the token has already expired.
|
||||
//
|
||||
// For tokens that don't have the `exp` claim, or that have it with value zero (typical for offline
|
||||
// access tokens) the result will always be `false` and zero.
|
||||
func tokenRemaining(token *jwt.Token, now time.Time) (expires bool, duration time.Duration,
|
||||
func tokenRemaining(token *tokenInfo, now time.Time) (expires bool, duration time.Duration,
|
||||
err error) {
|
||||
claims, ok := token.Claims.(jwt.MapClaims)
|
||||
// For opaque tokens we can't use the claims to determine when they expire, so we will
|
||||
// assume that they never expire.
|
||||
if token == nil || token.object == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// For JSON web tokens we use tthe `exp` claim to determine when they expire.
|
||||
claims, ok := token.object.Claims.(jwt.MapClaims)
|
||||
if !ok {
|
||||
err = fmt.Errorf("expected map claims but got %T", claims)
|
||||
return
|
||||
|
|
|
|||
27
vendor/github.com/openshift-online/ocm-sdk-go/authentication/token_info.go
generated
vendored
Normal file
27
vendor/github.com/openshift-online/ocm-sdk-go/authentication/token_info.go
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
Copyright (c) 2021 Red Hat, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package authentication
|
||||
|
||||
import "github.com/golang-jwt/jwt"
|
||||
|
||||
// tokenInfo stores information about a token. We need to store both the original text and the
|
||||
// parsed objects because some tokens (refresh tokens in particular) may be opaque strings instead
|
||||
// of JSON web tokens.
|
||||
type tokenInfo struct {
|
||||
text string
|
||||
object *jwt.Token
|
||||
}
|
||||
156
vendor/github.com/openshift-online/ocm-sdk-go/authentication/transport_wrapper.go
generated
vendored
156
vendor/github.com/openshift-online/ocm-sdk-go/authentication/transport_wrapper.go
generated
vendored
|
|
@ -92,8 +92,8 @@ type TransportWrapper struct {
|
|||
tokenServer *internal.ServerAddress
|
||||
tokenMutex *sync.Mutex
|
||||
tokenParser *jwt.Parser
|
||||
accessToken *jwt.Token
|
||||
refreshToken *jwt.Token
|
||||
accessToken *tokenInfo
|
||||
refreshToken *tokenInfo
|
||||
|
||||
// Fields used for metrics:
|
||||
metricsSubsystem string
|
||||
|
|
@ -337,39 +337,82 @@ func (b *TransportWrapperBuilder) Build(ctx context.Context) (result *TransportW
|
|||
return
|
||||
}
|
||||
|
||||
// Create the token parser:
|
||||
tokenParser := &jwt.Parser{}
|
||||
|
||||
// Parse the tokens:
|
||||
tokenParser := new(jwt.Parser)
|
||||
var accessToken *jwt.Token
|
||||
var refreshToken *jwt.Token
|
||||
var accessToken *tokenInfo
|
||||
var refreshToken *tokenInfo
|
||||
for i, text := range b.tokens {
|
||||
var token *jwt.Token
|
||||
token, _, err = tokenParser.ParseUnverified(text, jwt.MapClaims{})
|
||||
var object *jwt.Token
|
||||
object, _, err = tokenParser.ParseUnverified(text, jwt.MapClaims{})
|
||||
if err != nil {
|
||||
err = fmt.Errorf("can't parse token %d: %w", i, err)
|
||||
return
|
||||
b.logger.Debug(
|
||||
ctx,
|
||||
"Can't parse token %d, will assume that it is an opaque "+
|
||||
"refresh token: %v",
|
||||
i, err,
|
||||
)
|
||||
refreshToken = &tokenInfo{
|
||||
text: text,
|
||||
}
|
||||
continue
|
||||
}
|
||||
claims, ok := token.Claims.(jwt.MapClaims)
|
||||
claims, ok := object.Claims.(jwt.MapClaims)
|
||||
if !ok {
|
||||
err = fmt.Errorf("claims of token %d are of type '%T'", i, claims)
|
||||
return
|
||||
}
|
||||
claim, ok := claims["typ"]
|
||||
if !ok {
|
||||
err = fmt.Errorf("token %d doesn't contain the 'typ' claim", i)
|
||||
return
|
||||
// When the token doesn't have the `typ` claim we will use the position to
|
||||
// decide: first token should be the access token and second should be the
|
||||
// refresh token. That is consistent with the signature of the method that
|
||||
// returns the tokens.
|
||||
switch i {
|
||||
case 0:
|
||||
b.logger.Debug(
|
||||
ctx,
|
||||
"First token doesn't have a 'typ' claim, will assume "+
|
||||
"that it is an access token",
|
||||
)
|
||||
accessToken = &tokenInfo{
|
||||
text: text,
|
||||
object: object,
|
||||
}
|
||||
continue
|
||||
case 1:
|
||||
b.logger.Debug(
|
||||
ctx,
|
||||
"Second token doesn't have a 'typ' claim, will assume "+
|
||||
"that it is a refresh token",
|
||||
)
|
||||
refreshToken = &tokenInfo{
|
||||
text: text,
|
||||
object: object,
|
||||
}
|
||||
continue
|
||||
default:
|
||||
err = fmt.Errorf("token %d doesn't contain the 'typ' claim", i)
|
||||
return
|
||||
}
|
||||
}
|
||||
typ, ok := claim.(string)
|
||||
if !ok {
|
||||
err = fmt.Errorf("claim 'type' of token %d is of type '%T'", i, claim)
|
||||
return
|
||||
}
|
||||
switch {
|
||||
case strings.EqualFold(typ, "Bearer"):
|
||||
accessToken = token
|
||||
case strings.EqualFold(typ, "Refresh"):
|
||||
refreshToken = token
|
||||
case strings.EqualFold(typ, "Offline"):
|
||||
refreshToken = token
|
||||
switch strings.ToLower(typ) {
|
||||
case "bearer":
|
||||
accessToken = &tokenInfo{
|
||||
text: text,
|
||||
object: object,
|
||||
}
|
||||
case "refresh", "offline":
|
||||
refreshToken = &tokenInfo{
|
||||
text: text,
|
||||
object: object,
|
||||
}
|
||||
default:
|
||||
err = fmt.Errorf("type '%s' of token %d is unknown", typ, i)
|
||||
return
|
||||
|
|
@ -650,9 +693,9 @@ func (w *TransportWrapper) tokens(ctx context.Context, attempt int,
|
|||
// Check the expiration times of the tokens:
|
||||
now := time.Now()
|
||||
var accessExpires bool
|
||||
var accessReamining time.Duration
|
||||
var accessRemaining time.Duration
|
||||
if w.accessToken != nil {
|
||||
accessExpires, accessReamining, err = tokenRemaining(w.accessToken, now)
|
||||
accessExpires, accessRemaining, err = tokenRemaining(w.accessToken, now)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -666,13 +709,13 @@ func (w *TransportWrapper) tokens(ctx context.Context, attempt int,
|
|||
}
|
||||
}
|
||||
if w.logger.DebugEnabled() {
|
||||
w.debugExpiry(ctx, "Bearer", w.accessToken, accessExpires, accessReamining)
|
||||
w.debugExpiry(ctx, "Bearer", w.accessToken, accessExpires, accessRemaining)
|
||||
w.debugExpiry(ctx, "Refresh", w.refreshToken, refreshExpires, refreshRemaining)
|
||||
}
|
||||
|
||||
// If the access token is available and it isn't expired or about to expire then we can
|
||||
// return the current tokens directly:
|
||||
if w.accessToken != nil && (!accessExpires || accessReamining >= minRemaining) {
|
||||
if w.accessToken != nil && (!accessExpires || accessRemaining >= minRemaining) {
|
||||
access, refresh = w.currentTokens()
|
||||
return
|
||||
}
|
||||
|
|
@ -739,12 +782,12 @@ func (w *TransportWrapper) tokens(ctx context.Context, attempt int,
|
|||
// that the refresh token is unavailable or completely expired. And we know that we don't
|
||||
// have credentials to request new tokens. But we can still use the access token if it isn't
|
||||
// expired.
|
||||
if w.accessToken != nil && accessReamining > 0 {
|
||||
if w.accessToken != nil && accessRemaining > 0 {
|
||||
w.logger.Warn(
|
||||
ctx,
|
||||
"Access token expires in only %s, but there is no other mechanism to "+
|
||||
"obtain a new token, so will try to use it anyhow",
|
||||
accessReamining,
|
||||
accessRemaining,
|
||||
)
|
||||
access, refresh = w.currentTokens()
|
||||
return
|
||||
|
|
@ -764,10 +807,10 @@ func (w *TransportWrapper) tokens(ctx context.Context, attempt int,
|
|||
// strings.
|
||||
func (w *TransportWrapper) currentTokens() (access, refresh string) {
|
||||
if w.accessToken != nil {
|
||||
access = w.accessToken.Raw
|
||||
access = w.accessToken.text
|
||||
}
|
||||
if w.refreshToken != nil {
|
||||
refresh = w.refreshToken.Raw
|
||||
refresh = w.refreshToken.text
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
@ -801,7 +844,7 @@ func (w *TransportWrapper) sendRefreshForm(ctx context.Context, attempt int) (co
|
|||
form := url.Values{}
|
||||
form.Set(grantTypeField, refreshTokenGrant)
|
||||
form.Set(clientIDField, w.clientID)
|
||||
form.Set(refreshTokenField, w.refreshToken.Raw)
|
||||
form.Set(refreshTokenField, w.refreshToken.text)
|
||||
code, result, err = w.sendForm(ctx, form, attempt)
|
||||
return
|
||||
}
|
||||
|
|
@ -901,37 +944,64 @@ func (w *TransportWrapper) sendFormTimed(ctx context.Context, form url.Values) (
|
|||
err = fmt.Errorf("token response status code is '%d'", response.StatusCode)
|
||||
return
|
||||
}
|
||||
if result.TokenType != nil && *result.TokenType != "bearer" {
|
||||
err = fmt.Errorf("expected 'bearer' token type but got '%s", *result.TokenType)
|
||||
if result.TokenType != nil && !strings.EqualFold(*result.TokenType, "bearer") {
|
||||
err = fmt.Errorf("expected 'bearer' token type but got '%s'", *result.TokenType)
|
||||
return
|
||||
}
|
||||
|
||||
// The response should always contains the access token, regardless of the kind of grant
|
||||
// that was used:
|
||||
var accessToken *jwt.Token
|
||||
var accessTokenText string
|
||||
var accessTokenObject *jwt.Token
|
||||
var accessToken *tokenInfo
|
||||
if result.AccessToken == nil {
|
||||
err = fmt.Errorf("no access token was received")
|
||||
return
|
||||
}
|
||||
accessToken, _, err = w.tokenParser.ParseUnverified(*result.AccessToken, jwt.MapClaims{})
|
||||
accessTokenText = *result.AccessToken
|
||||
accessTokenObject, _, err = w.tokenParser.ParseUnverified(
|
||||
accessTokenText,
|
||||
jwt.MapClaims{},
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if accessTokenText != "" {
|
||||
accessToken = &tokenInfo{
|
||||
text: accessTokenText,
|
||||
object: accessTokenObject,
|
||||
}
|
||||
}
|
||||
|
||||
// The refresh token isn't mandatory for the client credentials grant:
|
||||
var refreshToken *jwt.Token
|
||||
// The refresh token isn't mandatory for the password and client credentials grants:
|
||||
var refreshTokenText string
|
||||
var refreshTokenObject *jwt.Token
|
||||
var refreshToken *tokenInfo
|
||||
if result.RefreshToken == nil {
|
||||
if form.Get(grantTypeField) != clientCredentialsGrant {
|
||||
grantType := form.Get(grantTypeField)
|
||||
if grantType != passwordGrant && grantType != clientCredentialsGrant {
|
||||
err = fmt.Errorf("no refresh token was received")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
refreshToken, _, err = w.tokenParser.ParseUnverified(
|
||||
*result.RefreshToken,
|
||||
refreshTokenText = *result.RefreshToken
|
||||
refreshTokenObject, _, err = w.tokenParser.ParseUnverified(
|
||||
refreshTokenText,
|
||||
jwt.MapClaims{},
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
w.logger.Debug(
|
||||
ctx,
|
||||
"Refresh token can't be parsed, will assume it is opaque: %v",
|
||||
err,
|
||||
)
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
if refreshTokenText != "" {
|
||||
refreshToken = &tokenInfo{
|
||||
text: refreshTokenText,
|
||||
object: refreshTokenObject,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -946,12 +1016,6 @@ func (w *TransportWrapper) sendFormTimed(ctx context.Context, form url.Values) (
|
|||
return
|
||||
}
|
||||
|
||||
// haveCredentials returns true if the connection has credentials that can be used to request new
|
||||
// tokens.
|
||||
func (w *TransportWrapper) haveCredentials() bool {
|
||||
return w.havePassword() || w.haveSecret()
|
||||
}
|
||||
|
||||
func (w *TransportWrapper) havePassword() bool {
|
||||
return w.user != "" && w.password != ""
|
||||
}
|
||||
|
|
@ -961,8 +1025,8 @@ func (w *TransportWrapper) haveSecret() bool {
|
|||
}
|
||||
|
||||
// debugExpiry sends to the log information about the expiration of the given token.
|
||||
func (w *TransportWrapper) debugExpiry(ctx context.Context, typ string, token *jwt.Token, expires bool,
|
||||
left time.Duration) {
|
||||
func (w *TransportWrapper) debugExpiry(ctx context.Context, typ string, token *tokenInfo,
|
||||
expires bool, left time.Duration) {
|
||||
if token != nil {
|
||||
if expires {
|
||||
if left < 0 {
|
||||
|
|
|
|||
2
vendor/github.com/openshift-online/ocm-sdk-go/internal/client_selector.go
generated
vendored
2
vendor/github.com/openshift-online/ocm-sdk-go/internal/client_selector.go
generated
vendored
|
|
@ -349,7 +349,7 @@ func (s *ClientSelector) createTransport(ctx context.Context,
|
|||
dialer := net.Dialer{}
|
||||
return dialer.DialContext(ctx, UnixNetwork, address.Socket)
|
||||
}
|
||||
transport.DialTLS = func(_, _ string) (net.Conn, error) {
|
||||
transport.DialTLS = func(_, _ string) (net.Conn, error) { // nolint
|
||||
// TODO: This ignores the passed context because it isn't currently
|
||||
// supported. Once we migrate to Go 1.15 it should be done like
|
||||
// this:
|
||||
|
|
|
|||
10
vendor/github.com/openshift-online/ocm-sdk-go/logging/go_logger.go
generated
vendored
10
vendor/github.com/openshift-online/ocm-sdk-go/logging/go_logger.go
generated
vendored
|
|
@ -120,7 +120,7 @@ func (l *GoLogger) Debug(ctx context.Context, format string, args ...interface{}
|
|||
if l.debugEnabled {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
// #nosec G104
|
||||
log.Output(1, msg)
|
||||
_ = log.Output(1, msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ func (l *GoLogger) Info(ctx context.Context, format string, args ...interface{})
|
|||
if l.infoEnabled {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
// #nosec G104
|
||||
log.Output(1, msg)
|
||||
_ = log.Output(1, msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -140,7 +140,7 @@ func (l *GoLogger) Warn(ctx context.Context, format string, args ...interface{})
|
|||
if l.warnEnabled {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
// #nosec G104
|
||||
log.Output(1, msg)
|
||||
_ = log.Output(1, msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -150,7 +150,7 @@ func (l *GoLogger) Error(ctx context.Context, format string, args ...interface{}
|
|||
if l.errorEnabled {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
// #nosec G104
|
||||
log.Output(1, msg)
|
||||
_ = log.Output(1, msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -160,6 +160,6 @@ func (l *GoLogger) Error(ctx context.Context, format string, args ...interface{}
|
|||
func (l *GoLogger) Fatal(ctx context.Context, format string, args ...interface{}) {
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
// #nosec G104
|
||||
log.Output(1, msg)
|
||||
_ = log.Output(1, msg)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue