github.com/openshift-online/ocm-sdk-go@v0.1.473/testing/tokens.go (about)

     1  /*
     2  Copyright (c) 2019 Red Hat, Inc.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8    http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package testing
    18  
    19  import (
    20  	"crypto/rand"
    21  	"crypto/rsa"
    22  	"encoding/base64"
    23  	"fmt"
    24  	"math/big"
    25  	"net/http"
    26  	"time"
    27  
    28  	"github.com/golang-jwt/jwt/v4"
    29  
    30  	. "github.com/onsi/gomega" // nolint
    31  )
    32  
    33  // MakeTokenObject generates a token with the claims resulting from merging the default claims and
    34  // the claims explicitly given.
    35  func MakeTokenObject(claims jwt.MapClaims) *jwt.Token {
    36  	merged := jwt.MapClaims{}
    37  	for name, value := range MakeClaims() {
    38  		merged[name] = value
    39  	}
    40  	for name, value := range claims {
    41  		if value == nil {
    42  			delete(merged, name)
    43  		} else {
    44  			merged[name] = value
    45  		}
    46  	}
    47  	token := jwt.NewWithClaims(jwt.SigningMethodRS256, merged)
    48  	token.Header["kid"] = "123"
    49  	var err error
    50  	token.Raw, err = token.SignedString(jwtPrivateKey)
    51  	Expect(err).ToNot(HaveOccurred())
    52  	return token
    53  }
    54  
    55  // MakeClaims generates a default set of claims to be used to issue a token.
    56  func MakeClaims() jwt.MapClaims {
    57  	iat := time.Now()
    58  	exp := iat.Add(1 * time.Minute)
    59  	return jwt.MapClaims{
    60  		"iss": "https://sso.redhat.com/auth/realms/redhat-external",
    61  		"iat": iat.Unix(),
    62  		"typ": "Bearer",
    63  		"exp": exp.Unix(),
    64  	}
    65  }
    66  
    67  // MakeTokenString generates a token issued by the default OpenID server and with the given type and
    68  // with the given life. If the life is zero the token will never expire. If the life is positive the
    69  // token will be valid, and expire after that time. If the life is negative the token will be
    70  // already expired that time ago.
    71  func MakeTokenString(typ string, life time.Duration) string {
    72  	claims := jwt.MapClaims{}
    73  	claims["typ"] = typ
    74  	if life != 0 {
    75  		claims["exp"] = time.Now().Add(life).Unix()
    76  	}
    77  	token := MakeTokenObject(claims)
    78  	return token.Raw
    79  }
    80  
    81  func RespondWithAccessAndRefreshTokens(accessToken, refreshToken string) http.HandlerFunc {
    82  	return RespondWithJSONTemplate(
    83  		http.StatusOK,
    84  		`{
    85  			"access_token": "{{ .AccessToken }}",
    86  			"refresh_token": "{{ .RefreshToken }}"
    87  		}`,
    88  		"AccessToken", accessToken,
    89  		"RefreshToken", refreshToken,
    90  	)
    91  }
    92  
    93  func RespondWithAccessToken(accessToken string) http.HandlerFunc {
    94  	return RespondWithJSONTemplate(
    95  		http.StatusOK,
    96  		`{
    97  			"access_token": "{{ .AccessToken }}"
    98  		}`,
    99  		"AccessToken", accessToken,
   100  	)
   101  }
   102  
   103  func RespondWithTokenError(err, description string) http.HandlerFunc {
   104  	return RespondWithJSONTemplate(
   105  		http.StatusUnauthorized,
   106  		`{
   107  			"error": "{{ .Error }}",
   108  			"error_description": "{{ .Description }}"
   109  		}`,
   110  		"Error", err,
   111  		"Description", description,
   112  	)
   113  }
   114  
   115  // DefaultJWKS generates the JSON web key set used for tests.
   116  func DefaultJWKS() []byte {
   117  	// Create a temporary file containing the JSON web key set:
   118  	bigE := big.NewInt(int64(jwtPublicKey.E))
   119  	bigN := jwtPublicKey.N
   120  	return []byte(fmt.Sprintf(
   121  		`{
   122  			"keys": [{
   123  				"kid": "123",
   124  				"kty": "RSA",
   125  				"alg": "RS256",
   126  				"e": "%s",
   127  				"n": "%s"
   128  			}]
   129  		}`,
   130  		base64.RawURLEncoding.EncodeToString(bigE.Bytes()),
   131  		base64.RawURLEncoding.EncodeToString(bigN.Bytes()),
   132  	))
   133  }
   134  
   135  // Public and private key that will be used to sign and verify tokens in the tests:
   136  var (
   137  	jwtPublicKey  *rsa.PublicKey
   138  	jwtPrivateKey *rsa.PrivateKey
   139  )
   140  
   141  func init() {
   142  	var err error
   143  
   144  	// Generate the keys used to sign and verify tokens:
   145  	jwtPrivateKey, err = rsa.GenerateKey(rand.Reader, 4096)
   146  	if err != nil {
   147  		panic(err)
   148  	}
   149  	jwtPublicKey = &jwtPrivateKey.PublicKey
   150  }