storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/jwt/parser_test.go (about)

     1  /*
     2   * MinIO Cloud Storage, (C) 2020 MinIO, 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 jwt
    18  
    19  // This file is a re-implementation of the original code here with some
    20  // additional allocation tweaks reproduced using GODEBUG=allocfreetrace=1
    21  // original file https://github.com/dgrijalva/jwt-go/blob/master/parser.go
    22  // borrowed under MIT License https://github.com/dgrijalva/jwt-go/blob/master/LICENSE
    23  
    24  import (
    25  	"fmt"
    26  	"testing"
    27  	"time"
    28  
    29  	"github.com/dgrijalva/jwt-go"
    30  )
    31  
    32  var (
    33  	defaultKeyFunc = func(claim *MapClaims) ([]byte, error) { return []byte("HelloSecret"), nil }
    34  	emptyKeyFunc   = func(claim *MapClaims) ([]byte, error) { return nil, nil }
    35  	errorKeyFunc   = func(claim *MapClaims) ([]byte, error) { return nil, fmt.Errorf("error loading key") }
    36  )
    37  
    38  var jwtTestData = []struct {
    39  	name        string
    40  	tokenString string
    41  	keyfunc     func(*MapClaims) ([]byte, error)
    42  	claims      jwt.Claims
    43  	valid       bool
    44  	errors      int32
    45  }{
    46  	{
    47  		"basic",
    48  		"",
    49  		defaultKeyFunc,
    50  		&MapClaims{
    51  			MapClaims: jwt.MapClaims{
    52  				"foo": "bar",
    53  			},
    54  		},
    55  		true,
    56  		0,
    57  	},
    58  	{
    59  		"basic expired",
    60  		"", // autogen
    61  		defaultKeyFunc,
    62  		&MapClaims{
    63  			MapClaims: jwt.MapClaims{
    64  				"foo": "bar",
    65  				"exp": float64(time.Now().Unix() - 100),
    66  			},
    67  		},
    68  		false,
    69  		-1,
    70  	},
    71  	{
    72  		"basic nbf",
    73  		"", // autogen
    74  		defaultKeyFunc,
    75  		&MapClaims{
    76  			MapClaims: jwt.MapClaims{
    77  				"foo": "bar",
    78  				"nbf": float64(time.Now().Unix() + 100),
    79  			},
    80  		},
    81  		false,
    82  		-1,
    83  	},
    84  	{
    85  		"expired and nbf",
    86  		"", // autogen
    87  		defaultKeyFunc,
    88  		&MapClaims{
    89  			MapClaims: jwt.MapClaims{
    90  				"foo": "bar",
    91  				"nbf": float64(time.Now().Unix() + 100),
    92  				"exp": float64(time.Now().Unix() - 100),
    93  			},
    94  		},
    95  		false,
    96  		-1,
    97  	},
    98  	{
    99  		"basic invalid",
   100  		"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.EhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
   101  		defaultKeyFunc,
   102  		&MapClaims{
   103  			MapClaims: jwt.MapClaims{
   104  				"foo": "bar",
   105  			},
   106  		},
   107  		false,
   108  		-1,
   109  	},
   110  	{
   111  		"basic nokeyfunc",
   112  		"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
   113  		nil,
   114  		&MapClaims{
   115  			MapClaims: jwt.MapClaims{
   116  				"foo": "bar",
   117  			},
   118  		},
   119  		false,
   120  		-1,
   121  	},
   122  	{
   123  		"basic nokey",
   124  		"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
   125  		emptyKeyFunc,
   126  		&MapClaims{
   127  			MapClaims: jwt.MapClaims{
   128  				"foo": "bar",
   129  			},
   130  		},
   131  		false,
   132  		-1,
   133  	},
   134  	{
   135  		"basic errorkey",
   136  		"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
   137  		errorKeyFunc,
   138  		&MapClaims{
   139  			MapClaims: jwt.MapClaims{
   140  				"foo": "bar",
   141  			},
   142  		},
   143  		false,
   144  		-1,
   145  	},
   146  	{
   147  		"Standard Claims",
   148  		"",
   149  		defaultKeyFunc,
   150  		&StandardClaims{
   151  			StandardClaims: jwt.StandardClaims{
   152  				ExpiresAt: time.Now().Add(time.Second * 10).Unix(),
   153  			},
   154  		},
   155  		true,
   156  		0,
   157  	},
   158  }
   159  
   160  func mapClaimsToken(claims *MapClaims) string {
   161  	claims.SetAccessKey("test")
   162  	j := jwt.NewWithClaims(jwt.SigningMethodHS512, claims)
   163  	tk, _ := j.SignedString([]byte("HelloSecret"))
   164  	return tk
   165  }
   166  
   167  func standardClaimsToken(claims *StandardClaims) string {
   168  	claims.AccessKey = "test"
   169  	claims.Subject = "test"
   170  	j := jwt.NewWithClaims(jwt.SigningMethodHS512, claims)
   171  	tk, _ := j.SignedString([]byte("HelloSecret"))
   172  	return tk
   173  }
   174  
   175  func TestParserParse(t *testing.T) {
   176  	// Iterate over test data set and run tests
   177  	for _, data := range jwtTestData {
   178  		data := data
   179  		t.Run(data.name, func(t *testing.T) {
   180  			// Parse the token
   181  			var err error
   182  
   183  			// Figure out correct claims type
   184  			switch claims := data.claims.(type) {
   185  			case *MapClaims:
   186  				if data.tokenString == "" {
   187  					data.tokenString = mapClaimsToken(claims)
   188  				}
   189  				err = ParseWithClaims(data.tokenString, &MapClaims{}, data.keyfunc)
   190  			case *StandardClaims:
   191  				if data.tokenString == "" {
   192  					data.tokenString = standardClaimsToken(claims)
   193  				}
   194  				err = ParseWithStandardClaims(data.tokenString, &StandardClaims{}, []byte("HelloSecret"))
   195  			}
   196  
   197  			if data.valid && err != nil {
   198  				t.Errorf("Error while verifying token: %T:%v", err, err)
   199  			}
   200  
   201  			if !data.valid && err == nil {
   202  				t.Errorf("Invalid token passed validation")
   203  			}
   204  
   205  			if data.errors != 0 {
   206  				_, ok := err.(*jwt.ValidationError)
   207  				if !ok {
   208  					t.Errorf("Expected *jwt.ValidationError, but got %#v instead", err)
   209  				}
   210  			}
   211  		})
   212  	}
   213  }