github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/appengine/login/googlesignin/jwt-go/jwt_test.go (about)

     1  package jwt_test
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/dgrijalva/jwt-go"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"reflect"
     9  	"testing"
    10  	"time"
    11  )
    12  
    13  var (
    14  	jwtTestDefaultKey []byte
    15  	defaultKeyFunc    jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return jwtTestDefaultKey, nil }
    16  	emptyKeyFunc      jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return nil, nil }
    17  	errorKeyFunc      jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return nil, fmt.Errorf("error loading key") }
    18  	nilKeyFunc        jwt.Keyfunc = nil
    19  )
    20  
    21  var jwtTestData = []struct {
    22  	name        string
    23  	tokenString string
    24  	keyfunc     jwt.Keyfunc
    25  	claims      map[string]interface{}
    26  	valid       bool
    27  	errors      uint32
    28  }{
    29  	{
    30  		"basic",
    31  		"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
    32  		defaultKeyFunc,
    33  		map[string]interface{}{"foo": "bar"},
    34  		true,
    35  		0,
    36  	},
    37  	{
    38  		"basic expired",
    39  		"", // autogen
    40  		defaultKeyFunc,
    41  		map[string]interface{}{"foo": "bar", "exp": float64(time.Now().Unix() - 100)},
    42  		false,
    43  		jwt.ValidationErrorExpired,
    44  	},
    45  	{
    46  		"basic nbf",
    47  		"", // autogen
    48  		defaultKeyFunc,
    49  		map[string]interface{}{"foo": "bar", "nbf": float64(time.Now().Unix() + 100)},
    50  		false,
    51  		jwt.ValidationErrorNotValidYet,
    52  	},
    53  	{
    54  		"expired and nbf",
    55  		"", // autogen
    56  		defaultKeyFunc,
    57  		map[string]interface{}{"foo": "bar", "nbf": float64(time.Now().Unix() + 100), "exp": float64(time.Now().Unix() - 100)},
    58  		false,
    59  		jwt.ValidationErrorNotValidYet | jwt.ValidationErrorExpired,
    60  	},
    61  	{
    62  		"basic invalid",
    63  		"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.EhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
    64  		defaultKeyFunc,
    65  		map[string]interface{}{"foo": "bar"},
    66  		false,
    67  		jwt.ValidationErrorSignatureInvalid,
    68  	},
    69  	{
    70  		"basic nokeyfunc",
    71  		"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
    72  		nilKeyFunc,
    73  		map[string]interface{}{"foo": "bar"},
    74  		false,
    75  		jwt.ValidationErrorUnverifiable,
    76  	},
    77  	{
    78  		"basic nokey",
    79  		"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
    80  		emptyKeyFunc,
    81  		map[string]interface{}{"foo": "bar"},
    82  		false,
    83  		jwt.ValidationErrorSignatureInvalid,
    84  	},
    85  	{
    86  		"basic errorkey",
    87  		"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
    88  		errorKeyFunc,
    89  		map[string]interface{}{"foo": "bar"},
    90  		false,
    91  		jwt.ValidationErrorUnverifiable,
    92  	},
    93  }
    94  
    95  func init() {
    96  	var e error
    97  	if jwtTestDefaultKey, e = ioutil.ReadFile("test/sample_key.pub"); e != nil {
    98  		panic(e)
    99  	}
   100  }
   101  
   102  func makeSample(c map[string]interface{}) string {
   103  	key, e := ioutil.ReadFile("test/sample_key")
   104  	if e != nil {
   105  		panic(e.Error())
   106  	}
   107  
   108  	token := jwt.New(jwt.SigningMethodRS256)
   109  	token.Claims = c
   110  	s, e := token.SignedString(key)
   111  
   112  	if e != nil {
   113  		panic(e.Error())
   114  	}
   115  
   116  	return s
   117  }
   118  
   119  func TestJWT(t *testing.T) {
   120  	for _, data := range jwtTestData {
   121  		if data.tokenString == "" {
   122  			data.tokenString = makeSample(data.claims)
   123  		}
   124  		token, err := jwt.Parse(data.tokenString, data.keyfunc)
   125  
   126  		if !reflect.DeepEqual(data.claims, token.Claims) {
   127  			t.Errorf("[%v] Claims mismatch. Expecting: %v  Got: %v", data.name, data.claims, token.Claims)
   128  		}
   129  		if data.valid && err != nil {
   130  			t.Errorf("[%v] Error while verifying token: %T:%v", data.name, err, err)
   131  		}
   132  		if !data.valid && err == nil {
   133  			t.Errorf("[%v] Invalid token passed validation", data.name)
   134  		}
   135  		if data.errors != 0 {
   136  			if err == nil {
   137  				t.Errorf("[%v] Expecting error.  Didn't get one.", data.name)
   138  			} else {
   139  				// compare the bitfield part of the error
   140  				if err.(*jwt.ValidationError).Errors != data.errors {
   141  					t.Errorf("[%v] Errors don't match expectation", data.name)
   142  				}
   143  
   144  			}
   145  		}
   146  	}
   147  }
   148  
   149  func TestParseRequest(t *testing.T) {
   150  	// Bearer token request
   151  	for _, data := range jwtTestData {
   152  		if data.tokenString == "" {
   153  			data.tokenString = makeSample(data.claims)
   154  		}
   155  
   156  		r, _ := http.NewRequest("GET", "/", nil)
   157  		r.Header.Set("Authorization", fmt.Sprintf("Bearer %v", data.tokenString))
   158  		token, err := jwt.ParseFromRequest(r, data.keyfunc)
   159  
   160  		if token == nil {
   161  			t.Errorf("[%v] Token was not found: %v", data.name, err)
   162  			continue
   163  		}
   164  		if !reflect.DeepEqual(data.claims, token.Claims) {
   165  			t.Errorf("[%v] Claims mismatch. Expecting: %v  Got: %v", data.name, data.claims, token.Claims)
   166  		}
   167  		if data.valid && err != nil {
   168  			t.Errorf("[%v] Error while verifying token: %v", data.name, err)
   169  		}
   170  		if !data.valid && err == nil {
   171  			t.Errorf("[%v] Invalid token passed validation", data.name)
   172  		}
   173  	}
   174  }
   175  
   176  // Helper method for benchmarking various methods
   177  func benchmarkSigning(b *testing.B, method jwt.SigningMethod, key interface{}) {
   178  	t := jwt.New(method)
   179  	b.RunParallel(func(pb *testing.PB) {
   180  		for pb.Next() {
   181  			if _, err := t.SignedString(key); err != nil {
   182  				b.Fatal(err)
   183  			}
   184  		}
   185  	})
   186  
   187  }