xref: /aosp_15_r20/external/tink/cc/jwt/raw_jwt_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1*e7b1675dSTing-Kang Chang // Copyright 2021 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 Chang #include "tink/jwt/raw_jwt.h"
18*e7b1675dSTing-Kang Chang 
19*e7b1675dSTing-Kang Chang #include <string>
20*e7b1675dSTing-Kang Chang #include <vector>
21*e7b1675dSTing-Kang Chang 
22*e7b1675dSTing-Kang Chang #include "gtest/gtest.h"
23*e7b1675dSTing-Kang Chang #include "absl/strings/escaping.h"
24*e7b1675dSTing-Kang Chang #include "absl/time/time.h"
25*e7b1675dSTing-Kang Chang #include "tink/util/test_matchers.h"
26*e7b1675dSTing-Kang Chang #include "tink/util/test_util.h"
27*e7b1675dSTing-Kang Chang 
28*e7b1675dSTing-Kang Chang using ::crypto::tink::test::IsOk;
29*e7b1675dSTing-Kang Chang using ::crypto::tink::test::IsOkAndHolds;
30*e7b1675dSTing-Kang Chang using ::testing::IsEmpty;
31*e7b1675dSTing-Kang Chang using ::testing::Not;
32*e7b1675dSTing-Kang Chang using ::testing::UnorderedElementsAreArray;
33*e7b1675dSTing-Kang Chang 
34*e7b1675dSTing-Kang Chang namespace crypto {
35*e7b1675dSTing-Kang Chang namespace tink {
36*e7b1675dSTing-Kang Chang 
TEST(RawJwt,GetTypeHeaderIssuerSubjectJwtIdOK)37*e7b1675dSTing-Kang Chang TEST(RawJwt, GetTypeHeaderIssuerSubjectJwtIdOK) {
38*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt = RawJwtBuilder()
39*e7b1675dSTing-Kang Chang                                    .SetTypeHeader("typeHeader")
40*e7b1675dSTing-Kang Chang                                    .SetIssuer("issuer")
41*e7b1675dSTing-Kang Chang                                    .SetSubject("subject")
42*e7b1675dSTing-Kang Chang                                    .SetJwtId("jwt_id")
43*e7b1675dSTing-Kang Chang                                    .WithoutExpiration()
44*e7b1675dSTing-Kang Chang                                    .Build();
45*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
46*e7b1675dSTing-Kang Chang 
47*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasTypeHeader());
48*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetTypeHeader(), IsOkAndHolds("typeHeader"));
49*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasIssuer());
50*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetIssuer(), IsOkAndHolds("issuer"));
51*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasSubject());
52*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetSubject(), IsOkAndHolds("subject"));
53*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasJwtId());
54*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetJwtId(), IsOkAndHolds("jwt_id"));
55*e7b1675dSTing-Kang Chang }
56*e7b1675dSTing-Kang Chang 
TEST(RawJwt,TimestampsOK)57*e7b1675dSTing-Kang Chang TEST(RawJwt, TimestampsOK) {
58*e7b1675dSTing-Kang Chang   absl::Time nbf = absl::FromUnixSeconds(1234567890);
59*e7b1675dSTing-Kang Chang   absl::Time iat = absl::FromUnixSeconds(1234567891);
60*e7b1675dSTing-Kang Chang   absl::Time exp = absl::FromUnixSeconds(1234567892);
61*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt = RawJwtBuilder()
62*e7b1675dSTing-Kang Chang                                    .SetNotBefore(nbf)
63*e7b1675dSTing-Kang Chang                                    .SetIssuedAt(iat)
64*e7b1675dSTing-Kang Chang                                    .SetExpiration(exp)
65*e7b1675dSTing-Kang Chang                                    .Build();
66*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
67*e7b1675dSTing-Kang Chang 
68*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasNotBefore());
69*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetNotBefore(), IsOkAndHolds(nbf));
70*e7b1675dSTing-Kang Chang 
71*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasIssuedAt());
72*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetIssuedAt(), IsOkAndHolds(iat));
73*e7b1675dSTing-Kang Chang 
74*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasExpiration());
75*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetExpiration(), IsOkAndHolds(exp));
76*e7b1675dSTing-Kang Chang }
77*e7b1675dSTing-Kang Chang 
TEST(RawJwt,ExpWithMillisAlwaysRoundDown)78*e7b1675dSTing-Kang Chang TEST(RawJwt, ExpWithMillisAlwaysRoundDown) {
79*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt =
80*e7b1675dSTing-Kang Chang       RawJwtBuilder().SetExpiration(absl::FromUnixMillis(123999)).Build();
81*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
82*e7b1675dSTing-Kang Chang 
83*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasExpiration());
84*e7b1675dSTing-Kang Chang   util::StatusOr<absl::Time> exp = jwt->GetExpiration();
85*e7b1675dSTing-Kang Chang   EXPECT_THAT(exp, IsOkAndHolds(absl::FromUnixSeconds(123)));
86*e7b1675dSTing-Kang Chang }
87*e7b1675dSTing-Kang Chang 
TEST(RawJwt,NbfWithMillisAlwaysRoundDown)88*e7b1675dSTing-Kang Chang TEST(RawJwt, NbfWithMillisAlwaysRoundDown) {
89*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt = RawJwtBuilder()
90*e7b1675dSTing-Kang Chang                                    .SetNotBefore(absl::FromUnixMillis(123999))
91*e7b1675dSTing-Kang Chang                                    .WithoutExpiration()
92*e7b1675dSTing-Kang Chang                                    .Build();
93*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
94*e7b1675dSTing-Kang Chang 
95*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasNotBefore());
96*e7b1675dSTing-Kang Chang   util::StatusOr<absl::Time> nbf = jwt->GetNotBefore();
97*e7b1675dSTing-Kang Chang   EXPECT_THAT(nbf, IsOkAndHolds(absl::FromUnixSeconds(123)));
98*e7b1675dSTing-Kang Chang }
99*e7b1675dSTing-Kang Chang 
TEST(RawJwt,IatWithMillisAlwaysRoundDown)100*e7b1675dSTing-Kang Chang TEST(RawJwt, IatWithMillisAlwaysRoundDown) {
101*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt = RawJwtBuilder()
102*e7b1675dSTing-Kang Chang                                    .SetIssuedAt(absl::FromUnixMillis(123999))
103*e7b1675dSTing-Kang Chang                                    .WithoutExpiration()
104*e7b1675dSTing-Kang Chang                                    .Build();
105*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
106*e7b1675dSTing-Kang Chang 
107*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasIssuedAt());
108*e7b1675dSTing-Kang Chang   util::StatusOr<absl::Time> iat = jwt->GetIssuedAt();
109*e7b1675dSTing-Kang Chang   EXPECT_THAT(iat, IsOkAndHolds(absl::FromUnixSeconds(123)));
110*e7b1675dSTing-Kang Chang }
111*e7b1675dSTing-Kang Chang 
TEST(RawJwt,LargeExpirationWorks)112*e7b1675dSTing-Kang Chang TEST(RawJwt, LargeExpirationWorks) {
113*e7b1675dSTing-Kang Chang   absl::Time large = absl::FromUnixSeconds(253402300799);  // year 9999
114*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt = RawJwtBuilder()
115*e7b1675dSTing-Kang Chang                                    .SetNotBefore(large)
116*e7b1675dSTing-Kang Chang                                    .SetIssuedAt(large)
117*e7b1675dSTing-Kang Chang                                    .SetExpiration(large)
118*e7b1675dSTing-Kang Chang                                    .Build();
119*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
120*e7b1675dSTing-Kang Chang 
121*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasExpiration());
122*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasIssuedAt());
123*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasNotBefore());
124*e7b1675dSTing-Kang Chang   util::StatusOr<absl::Time> exp = jwt->GetExpiration();
125*e7b1675dSTing-Kang Chang   EXPECT_THAT(exp, IsOkAndHolds(large));
126*e7b1675dSTing-Kang Chang   util::StatusOr<absl::Time> iat = jwt->GetIssuedAt();
127*e7b1675dSTing-Kang Chang   EXPECT_THAT(iat, IsOkAndHolds(large));
128*e7b1675dSTing-Kang Chang   util::StatusOr<absl::Time> nbf = jwt->GetNotBefore();
129*e7b1675dSTing-Kang Chang   EXPECT_THAT(nbf, IsOkAndHolds(large));
130*e7b1675dSTing-Kang Chang }
131*e7b1675dSTing-Kang Chang 
TEST(RawJwt,TooLargeTimestampsFail)132*e7b1675dSTing-Kang Chang TEST(RawJwt, TooLargeTimestampsFail) {
133*e7b1675dSTing-Kang Chang   absl::Time too_large = absl::FromUnixSeconds(253402300800);  // year 10000
134*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder().SetExpiration(too_large).Build().ok());
135*e7b1675dSTing-Kang Chang   EXPECT_FALSE(
136*e7b1675dSTing-Kang Chang       RawJwtBuilder().SetIssuedAt(too_large).WithoutExpiration().Build().ok());
137*e7b1675dSTing-Kang Chang   EXPECT_FALSE(
138*e7b1675dSTing-Kang Chang       RawJwtBuilder().SetNotBefore(too_large).WithoutExpiration().Build().ok());
139*e7b1675dSTing-Kang Chang }
140*e7b1675dSTing-Kang Chang 
TEST(RawJwt,NegativeTimestampsFail)141*e7b1675dSTing-Kang Chang TEST(RawJwt, NegativeTimestampsFail) {
142*e7b1675dSTing-Kang Chang   absl::Time neg = absl::FromUnixMillis(-1);
143*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder().SetExpiration(neg).Build().ok());
144*e7b1675dSTing-Kang Chang   EXPECT_FALSE(
145*e7b1675dSTing-Kang Chang       RawJwtBuilder().SetIssuedAt(neg).WithoutExpiration().Build().ok());
146*e7b1675dSTing-Kang Chang   EXPECT_FALSE(
147*e7b1675dSTing-Kang Chang       RawJwtBuilder().SetNotBefore(neg).WithoutExpiration().Build().ok());
148*e7b1675dSTing-Kang Chang }
149*e7b1675dSTing-Kang Chang 
TEST(RawJwt,SetExpirationAndWithoutExpirationFail)150*e7b1675dSTing-Kang Chang TEST(RawJwt, SetExpirationAndWithoutExpirationFail) {
151*e7b1675dSTing-Kang Chang   absl::Time exp = absl::FromUnixMillis(12345);
152*e7b1675dSTing-Kang Chang   EXPECT_FALSE(
153*e7b1675dSTing-Kang Chang       RawJwtBuilder().SetExpiration(exp).WithoutExpiration().Build().ok());
154*e7b1675dSTing-Kang Chang }
155*e7b1675dSTing-Kang Chang 
TEST(RawJwt,NeitherSetExpirationNorWithoutExpirationFail)156*e7b1675dSTing-Kang Chang TEST(RawJwt, NeitherSetExpirationNorWithoutExpirationFail) {
157*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder().Build().ok());
158*e7b1675dSTing-Kang Chang }
159*e7b1675dSTing-Kang Chang 
TEST(RawJwt,SetAudienceAndGetAudiencesOK)160*e7b1675dSTing-Kang Chang TEST(RawJwt, SetAudienceAndGetAudiencesOK) {
161*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt =
162*e7b1675dSTing-Kang Chang       RawJwtBuilder().SetAudience("audience").WithoutExpiration().Build();
163*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
164*e7b1675dSTing-Kang Chang 
165*e7b1675dSTing-Kang Chang   std::vector<std::string> expected = {"audience"};
166*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasAudiences());
167*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetAudiences(), IsOkAndHolds(expected));
168*e7b1675dSTing-Kang Chang }
169*e7b1675dSTing-Kang Chang 
TEST(RawJwt,SetAudiencesAndGetAudiencesOK)170*e7b1675dSTing-Kang Chang TEST(RawJwt, SetAudiencesAndGetAudiencesOK) {
171*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt = RawJwtBuilder()
172*e7b1675dSTing-Kang Chang                                    .SetAudiences({"audience1", "audience2"})
173*e7b1675dSTing-Kang Chang                                    .WithoutExpiration()
174*e7b1675dSTing-Kang Chang                                    .Build();
175*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
176*e7b1675dSTing-Kang Chang 
177*e7b1675dSTing-Kang Chang   std::vector<std::string> expected = {"audience1", "audience2"};
178*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasAudiences());
179*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetAudiences(), IsOkAndHolds(expected));
180*e7b1675dSTing-Kang Chang }
181*e7b1675dSTing-Kang Chang 
TEST(RawJwt,AddGetAudiencesOK)182*e7b1675dSTing-Kang Chang TEST(RawJwt, AddGetAudiencesOK) {
183*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt = RawJwtBuilder()
184*e7b1675dSTing-Kang Chang                                    .AddAudience("audience1")
185*e7b1675dSTing-Kang Chang                                    .AddAudience("audience2")
186*e7b1675dSTing-Kang Chang                                    .WithoutExpiration()
187*e7b1675dSTing-Kang Chang                                    .Build();
188*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
189*e7b1675dSTing-Kang Chang 
190*e7b1675dSTing-Kang Chang   std::vector<std::string> expected = {"audience1", "audience2"};
191*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasAudiences());
192*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetAudiences(), IsOkAndHolds(expected));
193*e7b1675dSTing-Kang Chang }
194*e7b1675dSTing-Kang Chang 
TEST(RawJwt,SetAudienceStringAud)195*e7b1675dSTing-Kang Chang TEST(RawJwt, SetAudienceStringAud) {
196*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt =
197*e7b1675dSTing-Kang Chang       RawJwtBuilder().SetAudience("audience").WithoutExpiration().Build();
198*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
199*e7b1675dSTing-Kang Chang 
200*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetJsonPayload(), IsOkAndHolds(R"({"aud":"audience"})"));
201*e7b1675dSTing-Kang Chang }
202*e7b1675dSTing-Kang Chang 
TEST(RawJwt,AddAudienceListAud)203*e7b1675dSTing-Kang Chang TEST(RawJwt, AddAudienceListAud) {
204*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt =
205*e7b1675dSTing-Kang Chang       RawJwtBuilder().AddAudience("audience").WithoutExpiration().Build();
206*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
207*e7b1675dSTing-Kang Chang 
208*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetJsonPayload(), IsOkAndHolds(R"({"aud":["audience"]})"));
209*e7b1675dSTing-Kang Chang }
210*e7b1675dSTing-Kang Chang 
TEST(RawJwt,SetAndAddAudienceFail)211*e7b1675dSTing-Kang Chang TEST(RawJwt, SetAndAddAudienceFail) {
212*e7b1675dSTing-Kang Chang   EXPECT_THAT(RawJwtBuilder()
213*e7b1675dSTing-Kang Chang                   .SetAudience("audience1")
214*e7b1675dSTing-Kang Chang                   .AddAudience("audience2")
215*e7b1675dSTing-Kang Chang                   .Build()
216*e7b1675dSTing-Kang Chang                   .status(),
217*e7b1675dSTing-Kang Chang               Not(IsOk()));
218*e7b1675dSTing-Kang Chang   EXPECT_THAT(RawJwtBuilder()
219*e7b1675dSTing-Kang Chang                   .AddAudience("audience2")
220*e7b1675dSTing-Kang Chang                   .SetAudience("audience1")
221*e7b1675dSTing-Kang Chang                   .Build()
222*e7b1675dSTing-Kang Chang                   .status(),
223*e7b1675dSTing-Kang Chang               Not(IsOk()));
224*e7b1675dSTing-Kang Chang }
225*e7b1675dSTing-Kang Chang 
TEST(RawJwt,GetCustomClaimOK)226*e7b1675dSTing-Kang Chang TEST(RawJwt, GetCustomClaimOK) {
227*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt =
228*e7b1675dSTing-Kang Chang       RawJwtBuilder()
229*e7b1675dSTing-Kang Chang           .WithoutExpiration()
230*e7b1675dSTing-Kang Chang           .AddNullClaim("null_claim")
231*e7b1675dSTing-Kang Chang           .AddBooleanClaim("boolean_claim", true)
232*e7b1675dSTing-Kang Chang           .AddNumberClaim("number_claim", 123.456)
233*e7b1675dSTing-Kang Chang           .AddStringClaim("string_claim", "a string")
234*e7b1675dSTing-Kang Chang           .AddJsonObjectClaim("object_claim", R"({ "number": 123.456})")
235*e7b1675dSTing-Kang Chang           .AddJsonArrayClaim("array_claim", R"([1, "one", 1.2, true])")
236*e7b1675dSTing-Kang Chang           .Build();
237*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
238*e7b1675dSTing-Kang Chang 
239*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->IsNullClaim("null_claim"));
240*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasBooleanClaim("boolean_claim"));
241*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetBooleanClaim("boolean_claim"), IsOkAndHolds(true));
242*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasNumberClaim("number_claim"));
243*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetNumberClaim("number_claim"), IsOkAndHolds(123.456));
244*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasStringClaim("string_claim"));
245*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetStringClaim("string_claim"), IsOkAndHolds("a string"));
246*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasJsonObjectClaim("object_claim"));
247*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetJsonObjectClaim("object_claim"),
248*e7b1675dSTing-Kang Chang               IsOkAndHolds(R"({"number":123.456})"));
249*e7b1675dSTing-Kang Chang   EXPECT_TRUE(jwt->HasJsonArrayClaim("array_claim"));
250*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetJsonArrayClaim("array_claim"),
251*e7b1675dSTing-Kang Chang               IsOkAndHolds(R"([1,"one",1.2,true])"));
252*e7b1675dSTing-Kang Chang 
253*e7b1675dSTing-Kang Chang   std::vector<std::string> expected_claim_names = {
254*e7b1675dSTing-Kang Chang       "object_claim", "number_claim", "boolean_claim",
255*e7b1675dSTing-Kang Chang       "array_claim",  "null_claim",   "string_claim"};
256*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->CustomClaimNames(),
257*e7b1675dSTing-Kang Chang               UnorderedElementsAreArray(expected_claim_names));
258*e7b1675dSTing-Kang Chang }
259*e7b1675dSTing-Kang Chang 
TEST(RawJwt,HasCustomClaimIsFalseForWrongType)260*e7b1675dSTing-Kang Chang TEST(RawJwt, HasCustomClaimIsFalseForWrongType) {
261*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt = RawJwtBuilder()
262*e7b1675dSTing-Kang Chang                                    .WithoutExpiration()
263*e7b1675dSTing-Kang Chang                                    .AddNullClaim("null_claim")
264*e7b1675dSTing-Kang Chang                                    .AddBooleanClaim("boolean_claim", true)
265*e7b1675dSTing-Kang Chang                                    .AddNumberClaim("number_claim", 123.456)
266*e7b1675dSTing-Kang Chang                                    .AddStringClaim("string_claim", "a string")
267*e7b1675dSTing-Kang Chang                                    .Build();
268*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
269*e7b1675dSTing-Kang Chang 
270*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->IsNullClaim("boolean_claim"));
271*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasBooleanClaim("number_claim"));
272*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasNumberClaim("string_claim"));
273*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasStringClaim("null_claim"));
274*e7b1675dSTing-Kang Chang }
275*e7b1675dSTing-Kang Chang 
TEST(RawJwt,HasAlwaysReturnsFalseForRegisteredClaims)276*e7b1675dSTing-Kang Chang TEST(RawJwt, HasAlwaysReturnsFalseForRegisteredClaims) {
277*e7b1675dSTing-Kang Chang   absl::Time now = absl::Now();
278*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt = RawJwtBuilder()
279*e7b1675dSTing-Kang Chang                                    .SetIssuer("issuer")
280*e7b1675dSTing-Kang Chang                                    .SetSubject("subject")
281*e7b1675dSTing-Kang Chang                                    .SetJwtId("jwt_id")
282*e7b1675dSTing-Kang Chang                                    .SetNotBefore(now - absl::Seconds(300))
283*e7b1675dSTing-Kang Chang                                    .SetIssuedAt(now)
284*e7b1675dSTing-Kang Chang                                    .SetExpiration(now + absl::Seconds(300))
285*e7b1675dSTing-Kang Chang                                    .Build();
286*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
287*e7b1675dSTing-Kang Chang 
288*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasStringClaim("iss"));
289*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasStringClaim("sub"));
290*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasStringClaim("jti"));
291*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasNumberClaim("nbf"));
292*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasNumberClaim("iat"));
293*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasNumberClaim("exp"));
294*e7b1675dSTing-Kang Chang 
295*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->CustomClaimNames(), IsEmpty());
296*e7b1675dSTing-Kang Chang }
297*e7b1675dSTing-Kang Chang 
TEST(RawJwt,GetRegisteredCustomClaimNotOK)298*e7b1675dSTing-Kang Chang TEST(RawJwt, GetRegisteredCustomClaimNotOK) {
299*e7b1675dSTing-Kang Chang   absl::Time now = absl::Now();
300*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt = RawJwtBuilder()
301*e7b1675dSTing-Kang Chang                                    .SetIssuer("issuer")
302*e7b1675dSTing-Kang Chang                                    .SetSubject("subject")
303*e7b1675dSTing-Kang Chang                                    .SetJwtId("jwt_id")
304*e7b1675dSTing-Kang Chang                                    .SetNotBefore(now - absl::Seconds(300))
305*e7b1675dSTing-Kang Chang                                    .SetIssuedAt(now)
306*e7b1675dSTing-Kang Chang                                    .SetExpiration(now + absl::Seconds(300))
307*e7b1675dSTing-Kang Chang                                    .Build();
308*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
309*e7b1675dSTing-Kang Chang 
310*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetStringClaim("iss").ok());
311*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetStringClaim("sub").ok());
312*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetStringClaim("jti").ok());
313*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetNumberClaim("nbf").ok());
314*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetNumberClaim("iat").ok());
315*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetNumberClaim("exp").ok());
316*e7b1675dSTing-Kang Chang }
317*e7b1675dSTing-Kang Chang 
TEST(RawJwt,SetRegisteredCustomClaimNotOK)318*e7b1675dSTing-Kang Chang TEST(RawJwt, SetRegisteredCustomClaimNotOK) {
319*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder()
320*e7b1675dSTing-Kang Chang                    .WithoutExpiration()
321*e7b1675dSTing-Kang Chang                    .AddStringClaim("iss", "issuer")
322*e7b1675dSTing-Kang Chang                    .Build()
323*e7b1675dSTing-Kang Chang                    .ok());
324*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder()
325*e7b1675dSTing-Kang Chang                    .WithoutExpiration()
326*e7b1675dSTing-Kang Chang                    .AddStringClaim("sub", "issuer")
327*e7b1675dSTing-Kang Chang                    .Build()
328*e7b1675dSTing-Kang Chang                    .ok());
329*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder()
330*e7b1675dSTing-Kang Chang                    .WithoutExpiration()
331*e7b1675dSTing-Kang Chang                    .AddStringClaim("jti", "issuer")
332*e7b1675dSTing-Kang Chang                    .Build()
333*e7b1675dSTing-Kang Chang                    .ok());
334*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder()
335*e7b1675dSTing-Kang Chang                    .WithoutExpiration()
336*e7b1675dSTing-Kang Chang                    .AddNumberClaim("nbf", 123)
337*e7b1675dSTing-Kang Chang                    .Build()
338*e7b1675dSTing-Kang Chang                    .ok());
339*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder()
340*e7b1675dSTing-Kang Chang                    .WithoutExpiration()
341*e7b1675dSTing-Kang Chang                    .AddNumberClaim("iat", 123)
342*e7b1675dSTing-Kang Chang                    .Build()
343*e7b1675dSTing-Kang Chang                    .ok());
344*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder()
345*e7b1675dSTing-Kang Chang                    .WithoutExpiration()
346*e7b1675dSTing-Kang Chang                    .AddNumberClaim("exp", 123)
347*e7b1675dSTing-Kang Chang                    .Build()
348*e7b1675dSTing-Kang Chang                    .ok());
349*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder()
350*e7b1675dSTing-Kang Chang                    .WithoutExpiration()
351*e7b1675dSTing-Kang Chang                    .AddBooleanClaim("iss", true)
352*e7b1675dSTing-Kang Chang                    .Build()
353*e7b1675dSTing-Kang Chang                    .ok());
354*e7b1675dSTing-Kang Chang   EXPECT_FALSE(
355*e7b1675dSTing-Kang Chang       RawJwtBuilder().WithoutExpiration().AddNullClaim("iss").Build().ok());
356*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder()
357*e7b1675dSTing-Kang Chang                    .WithoutExpiration()
358*e7b1675dSTing-Kang Chang                    .AddJsonObjectClaim("iss", "{\"1\": 2}")
359*e7b1675dSTing-Kang Chang                    .Build()
360*e7b1675dSTing-Kang Chang                    .ok());
361*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder()
362*e7b1675dSTing-Kang Chang                    .WithoutExpiration()
363*e7b1675dSTing-Kang Chang                    .AddJsonArrayClaim("iss", "[1,2]")
364*e7b1675dSTing-Kang Chang                    .Build()
365*e7b1675dSTing-Kang Chang                    .ok());
366*e7b1675dSTing-Kang Chang }
367*e7b1675dSTing-Kang Chang 
TEST(RawJwt,SetInvalidJsonObjectClaimNotOK)368*e7b1675dSTing-Kang Chang TEST(RawJwt, SetInvalidJsonObjectClaimNotOK) {
369*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder()
370*e7b1675dSTing-Kang Chang                    .WithoutExpiration()
371*e7b1675dSTing-Kang Chang                    .AddJsonObjectClaim("obj", "invalid")
372*e7b1675dSTing-Kang Chang                    .Build()
373*e7b1675dSTing-Kang Chang                    .ok());
374*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder()
375*e7b1675dSTing-Kang Chang                    .WithoutExpiration()
376*e7b1675dSTing-Kang Chang                    .AddJsonObjectClaim("obj", R"("string")")
377*e7b1675dSTing-Kang Chang                    .Build()
378*e7b1675dSTing-Kang Chang                    .ok());
379*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder()
380*e7b1675dSTing-Kang Chang                    .WithoutExpiration()
381*e7b1675dSTing-Kang Chang                    .AddJsonObjectClaim("obj", "42")
382*e7b1675dSTing-Kang Chang                    .Build()
383*e7b1675dSTing-Kang Chang                    .ok());
384*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder()
385*e7b1675dSTing-Kang Chang                    .WithoutExpiration()
386*e7b1675dSTing-Kang Chang                    .AddJsonObjectClaim("obj", "[1,2]")
387*e7b1675dSTing-Kang Chang                    .Build()
388*e7b1675dSTing-Kang Chang                    .ok());
389*e7b1675dSTing-Kang Chang }
390*e7b1675dSTing-Kang Chang 
TEST(RawJwt,SetInvalidJsonArrayClaimNotOK)391*e7b1675dSTing-Kang Chang TEST(RawJwt, SetInvalidJsonArrayClaimNotOK) {
392*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder()
393*e7b1675dSTing-Kang Chang                    .WithoutExpiration()
394*e7b1675dSTing-Kang Chang                    .AddJsonArrayClaim("arr", "invalid")
395*e7b1675dSTing-Kang Chang                    .Build()
396*e7b1675dSTing-Kang Chang                    .ok());
397*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder()
398*e7b1675dSTing-Kang Chang                    .WithoutExpiration()
399*e7b1675dSTing-Kang Chang                    .AddJsonArrayClaim("arr", R"("string")")
400*e7b1675dSTing-Kang Chang                    .Build()
401*e7b1675dSTing-Kang Chang                    .ok());
402*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder()
403*e7b1675dSTing-Kang Chang                    .WithoutExpiration()
404*e7b1675dSTing-Kang Chang                    .AddJsonArrayClaim("arr", "42")
405*e7b1675dSTing-Kang Chang                    .Build()
406*e7b1675dSTing-Kang Chang                    .ok());
407*e7b1675dSTing-Kang Chang   EXPECT_FALSE(RawJwtBuilder()
408*e7b1675dSTing-Kang Chang                    .WithoutExpiration()
409*e7b1675dSTing-Kang Chang                    .AddJsonArrayClaim("arr", R"({"1": 2})")
410*e7b1675dSTing-Kang Chang                    .Build()
411*e7b1675dSTing-Kang Chang                    .ok());
412*e7b1675dSTing-Kang Chang }
413*e7b1675dSTing-Kang Chang 
TEST(RawJwt,EmptyTokenHasAndIsReturnsFalse)414*e7b1675dSTing-Kang Chang TEST(RawJwt, EmptyTokenHasAndIsReturnsFalse) {
415*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt = RawJwtBuilder().WithoutExpiration().Build();
416*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
417*e7b1675dSTing-Kang Chang 
418*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasTypeHeader());
419*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasIssuer());
420*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasSubject());
421*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasAudiences());
422*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasJwtId());
423*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasExpiration());
424*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasNotBefore());
425*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasIssuedAt());
426*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->IsNullClaim("null_claim"));
427*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasBooleanClaim("boolean_claim"));
428*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasNumberClaim("number_claim"));
429*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasStringClaim("string_claim"));
430*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasJsonObjectClaim("object_claim"));
431*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->HasJsonArrayClaim("array_claim"));
432*e7b1675dSTing-Kang Chang }
433*e7b1675dSTing-Kang Chang 
TEST(RawJwt,EmptyTokenGetReturnsNotOK)434*e7b1675dSTing-Kang Chang TEST(RawJwt, EmptyTokenGetReturnsNotOK) {
435*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt = RawJwtBuilder().WithoutExpiration().Build();
436*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
437*e7b1675dSTing-Kang Chang 
438*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetTypeHeader().ok());
439*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetIssuer().ok());
440*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetSubject().ok());
441*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetAudiences().ok());
442*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetJwtId().ok());
443*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetExpiration().ok());
444*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetNotBefore().ok());
445*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetIssuedAt().ok());
446*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->IsNullClaim("null_claim"));
447*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetBooleanClaim("boolean_claim").ok());
448*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetNumberClaim("number_claim").ok());
449*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetStringClaim("string_claim").ok());
450*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetJsonObjectClaim("object_claim").ok());
451*e7b1675dSTing-Kang Chang   EXPECT_FALSE(jwt->GetJsonArrayClaim("array_claim").ok());
452*e7b1675dSTing-Kang Chang }
453*e7b1675dSTing-Kang Chang 
TEST(RawJwt,BuildCanBeCalledTwice)454*e7b1675dSTing-Kang Chang TEST(RawJwt, BuildCanBeCalledTwice) {
455*e7b1675dSTing-Kang Chang   auto builder = RawJwtBuilder()
456*e7b1675dSTing-Kang Chang                      .SetIssuer("issuer")
457*e7b1675dSTing-Kang Chang                      .SetSubject("subject")
458*e7b1675dSTing-Kang Chang                      .WithoutExpiration();
459*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt = builder.Build();
460*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
461*e7b1675dSTing-Kang Chang 
462*e7b1675dSTing-Kang Chang   builder.SetSubject("subject2");
463*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt2 = builder.Build();
464*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt2, IsOk());
465*e7b1675dSTing-Kang Chang 
466*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetIssuer(), IsOkAndHolds("issuer"));
467*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetSubject(), IsOkAndHolds("subject"));
468*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt2->GetIssuer(), IsOkAndHolds("issuer"));
469*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt2->GetSubject(), IsOkAndHolds("subject2"));
470*e7b1675dSTing-Kang Chang }
471*e7b1675dSTing-Kang Chang 
TEST(RawJwt,GetJsonPayload)472*e7b1675dSTing-Kang Chang TEST(RawJwt, GetJsonPayload) {
473*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt =
474*e7b1675dSTing-Kang Chang       RawJwtBuilder().SetIssuer("issuer").WithoutExpiration().Build();
475*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
476*e7b1675dSTing-Kang Chang 
477*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetJsonPayload(), IsOkAndHolds(R"({"iss":"issuer"})"));
478*e7b1675dSTing-Kang Chang }
479*e7b1675dSTing-Kang Chang 
TEST(RawJwt,IntegerIsEncodedAsInteger)480*e7b1675dSTing-Kang Chang TEST(RawJwt, IntegerIsEncodedAsInteger) {
481*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt =
482*e7b1675dSTing-Kang Chang       RawJwtBuilder().AddNumberClaim("num", 1).WithoutExpiration().Build();
483*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
484*e7b1675dSTing-Kang Chang 
485*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetJsonPayload(), IsOkAndHolds(R"({"num":1})"));
486*e7b1675dSTing-Kang Chang }
487*e7b1675dSTing-Kang Chang 
TEST(RawJwt,GetExpirationJsonPayload)488*e7b1675dSTing-Kang Chang TEST(RawJwt, GetExpirationJsonPayload) {
489*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt =
490*e7b1675dSTing-Kang Chang       RawJwtBuilder().SetExpiration(absl::FromUnixSeconds(2218027244)).Build();
491*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
492*e7b1675dSTing-Kang Chang 
493*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetJsonPayload(), IsOkAndHolds(R"({"exp":2218027244})"));
494*e7b1675dSTing-Kang Chang }
495*e7b1675dSTing-Kang Chang 
TEST(RawJwt,GetNanoExpirationJsonPayload)496*e7b1675dSTing-Kang Chang TEST(RawJwt, GetNanoExpirationJsonPayload) {
497*e7b1675dSTing-Kang Chang   util::StatusOr<RawJwt> jwt =
498*e7b1675dSTing-Kang Chang       RawJwtBuilder().SetExpiration(absl::FromUnixNanos(123456789012)).Build();
499*e7b1675dSTing-Kang Chang   ASSERT_THAT(jwt, IsOk());
500*e7b1675dSTing-Kang Chang 
501*e7b1675dSTing-Kang Chang   EXPECT_THAT(jwt->GetJsonPayload(), IsOkAndHolds(R"({"exp":123})"));
502*e7b1675dSTing-Kang Chang }
503*e7b1675dSTing-Kang Chang 
504*e7b1675dSTing-Kang Chang }  // namespace tink
505*e7b1675dSTing-Kang Chang }  // namespace crypto
506