xref: /aosp_15_r20/external/tink/go/jwt/verified_jwt_test.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1*e7b1675dSTing-Kang Chang// Copyright 2022 Google LLC
2*e7b1675dSTing-Kang Chang//
3*e7b1675dSTing-Kang Chang// Licensed under the Apache License, Version 2.0 (the "License");
4*e7b1675dSTing-Kang Chang// you may not use this file except in compliance with the License.
5*e7b1675dSTing-Kang Chang// You may obtain a copy of the License at
6*e7b1675dSTing-Kang Chang//
7*e7b1675dSTing-Kang Chang//      http://www.apache.org/licenses/LICENSE-2.0
8*e7b1675dSTing-Kang Chang//
9*e7b1675dSTing-Kang Chang// Unless required by applicable law or agreed to in writing, software
10*e7b1675dSTing-Kang Chang// distributed under the License is distributed on an "AS IS" BASIS,
11*e7b1675dSTing-Kang Chang// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*e7b1675dSTing-Kang Chang// See the License for the specific language governing permissions and
13*e7b1675dSTing-Kang Chang// limitations under the License.
14*e7b1675dSTing-Kang Chang//
15*e7b1675dSTing-Kang Chang////////////////////////////////////////////////////////////////////////////////
16*e7b1675dSTing-Kang Chang
17*e7b1675dSTing-Kang Changpackage jwt_test
18*e7b1675dSTing-Kang Chang
19*e7b1675dSTing-Kang Changimport (
20*e7b1675dSTing-Kang Chang	"testing"
21*e7b1675dSTing-Kang Chang	"time"
22*e7b1675dSTing-Kang Chang
23*e7b1675dSTing-Kang Chang	"github.com/google/go-cmp/cmp"
24*e7b1675dSTing-Kang Chang	"github.com/google/go-cmp/cmp/cmpopts"
25*e7b1675dSTing-Kang Chang	"github.com/google/tink/go/jwt"
26*e7b1675dSTing-Kang Chang	"github.com/google/tink/go/keyset"
27*e7b1675dSTing-Kang Chang)
28*e7b1675dSTing-Kang Chang
29*e7b1675dSTing-Kang Changfunc createVerifiedJWT(rawJWT *jwt.RawJWT) (*jwt.VerifiedJWT, error) {
30*e7b1675dSTing-Kang Chang	kh, err := keyset.NewHandle(jwt.HS256Template())
31*e7b1675dSTing-Kang Chang	if err != nil {
32*e7b1675dSTing-Kang Chang		return nil, err
33*e7b1675dSTing-Kang Chang	}
34*e7b1675dSTing-Kang Chang	m, err := jwt.NewMAC(kh)
35*e7b1675dSTing-Kang Chang	if err != nil {
36*e7b1675dSTing-Kang Chang		return nil, err
37*e7b1675dSTing-Kang Chang	}
38*e7b1675dSTing-Kang Chang	compact, err := m.ComputeMACAndEncode(rawJWT)
39*e7b1675dSTing-Kang Chang	if err != nil {
40*e7b1675dSTing-Kang Chang		return nil, err
41*e7b1675dSTing-Kang Chang	}
42*e7b1675dSTing-Kang Chang	// This validator is purposely instantiated to always pass.
43*e7b1675dSTing-Kang Chang	// It isn't really validating much and probably shouldn't
44*e7b1675dSTing-Kang Chang	// be used like this out side of these tests.
45*e7b1675dSTing-Kang Chang	opts := &jwt.ValidatorOpts{
46*e7b1675dSTing-Kang Chang		AllowMissingExpiration: true,
47*e7b1675dSTing-Kang Chang		IgnoreTypeHeader:       true,
48*e7b1675dSTing-Kang Chang		IgnoreAudiences:        true,
49*e7b1675dSTing-Kang Chang		IgnoreIssuer:           true,
50*e7b1675dSTing-Kang Chang	}
51*e7b1675dSTing-Kang Chang	issuedAt, err := rawJWT.IssuedAt()
52*e7b1675dSTing-Kang Chang	if err == nil {
53*e7b1675dSTing-Kang Chang		opts.FixedNow = issuedAt
54*e7b1675dSTing-Kang Chang	}
55*e7b1675dSTing-Kang Chang
56*e7b1675dSTing-Kang Chang	validator, err := jwt.NewValidator(opts)
57*e7b1675dSTing-Kang Chang	if err != nil {
58*e7b1675dSTing-Kang Chang		return nil, err
59*e7b1675dSTing-Kang Chang	}
60*e7b1675dSTing-Kang Chang	return m.VerifyMACAndDecode(compact, validator)
61*e7b1675dSTing-Kang Chang}
62*e7b1675dSTing-Kang Chang
63*e7b1675dSTing-Kang Changfunc TestGetRegisteredStringClaims(t *testing.T) {
64*e7b1675dSTing-Kang Chang	opts := &jwt.RawJWTOptions{
65*e7b1675dSTing-Kang Chang		TypeHeader:        refString("typeHeader"),
66*e7b1675dSTing-Kang Chang		Subject:           refString("test-subject"),
67*e7b1675dSTing-Kang Chang		Issuer:            refString("test-issuer"),
68*e7b1675dSTing-Kang Chang		JWTID:             refString("1"),
69*e7b1675dSTing-Kang Chang		WithoutExpiration: true,
70*e7b1675dSTing-Kang Chang	}
71*e7b1675dSTing-Kang Chang	rawJWT, err := jwt.NewRawJWT(opts)
72*e7b1675dSTing-Kang Chang	if err != nil {
73*e7b1675dSTing-Kang Chang		t.Fatalf("jwt.NewRawJWT(%v): %v", opts, err)
74*e7b1675dSTing-Kang Chang	}
75*e7b1675dSTing-Kang Chang	verifiedJWT, err := createVerifiedJWT(rawJWT)
76*e7b1675dSTing-Kang Chang	if err != nil {
77*e7b1675dSTing-Kang Chang		t.Fatalf("creating verifiedJWT: %v", err)
78*e7b1675dSTing-Kang Chang	}
79*e7b1675dSTing-Kang Chang	if !verifiedJWT.HasTypeHeader() {
80*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasTypeHeader() = false, want true")
81*e7b1675dSTing-Kang Chang	}
82*e7b1675dSTing-Kang Chang	if !verifiedJWT.HasSubject() {
83*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasSubject() = false, want true")
84*e7b1675dSTing-Kang Chang	}
85*e7b1675dSTing-Kang Chang	if !verifiedJWT.HasIssuer() {
86*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasIssuer() = false, want true")
87*e7b1675dSTing-Kang Chang	}
88*e7b1675dSTing-Kang Chang	if !verifiedJWT.HasJWTID() {
89*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasJWTID() = false, want true")
90*e7b1675dSTing-Kang Chang	}
91*e7b1675dSTing-Kang Chang	typeHeader, err := verifiedJWT.TypeHeader()
92*e7b1675dSTing-Kang Chang	if err != nil {
93*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.TypeHeader() err = %v, want nil", err)
94*e7b1675dSTing-Kang Chang	}
95*e7b1675dSTing-Kang Chang	if !cmp.Equal(typeHeader, *opts.TypeHeader) {
96*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.TypeHeader() = %q, want %q", typeHeader, *opts.TypeHeader)
97*e7b1675dSTing-Kang Chang	}
98*e7b1675dSTing-Kang Chang	subject, err := verifiedJWT.Subject()
99*e7b1675dSTing-Kang Chang	if err != nil {
100*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.Subject() err = %v, want nil", err)
101*e7b1675dSTing-Kang Chang	}
102*e7b1675dSTing-Kang Chang	if !cmp.Equal(subject, *opts.Subject) {
103*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.Subject() = %q, want %q", subject, *opts.Subject)
104*e7b1675dSTing-Kang Chang	}
105*e7b1675dSTing-Kang Chang	issuer, err := verifiedJWT.Issuer()
106*e7b1675dSTing-Kang Chang	if err != nil {
107*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.Issuer() err = %v, want nil", err)
108*e7b1675dSTing-Kang Chang	}
109*e7b1675dSTing-Kang Chang	if !cmp.Equal(issuer, *opts.Issuer) {
110*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.Issuer() = %q, want %q", issuer, *opts.Issuer)
111*e7b1675dSTing-Kang Chang	}
112*e7b1675dSTing-Kang Chang	jwtID, err := verifiedJWT.JWTID()
113*e7b1675dSTing-Kang Chang	if err != nil {
114*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.JWTID() err = %v, want nil", err)
115*e7b1675dSTing-Kang Chang	}
116*e7b1675dSTing-Kang Chang	if !cmp.Equal(jwtID, *opts.JWTID) {
117*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.JWTID() = %q, want %q", jwtID, *opts.JWTID)
118*e7b1675dSTing-Kang Chang	}
119*e7b1675dSTing-Kang Chang	if !cmp.Equal(verifiedJWT.CustomClaimNames(), []string{}) {
120*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.CustomClaimNames() = %q want %q", verifiedJWT.CustomClaimNames(), []string{})
121*e7b1675dSTing-Kang Chang	}
122*e7b1675dSTing-Kang Chang}
123*e7b1675dSTing-Kang Chang
124*e7b1675dSTing-Kang Changfunc TestGetRegisteredTimestampClaims(t *testing.T) {
125*e7b1675dSTing-Kang Chang	now := time.Now()
126*e7b1675dSTing-Kang Chang	opts := &jwt.RawJWTOptions{
127*e7b1675dSTing-Kang Chang		ExpiresAt: refTime(now.Add(time.Hour * 24).Unix()),
128*e7b1675dSTing-Kang Chang		IssuedAt:  refTime(now.Unix()),
129*e7b1675dSTing-Kang Chang		NotBefore: refTime(now.Add(-time.Hour * 2).Unix()),
130*e7b1675dSTing-Kang Chang	}
131*e7b1675dSTing-Kang Chang	rawJWT, err := jwt.NewRawJWT(opts)
132*e7b1675dSTing-Kang Chang	if err != nil {
133*e7b1675dSTing-Kang Chang		t.Fatalf("jwt.NewRawJWT(%v): %v", opts, err)
134*e7b1675dSTing-Kang Chang	}
135*e7b1675dSTing-Kang Chang	verifiedJWT, err := createVerifiedJWT(rawJWT)
136*e7b1675dSTing-Kang Chang	if err != nil {
137*e7b1675dSTing-Kang Chang		t.Fatalf("creating verifiedJWT: %v", err)
138*e7b1675dSTing-Kang Chang	}
139*e7b1675dSTing-Kang Chang	if !verifiedJWT.HasExpiration() {
140*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasExpiration() = false, want true")
141*e7b1675dSTing-Kang Chang	}
142*e7b1675dSTing-Kang Chang	if !verifiedJWT.HasIssuedAt() {
143*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasIssuedAt() = false, want true")
144*e7b1675dSTing-Kang Chang	}
145*e7b1675dSTing-Kang Chang	if !verifiedJWT.HasNotBefore() {
146*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasNotBefore() = false, want true")
147*e7b1675dSTing-Kang Chang	}
148*e7b1675dSTing-Kang Chang	expiresAt, err := verifiedJWT.ExpiresAt()
149*e7b1675dSTing-Kang Chang	if err != nil {
150*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.ExpiresAt() err = %v, want nil", err)
151*e7b1675dSTing-Kang Chang	}
152*e7b1675dSTing-Kang Chang	if !cmp.Equal(expiresAt, *opts.ExpiresAt) {
153*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.ExpiresAt() = %q, want %q", expiresAt, *opts.ExpiresAt)
154*e7b1675dSTing-Kang Chang	}
155*e7b1675dSTing-Kang Chang	issuedAt, err := verifiedJWT.IssuedAt()
156*e7b1675dSTing-Kang Chang	if err != nil {
157*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.IssuedAt() err = %v, want nil", err)
158*e7b1675dSTing-Kang Chang	}
159*e7b1675dSTing-Kang Chang	if !cmp.Equal(issuedAt, *opts.IssuedAt) {
160*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.IssuedAt() = %q, want %q", issuedAt, *opts.IssuedAt)
161*e7b1675dSTing-Kang Chang	}
162*e7b1675dSTing-Kang Chang	notBefore, err := verifiedJWT.NotBefore()
163*e7b1675dSTing-Kang Chang	if err != nil {
164*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.NotBefore() err = %v, want nil", err)
165*e7b1675dSTing-Kang Chang	}
166*e7b1675dSTing-Kang Chang	if !cmp.Equal(notBefore, *opts.NotBefore) {
167*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.NotBefore() = %q, want %q", notBefore, *opts.NotBefore)
168*e7b1675dSTing-Kang Chang	}
169*e7b1675dSTing-Kang Chang}
170*e7b1675dSTing-Kang Chang
171*e7b1675dSTing-Kang Changfunc TestGetAudiencesClaim(t *testing.T) {
172*e7b1675dSTing-Kang Chang	opts := &jwt.RawJWTOptions{
173*e7b1675dSTing-Kang Chang		WithoutExpiration: true,
174*e7b1675dSTing-Kang Chang		Audiences:         []string{"foo", "bar"},
175*e7b1675dSTing-Kang Chang	}
176*e7b1675dSTing-Kang Chang	rawJWT, err := jwt.NewRawJWT(opts)
177*e7b1675dSTing-Kang Chang	if err != nil {
178*e7b1675dSTing-Kang Chang		t.Fatalf("jwt.NewRawJWT(%v): %v", opts, err)
179*e7b1675dSTing-Kang Chang	}
180*e7b1675dSTing-Kang Chang	verifiedJWT, err := createVerifiedJWT(rawJWT)
181*e7b1675dSTing-Kang Chang	if err != nil {
182*e7b1675dSTing-Kang Chang		t.Fatalf("creating verifiedJWT: %v", err)
183*e7b1675dSTing-Kang Chang	}
184*e7b1675dSTing-Kang Chang	if !verifiedJWT.HasAudiences() {
185*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasAudiences() = false, want true")
186*e7b1675dSTing-Kang Chang	}
187*e7b1675dSTing-Kang Chang	audiences, err := verifiedJWT.Audiences()
188*e7b1675dSTing-Kang Chang	if err != nil {
189*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.Audiences() err = %v, want nil", err)
190*e7b1675dSTing-Kang Chang	}
191*e7b1675dSTing-Kang Chang	if !cmp.Equal(audiences, opts.Audiences) {
192*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.Audiences() = %q, want %q", audiences, opts.Audiences)
193*e7b1675dSTing-Kang Chang	}
194*e7b1675dSTing-Kang Chang}
195*e7b1675dSTing-Kang Chang
196*e7b1675dSTing-Kang Changfunc TestGetCustomClaims(t *testing.T) {
197*e7b1675dSTing-Kang Chang	opts := &jwt.RawJWTOptions{
198*e7b1675dSTing-Kang Chang		WithoutExpiration: true,
199*e7b1675dSTing-Kang Chang		CustomClaims: map[string]interface{}{
200*e7b1675dSTing-Kang Chang			"cc-null":   nil,
201*e7b1675dSTing-Kang Chang			"cc-num":    1.67,
202*e7b1675dSTing-Kang Chang			"cc-bool":   true,
203*e7b1675dSTing-Kang Chang			"cc-string": "goo",
204*e7b1675dSTing-Kang Chang			"cc-array":  []interface{}{"1", "2", "3"},
205*e7b1675dSTing-Kang Chang			"cc-object": map[string]interface{}{"cc-nested-num": 5.99},
206*e7b1675dSTing-Kang Chang		},
207*e7b1675dSTing-Kang Chang	}
208*e7b1675dSTing-Kang Chang	rawJWT, err := jwt.NewRawJWT(opts)
209*e7b1675dSTing-Kang Chang	if err != nil {
210*e7b1675dSTing-Kang Chang		t.Fatalf("jwt.NewRawJWT(%v): %v", opts, err)
211*e7b1675dSTing-Kang Chang	}
212*e7b1675dSTing-Kang Chang	verifiedJWT, err := createVerifiedJWT(rawJWT)
213*e7b1675dSTing-Kang Chang	if err != nil {
214*e7b1675dSTing-Kang Chang		t.Fatalf("creating verifiedJWT: %v", err)
215*e7b1675dSTing-Kang Chang	}
216*e7b1675dSTing-Kang Chang	wantCustomClaims := []string{"cc-num", "cc-bool", "cc-null", "cc-string", "cc-array", "cc-object"}
217*e7b1675dSTing-Kang Chang	if !cmp.Equal(verifiedJWT.CustomClaimNames(), wantCustomClaims, cmpopts.SortSlices(func(a, b string) bool { return a < b })) {
218*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.CustomClaimNames() = %q, want %q", verifiedJWT.CustomClaimNames(), wantCustomClaims)
219*e7b1675dSTing-Kang Chang	}
220*e7b1675dSTing-Kang Chang	if !verifiedJWT.HasNullClaim("cc-null") {
221*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasNullClaim('cc-null') = false, want true")
222*e7b1675dSTing-Kang Chang	}
223*e7b1675dSTing-Kang Chang	if !verifiedJWT.HasNumberClaim("cc-num") {
224*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasNumberClaim('cc-num') = false, want true")
225*e7b1675dSTing-Kang Chang	}
226*e7b1675dSTing-Kang Chang	if !verifiedJWT.HasBooleanClaim("cc-bool") {
227*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasBooleanClaim('cc-bool') = false, want true")
228*e7b1675dSTing-Kang Chang	}
229*e7b1675dSTing-Kang Chang	if !verifiedJWT.HasStringClaim("cc-string") {
230*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasStringClaim('cc-string') = false, want true")
231*e7b1675dSTing-Kang Chang	}
232*e7b1675dSTing-Kang Chang	if !verifiedJWT.HasArrayClaim("cc-array") {
233*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasArrayClaim('cc-array') = false, want true")
234*e7b1675dSTing-Kang Chang	}
235*e7b1675dSTing-Kang Chang	if !verifiedJWT.HasObjectClaim("cc-object") {
236*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasObjectClaim('cc-object') = false, want true")
237*e7b1675dSTing-Kang Chang	}
238*e7b1675dSTing-Kang Chang	number, err := verifiedJWT.NumberClaim("cc-num")
239*e7b1675dSTing-Kang Chang	if err != nil {
240*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.NumberClaim('cc-num') err = %v, want nil", err)
241*e7b1675dSTing-Kang Chang	}
242*e7b1675dSTing-Kang Chang	if !cmp.Equal(number, opts.CustomClaims["cc-num"]) {
243*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.NumberClaim('cc-num') = %f, want %f", number, opts.CustomClaims["cc-num"])
244*e7b1675dSTing-Kang Chang	}
245*e7b1675dSTing-Kang Chang	boolean, err := verifiedJWT.BooleanClaim("cc-bool")
246*e7b1675dSTing-Kang Chang	if err != nil {
247*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.BooleanClaim('cc-bool') err = %v, want nil", err)
248*e7b1675dSTing-Kang Chang	}
249*e7b1675dSTing-Kang Chang	if !cmp.Equal(boolean, opts.CustomClaims["cc-bool"]) {
250*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.BooleanClaim('cc-bool') = %v, want %v", boolean, opts.CustomClaims["cc-bool"])
251*e7b1675dSTing-Kang Chang	}
252*e7b1675dSTing-Kang Chang	str, err := verifiedJWT.StringClaim("cc-string")
253*e7b1675dSTing-Kang Chang	if err != nil {
254*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.StringClaim('cc-string') err = %v, want nil", err)
255*e7b1675dSTing-Kang Chang	}
256*e7b1675dSTing-Kang Chang	if !cmp.Equal(str, opts.CustomClaims["cc-string"]) {
257*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.StringClaim('cc-string') = %q, want %q", str, opts.CustomClaims["cc-string"])
258*e7b1675dSTing-Kang Chang	}
259*e7b1675dSTing-Kang Chang	array, err := verifiedJWT.ArrayClaim("cc-array")
260*e7b1675dSTing-Kang Chang	if err != nil {
261*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.ArrayClaim('cc-array') err = %v, want nil", err)
262*e7b1675dSTing-Kang Chang	}
263*e7b1675dSTing-Kang Chang	if !cmp.Equal(array, opts.CustomClaims["cc-array"]) {
264*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.ArrayClaim('cc-array') = %q, want %q", array, opts.CustomClaims["cc-array"])
265*e7b1675dSTing-Kang Chang	}
266*e7b1675dSTing-Kang Chang	object, err := verifiedJWT.ObjectClaim("cc-object")
267*e7b1675dSTing-Kang Chang	if err != nil {
268*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.ObjectClaim('cc-object') err = %v, want nil", err)
269*e7b1675dSTing-Kang Chang	}
270*e7b1675dSTing-Kang Chang	if !cmp.Equal(object, opts.CustomClaims["cc-object"]) {
271*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.ObjectClaim('cc-object') = %q, want %q", object, opts.CustomClaims["cc-object"])
272*e7b1675dSTing-Kang Chang	}
273*e7b1675dSTing-Kang Chang}
274*e7b1675dSTing-Kang Chang
275*e7b1675dSTing-Kang Changfunc TestCustomClaimIsFalseForWrongType(t *testing.T) {
276*e7b1675dSTing-Kang Chang	opts := &jwt.RawJWTOptions{
277*e7b1675dSTing-Kang Chang		WithoutExpiration: true,
278*e7b1675dSTing-Kang Chang		CustomClaims: map[string]interface{}{
279*e7b1675dSTing-Kang Chang			"cc-null":   nil,
280*e7b1675dSTing-Kang Chang			"cc-num":    1.67,
281*e7b1675dSTing-Kang Chang			"cc-bool":   true,
282*e7b1675dSTing-Kang Chang			"cc-string": "goo",
283*e7b1675dSTing-Kang Chang			"cc-array":  []interface{}{"1", "2", "3"},
284*e7b1675dSTing-Kang Chang			"cc-object": map[string]interface{}{"cc-nested-num": 5.99},
285*e7b1675dSTing-Kang Chang		},
286*e7b1675dSTing-Kang Chang	}
287*e7b1675dSTing-Kang Chang	rawJWT, err := jwt.NewRawJWT(opts)
288*e7b1675dSTing-Kang Chang	if err != nil {
289*e7b1675dSTing-Kang Chang		t.Fatalf("jwt.NewRawJWT(%v): %v", opts, err)
290*e7b1675dSTing-Kang Chang	}
291*e7b1675dSTing-Kang Chang	verifiedJWT, err := createVerifiedJWT(rawJWT)
292*e7b1675dSTing-Kang Chang	if err != nil {
293*e7b1675dSTing-Kang Chang		t.Fatalf("creating verifiedJWT: %v", err)
294*e7b1675dSTing-Kang Chang	}
295*e7b1675dSTing-Kang Chang	if verifiedJWT.HasNullClaim("cc-object") {
296*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasNullClaim('cc-object') = true, want false")
297*e7b1675dSTing-Kang Chang	}
298*e7b1675dSTing-Kang Chang	if verifiedJWT.HasNumberClaim("cc-bool") {
299*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasNumberClaim('cc-bool') = true, want false")
300*e7b1675dSTing-Kang Chang	}
301*e7b1675dSTing-Kang Chang	if verifiedJWT.HasStringClaim("cc-array") {
302*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasStringClaim('cc-array') = true, want false")
303*e7b1675dSTing-Kang Chang	}
304*e7b1675dSTing-Kang Chang	if verifiedJWT.HasBooleanClaim("cc-string") {
305*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasBooleanClaim('cc-string') = true, want false")
306*e7b1675dSTing-Kang Chang	}
307*e7b1675dSTing-Kang Chang	if verifiedJWT.HasArrayClaim("cc-null") {
308*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasArrayClaim('cc-null') = true, want false")
309*e7b1675dSTing-Kang Chang	}
310*e7b1675dSTing-Kang Chang	if verifiedJWT.HasObjectClaim("cc-num") {
311*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasObjectClaim('cc-num') = true, want false")
312*e7b1675dSTing-Kang Chang	}
313*e7b1675dSTing-Kang Chang}
314*e7b1675dSTing-Kang Chang
315*e7b1675dSTing-Kang Changfunc TestNoClaimsCallHasAndGet(t *testing.T) {
316*e7b1675dSTing-Kang Chang	opts := &jwt.RawJWTOptions{
317*e7b1675dSTing-Kang Chang		WithoutExpiration: true,
318*e7b1675dSTing-Kang Chang	}
319*e7b1675dSTing-Kang Chang	rawJWT, err := jwt.NewRawJWT(opts)
320*e7b1675dSTing-Kang Chang	if err != nil {
321*e7b1675dSTing-Kang Chang		t.Fatalf("jwt.NewRawJWT(%v): %v", opts, err)
322*e7b1675dSTing-Kang Chang	}
323*e7b1675dSTing-Kang Chang	verifiedJWT, err := createVerifiedJWT(rawJWT)
324*e7b1675dSTing-Kang Chang	if err != nil {
325*e7b1675dSTing-Kang Chang		t.Fatalf("creating verifiedJWT: %v", err)
326*e7b1675dSTing-Kang Chang	}
327*e7b1675dSTing-Kang Chang	if verifiedJWT.HasAudiences() {
328*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasAudiences() = true, want false")
329*e7b1675dSTing-Kang Chang	}
330*e7b1675dSTing-Kang Chang	if verifiedJWT.HasSubject() {
331*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasSubject() = true, want false")
332*e7b1675dSTing-Kang Chang	}
333*e7b1675dSTing-Kang Chang	if verifiedJWT.HasIssuer() {
334*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasIssuer() = true, want false")
335*e7b1675dSTing-Kang Chang	}
336*e7b1675dSTing-Kang Chang	if verifiedJWT.HasJWTID() {
337*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasJWTID() = true, want false")
338*e7b1675dSTing-Kang Chang	}
339*e7b1675dSTing-Kang Chang	if verifiedJWT.HasNotBefore() {
340*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasNotBefore() = true, want false")
341*e7b1675dSTing-Kang Chang	}
342*e7b1675dSTing-Kang Chang	if verifiedJWT.HasExpiration() {
343*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasExpiration() = true, want false")
344*e7b1675dSTing-Kang Chang	}
345*e7b1675dSTing-Kang Chang	if verifiedJWT.HasIssuedAt() {
346*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.HasIssuedAt() = true, want false")
347*e7b1675dSTing-Kang Chang	}
348*e7b1675dSTing-Kang Chang	if !cmp.Equal(verifiedJWT.CustomClaimNames(), []string{}) {
349*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.CustomClaimNames() = %q want %q", verifiedJWT.CustomClaimNames(), []string{})
350*e7b1675dSTing-Kang Chang	}
351*e7b1675dSTing-Kang Chang}
352*e7b1675dSTing-Kang Chang
353*e7b1675dSTing-Kang Changfunc TestCantGetRegisteredClaimsThroughCustomClaims(t *testing.T) {
354*e7b1675dSTing-Kang Chang	now := time.Now()
355*e7b1675dSTing-Kang Chang	opts := &jwt.RawJWTOptions{
356*e7b1675dSTing-Kang Chang		TypeHeader: refString("typeHeader"),
357*e7b1675dSTing-Kang Chang		Subject:    refString("test-subject"),
358*e7b1675dSTing-Kang Chang		Issuer:     refString("test-issuer"),
359*e7b1675dSTing-Kang Chang		JWTID:      refString("1"),
360*e7b1675dSTing-Kang Chang		Audiences:  []string{"foo", "bar"},
361*e7b1675dSTing-Kang Chang		ExpiresAt:  refTime(now.Add(time.Hour * 24).Unix()),
362*e7b1675dSTing-Kang Chang		IssuedAt:   refTime(now.Unix()),
363*e7b1675dSTing-Kang Chang		NotBefore:  refTime(now.Add(-time.Hour * 2).Unix()),
364*e7b1675dSTing-Kang Chang	}
365*e7b1675dSTing-Kang Chang	rawJWT, err := jwt.NewRawJWT(opts)
366*e7b1675dSTing-Kang Chang	if err != nil {
367*e7b1675dSTing-Kang Chang		t.Fatalf("jwt.NewRawJWT(%v): %v", opts, err)
368*e7b1675dSTing-Kang Chang	}
369*e7b1675dSTing-Kang Chang	verifiedJWT, err := createVerifiedJWT(rawJWT)
370*e7b1675dSTing-Kang Chang	if err != nil {
371*e7b1675dSTing-Kang Chang		t.Fatalf("creating verifiedJWT: %v", err)
372*e7b1675dSTing-Kang Chang	}
373*e7b1675dSTing-Kang Chang	for _, c := range []string{"iss", "sub", "aud", "jti", "exp", "nbf", "iat"} {
374*e7b1675dSTing-Kang Chang		if verifiedJWT.HasStringClaim(c) {
375*e7b1675dSTing-Kang Chang			t.Errorf("verifiedJWT.HasStringClaim(%q) = true, want false", c)
376*e7b1675dSTing-Kang Chang		}
377*e7b1675dSTing-Kang Chang		if verifiedJWT.HasNumberClaim(c) {
378*e7b1675dSTing-Kang Chang			t.Errorf("verifiedJWT.HasNumberClaim(%q) = true, want false", c)
379*e7b1675dSTing-Kang Chang		}
380*e7b1675dSTing-Kang Chang		if verifiedJWT.HasArrayClaim(c) {
381*e7b1675dSTing-Kang Chang			t.Errorf("verifiedJWT.HasArrayClaim(%q) = true, want false", c)
382*e7b1675dSTing-Kang Chang		}
383*e7b1675dSTing-Kang Chang
384*e7b1675dSTing-Kang Chang		if _, err := verifiedJWT.StringClaim(c); err == nil {
385*e7b1675dSTing-Kang Chang			t.Errorf("verifiedJWT.StringClaim(%q) err = nil, want error", c)
386*e7b1675dSTing-Kang Chang		}
387*e7b1675dSTing-Kang Chang		if _, err := verifiedJWT.NumberClaim(c); err == nil {
388*e7b1675dSTing-Kang Chang			t.Errorf("verifiedJWT.NumberClaim(%q) err = nil, want error", c)
389*e7b1675dSTing-Kang Chang		}
390*e7b1675dSTing-Kang Chang		if _, err := verifiedJWT.ArrayClaim(c); err == nil {
391*e7b1675dSTing-Kang Chang			t.Errorf("verifiedJWT.ArrayClaim(%q) err = nil, want error", c)
392*e7b1675dSTing-Kang Chang		}
393*e7b1675dSTing-Kang Chang	}
394*e7b1675dSTing-Kang Chang}
395*e7b1675dSTing-Kang Chang
396*e7b1675dSTing-Kang Changfunc TestGetJSONPayload(t *testing.T) {
397*e7b1675dSTing-Kang Chang	opts := &jwt.RawJWTOptions{
398*e7b1675dSTing-Kang Chang		Subject:           refString("test-subject"),
399*e7b1675dSTing-Kang Chang		WithoutExpiration: true,
400*e7b1675dSTing-Kang Chang	}
401*e7b1675dSTing-Kang Chang	rawJWT, err := jwt.NewRawJWT(opts)
402*e7b1675dSTing-Kang Chang	if err != nil {
403*e7b1675dSTing-Kang Chang		t.Fatalf("jwt.NewRawJWT(%v): %v", opts, err)
404*e7b1675dSTing-Kang Chang	}
405*e7b1675dSTing-Kang Chang	verifiedJWT, err := createVerifiedJWT(rawJWT)
406*e7b1675dSTing-Kang Chang	if err != nil {
407*e7b1675dSTing-Kang Chang		t.Fatalf("creating verifiedJWT: %v", err)
408*e7b1675dSTing-Kang Chang	}
409*e7b1675dSTing-Kang Chang	j, err := verifiedJWT.JSONPayload()
410*e7b1675dSTing-Kang Chang	if err != nil {
411*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.JSONPayload() err = %v, want nil", err)
412*e7b1675dSTing-Kang Chang	}
413*e7b1675dSTing-Kang Chang	expected := `{"sub":"test-subject"}`
414*e7b1675dSTing-Kang Chang	if !cmp.Equal(string(j), expected) {
415*e7b1675dSTing-Kang Chang		t.Errorf("verifiedJWT.JSONPayload() = %q, want %q", string(j), expected)
416*e7b1675dSTing-Kang Chang	}
417*e7b1675dSTing-Kang Chang}
418