github.com/Aoi-hosizora/ahlib-more@v1.5.1-0.20230404072844-256112befaf6/xjwt/xjwt_test.go (about)

     1  package xjwt
     2  
     3  import (
     4  	"errors"
     5  	"github.com/Aoi-hosizora/ahlib/xtesting"
     6  	"github.com/golang-jwt/jwt/v4"
     7  	"testing"
     8  	"time"
     9  )
    10  
    11  func TestGenerateToken(t *testing.T) {
    12  	for _, tc := range []struct {
    13  		giveMethod jwt.SigningMethod
    14  		wantSecret interface{}
    15  		wantError  bool
    16  	}{
    17  		{jwt.SigningMethodNone, []byte{}, true},
    18  		{jwt.SigningMethodHS256, []byte{}, false},
    19  		{jwt.SigningMethodHS384, []byte{}, false},
    20  		{jwt.SigningMethodHS512, []byte{}, false},
    21  		{jwt.SigningMethodES256, []byte{}, true},
    22  		{jwt.SigningMethodES384, []byte{}, true},
    23  		{jwt.SigningMethodES512, []byte{}, true},
    24  	} {
    25  		_, err := GenerateToken(tc.giveMethod, &jwt.RegisteredClaims{}, tc.wantSecret)
    26  		if tc.wantError {
    27  			xtesting.NotNil(t, err)
    28  		} else {
    29  			xtesting.Nil(t, err)
    30  		}
    31  	}
    32  
    33  	for _, tc := range []struct {
    34  		giveFn     func(jwt.Claims, []byte) (string, error)
    35  		giveSecret []byte
    36  		wantError  bool
    37  	}{
    38  		{GenerateTokenWithHS256, []byte{}, false},
    39  		{GenerateTokenWithHS256, []byte{'#'}, false},
    40  		{GenerateTokenWithHS384, []byte{}, false},
    41  		{GenerateTokenWithHS384, []byte{'#'}, false},
    42  		{GenerateTokenWithHS512, []byte{}, false},
    43  		{GenerateTokenWithHS512, []byte{'#'}, false},
    44  	} {
    45  		token, err := tc.giveFn(&jwt.RegisteredClaims{}, tc.giveSecret)
    46  		if tc.wantError {
    47  			xtesting.NotNil(t, err)
    48  		} else {
    49  			xtesting.Nil(t, err)
    50  			xtesting.NotBlankString(t, token)
    51  		}
    52  	}
    53  }
    54  
    55  func TestParseToken(t *testing.T) {
    56  	secret := []byte("A!B@C#D$E%F^G&")
    57  	type userClaims struct {
    58  		Uid      uint64
    59  		Username string
    60  		jwt.RegisteredClaims
    61  	}
    62  	uid := uint64(20)
    63  	username := "test user"
    64  	now := time.Now()
    65  
    66  	claims := &userClaims{
    67  		Uid:      uid,
    68  		Username: username,
    69  		RegisteredClaims: jwt.RegisteredClaims{
    70  			Issuer:    username,
    71  			IssuedAt:  jwt.NewNumericDate(now),
    72  			NotBefore: jwt.NewNumericDate(now.Add(time.Second)),
    73  			ExpiresAt: jwt.NewNumericDate(now.Add(2 * time.Second)),
    74  		},
    75  	}
    76  	// | now | +1s | +2s | +3s |
    77  	// |-----|-----------|-----|
    78  	//   NBF       OK      EXP
    79  	token, err := GenerateTokenWithHS256(claims, secret)
    80  	xtesting.Nil(t, err)
    81  
    82  	// 1. NBF
    83  	_, err = ParseToken(token, secret, &userClaims{})
    84  	xtesting.NotNil(t, err)
    85  	xtesting.True(t, IsNotValidYetError(err))
    86  
    87  	_, err = ParseTokenClaims(token, secret, &userClaims{})
    88  	xtesting.NotNil(t, err)
    89  	xtesting.True(t, IsNotValidYetError(err))
    90  
    91  	// 2. Valid
    92  	time.Sleep(time.Second)
    93  	parsedToken, err := ParseToken(token, secret, &userClaims{})
    94  	xtesting.Nil(t, err)
    95  	xtesting.Equal(t, parsedToken.Claims.(*userClaims).Uid, uid)
    96  	xtesting.Equal(t, parsedToken.Claims.(*userClaims).Username, username)
    97  	xtesting.Equal(t, parsedToken.Claims.(*userClaims).Issuer, username)
    98  	xtesting.Equal(t, parsedToken.Claims.(*userClaims).IssuedAt.Unix(), now.Unix())
    99  
   100  	parsedClaims, err := ParseTokenClaims(token, secret, &userClaims{})
   101  	xtesting.Nil(t, err)
   102  	xtesting.Equal(t, parsedClaims.(*userClaims).Uid, uid)
   103  	xtesting.Equal(t, parsedClaims.(*userClaims).Username, username)
   104  	xtesting.Equal(t, parsedClaims.(*userClaims).Issuer, username)
   105  	xtesting.Equal(t, parsedClaims.(*userClaims).IssuedAt.Unix(), now.Unix())
   106  
   107  	// 3. EXP
   108  	time.Sleep(2 * time.Second)
   109  	_, err = ParseToken(token, secret, &userClaims{})
   110  	xtesting.NotNil(t, err)
   111  	xtesting.True(t, IsExpiredError(err))
   112  
   113  	_, err = ParseTokenClaims(token, secret, &userClaims{})
   114  	xtesting.NotNil(t, err)
   115  	xtesting.True(t, IsExpiredError(err))
   116  }
   117  
   118  func TestValidationError(t *testing.T) {
   119  	for _, tc := range []struct {
   120  		giveFn  func(error) bool
   121  		giveErr error
   122  		want    bool
   123  	}{
   124  		{IsAudienceError, nil, false},
   125  		{IsAudienceError, errors.New(""), false},
   126  		{IsAudienceError, jwt.NewValidationError("", jwt.ValidationErrorMalformed), false},
   127  		{IsAudienceError, jwt.NewValidationError("", jwt.ValidationErrorAudience), true},
   128  		{IsAudienceError, jwt.NewValidationError("", jwt.ValidationErrorAudience|jwt.ValidationErrorMalformed), true},
   129  
   130  		{IsExpiredError, nil, false},
   131  		{IsExpiredError, errors.New(""), false},
   132  		{IsExpiredError, jwt.NewValidationError("", jwt.ValidationErrorMalformed), false},
   133  		{IsExpiredError, jwt.NewValidationError("", jwt.ValidationErrorExpired), true},
   134  		{IsExpiredError, jwt.NewValidationError("", jwt.ValidationErrorExpired|jwt.ValidationErrorMalformed), true},
   135  
   136  		{IsIdError, nil, false},
   137  		{IsIdError, errors.New(""), false},
   138  		{IsIdError, jwt.NewValidationError("", jwt.ValidationErrorMalformed), false},
   139  		{IsIdError, jwt.NewValidationError("", jwt.ValidationErrorId), true},
   140  		{IsIdError, jwt.NewValidationError("", jwt.ValidationErrorId|jwt.ValidationErrorMalformed), true},
   141  
   142  		{IsIssuedAtError, nil, false},
   143  		{IsIssuedAtError, errors.New(""), false},
   144  		{IsIssuedAtError, jwt.NewValidationError("", jwt.ValidationErrorMalformed), false},
   145  		{IsIssuedAtError, jwt.NewValidationError("", jwt.ValidationErrorIssuedAt), true},
   146  		{IsIssuedAtError, jwt.NewValidationError("", jwt.ValidationErrorIssuedAt|jwt.ValidationErrorMalformed), true},
   147  
   148  		{IsIssuerError, nil, false},
   149  		{IsIssuerError, errors.New(""), false},
   150  		{IsIssuerError, jwt.NewValidationError("", jwt.ValidationErrorMalformed), false},
   151  		{IsIssuerError, jwt.NewValidationError("", jwt.ValidationErrorIssuer), true},
   152  		{IsIssuerError, jwt.NewValidationError("", jwt.ValidationErrorIssuer|jwt.ValidationErrorMalformed), true},
   153  
   154  		{IsNotValidYetError, nil, false},
   155  		{IsNotValidYetError, errors.New(""), false},
   156  		{IsNotValidYetError, jwt.NewValidationError("", jwt.ValidationErrorMalformed), false},
   157  		{IsNotValidYetError, jwt.NewValidationError("", jwt.ValidationErrorNotValidYet), true},
   158  		{IsNotValidYetError, jwt.NewValidationError("", jwt.ValidationErrorNotValidYet|jwt.ValidationErrorMalformed), true},
   159  
   160  		{IsTokenInvalidError, nil, false},
   161  		{IsTokenInvalidError, errors.New(""), false},
   162  		{IsTokenInvalidError, jwt.NewValidationError("", jwt.ValidationErrorClaimsInvalid), false},
   163  		{IsTokenInvalidError, jwt.NewValidationError("", jwt.ValidationErrorMalformed), true},
   164  		{IsTokenInvalidError, jwt.NewValidationError("", jwt.ValidationErrorUnverifiable), true},
   165  		{IsTokenInvalidError, jwt.NewValidationError("", jwt.ValidationErrorSignatureInvalid), true},
   166  		{IsTokenInvalidError, jwt.NewValidationError("", jwt.ValidationErrorMalformed|jwt.ValidationErrorClaimsInvalid), true},
   167  
   168  		{IsClaimsInvalidError, nil, false},
   169  		{IsClaimsInvalidError, errors.New(""), false},
   170  		{IsClaimsInvalidError, jwt.NewValidationError("", jwt.ValidationErrorMalformed), false},
   171  		{IsClaimsInvalidError, jwt.NewValidationError("", jwt.ValidationErrorClaimsInvalid), true},
   172  		{IsClaimsInvalidError, jwt.NewValidationError("", jwt.ValidationErrorClaimsInvalid|jwt.ValidationErrorMalformed), true},
   173  	} {
   174  		xtesting.Equal(t, tc.giveFn(tc.giveErr), tc.want)
   175  	}
   176  }