Skip to content

Commit f85f271

Browse files
authored
Merge pull request #98 from bbockelm/explicit_time
Allow the library user to explicitly set the "current" time.
2 parents b4ac826 + 39390f3 commit f85f271

File tree

4 files changed

+104
-11
lines changed

4 files changed

+104
-11
lines changed

src/scitokens.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,18 @@ int validator_validate(Validator validator, SciToken scitoken, char **err_msg) {
347347
}
348348

349349

350+
int validator_set_time(Validator validator, time_t now, char **err_msg) {
351+
if (validator == nullptr) {
352+
if (err_msg) {*err_msg = strdup("Validator may not be a null pointer");}
353+
return -1;
354+
}
355+
auto real_validator = reinterpret_cast<scitokens::Validator*>(validator);
356+
357+
real_validator->set_now(std::chrono::system_clock::from_time_t(now));
358+
359+
return 0;
360+
}
361+
350362
Enforcer enforcer_create(const char *issuer, const char **audience_list, char **err_msg) {
351363
if (issuer == nullptr) {
352364
if (err_msg) {*err_msg = strdup("Issuer may not be a null pointer");}
@@ -388,6 +400,19 @@ void enforcer_set_validate_profile(Enforcer enf, SciTokenProfile profile) {
388400
}
389401

390402

403+
int enforcer_set_time(Enforcer enf, time_t now, char **err_msg) {
404+
if (enf == nullptr) {
405+
if (err_msg) {*err_msg = strdup("Enforcer may not be a null pointer");}
406+
return -1;
407+
}
408+
auto real_enf = reinterpret_cast<scitokens::Enforcer*>(enf);
409+
410+
real_enf->set_now(std::chrono::system_clock::from_time_t(now));
411+
412+
return 0;
413+
}
414+
415+
391416
int enforcer_generate_acls(const Enforcer enf, const SciToken scitoken, Acl **acls, char **err_msg) {
392417
if (enf == nullptr) {
393418
if (err_msg) {*err_msg = strdup("Enforcer may not be a null pointer");}

src/scitokens.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
*/
66

77
#ifdef __cplusplus
8+
#include <ctime>
89
extern "C" {
10+
#else
11+
#include <time.h>
912
#endif
1013

1114
typedef void * SciTokenKey;
@@ -100,6 +103,12 @@ Validator validator_create();
100103
*/
101104
void validator_set_token_profile(Validator, SciTokenProfile profile);
102105

106+
/**
107+
* Set the time to use with the validator. Useful if you want to see if the token would
108+
* have been valid at some time in the past.
109+
*/
110+
int validator_set_time(Validator validator, time_t now, char **err_msg);
111+
103112
int validator_add(Validator validator, const char *claim, StringValidatorFunction validator_func, char **err_msg);
104113

105114
int validator_add_critical_claims(Validator validator, const char **claims, char **err_msg);
@@ -121,6 +130,12 @@ void enforcer_destroy(Enforcer);
121130
*/
122131
void enforcer_set_validate_profile(Enforcer, SciTokenProfile profile);
123132

133+
/**
134+
* Set the time to use with the enforcer. Useful if you want to see if the token would
135+
* have been valid at some time in the past.
136+
*/
137+
int enforcer_set_time(Enforcer enf, time_t now, char **err_msg);
138+
124139
int enforcer_generate_acls(const Enforcer enf, const SciToken scitokens, Acl **acls, char **err_msg);
125140

126141
void enforcer_acl_free(Acl *acls);

src/scitokens_internal.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@
66
#include <jwt-cpp/jwt.h>
77
#include <uuid/uuid.h>
88

9+
namespace {
10+
11+
struct FixedClock {
12+
jwt::date m_now;
13+
jwt::date now() const {return m_now;}
14+
};
15+
16+
}
17+
918
namespace jwt {
1019
template<typename json_traits>
1120
class decoded_jwt;
@@ -267,6 +276,10 @@ class Validator {
267276
typedef std::map<std::string, std::vector<std::pair<ClaimValidatorFunction, void*>>> ClaimValidatorMap;
268277

269278
public:
279+
Validator() : m_now(std::chrono::system_clock::now()) {}
280+
281+
void set_now(std::chrono::system_clock::time_point now) {m_now = now;}
282+
270283
void verify(const SciToken &scitoken) {
271284
const jwt::decoded_jwt<jwt::traits::kazuho_picojson> *jwt_decoded = scitoken.m_decoded.get();
272285
if (!jwt_decoded) {
@@ -343,7 +356,8 @@ class Validator {
343356
get_public_key_pem(jwt.get_issuer(), key_id, public_pem, algorithm);
344357
// std::cout << "Public PEM: " << public_pem << std::endl << "Algorithm: " << algorithm << std::endl;
345358
SciTokenKey key(key_id, algorithm, public_pem, "");
346-
auto verifier = jwt::verify()
359+
360+
auto verifier = jwt::verify<FixedClock, jwt::traits::kazuho_picojson>({m_now})
347361
.allow_algorithm(key);
348362

349363
verifier.verify(jwt);
@@ -544,6 +558,8 @@ class Validator {
544558
ClaimStringValidatorMap m_validators;
545559
ClaimValidatorMap m_claim_validators;
546560

561+
std::chrono::system_clock::time_point m_now;
562+
547563
std::vector<std::string> m_critical_claims;
548564
std::vector<std::string> m_allowed_issuers;
549565
};
@@ -572,6 +588,8 @@ class Enforcer {
572588
m_validator.add_critical_claims(critical_claims);
573589
}
574590

591+
void set_now(std::chrono::system_clock::time_point now) {m_validator.set_now(now);}
592+
575593
void set_validate_profile(SciToken::Profile profile) {
576594
m_validate_profile = profile;
577595
}

test/main.cpp

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ class SerializeTest : public ::testing::Test {
167167
"1", ec_public, &err_msg);
168168
ASSERT_TRUE(rv == 0);
169169

170+
scitoken_set_lifetime(m_token.get(), 60);
171+
172+
m_audiences_array.push_back("https://demo.scitokens.org/");
173+
m_audiences_array.push_back(nullptr);
174+
170175
const char *groups[3] = {nullptr, nullptr, nullptr};
171176
const char group0[] = "group0";
172177
const char group1[] = "group1";
@@ -186,6 +191,8 @@ class SerializeTest : public ::testing::Test {
186191
using TokenPtr = std::unique_ptr<void, decltype(&scitoken_destroy)>;
187192
TokenPtr m_token{nullptr, scitoken_destroy};
188193

194+
std::vector<const char *> m_audiences_array;
195+
189196
TokenPtr m_read_token{nullptr, scitoken_destroy};
190197
};
191198

@@ -354,11 +361,7 @@ TEST_F(SerializeTest, EnforcerTest) {
354361
"https://demo.scitokens.org/", &err_msg);
355362
ASSERT_TRUE(rv == 0);
356363

357-
std::vector<const char *> audiences_array;
358-
audiences_array.push_back("https://demo.scitokens.org/");
359-
audiences_array.push_back(nullptr);
360-
361-
auto enforcer = enforcer_create("https://demo.scitokens.org/gtest", &audiences_array[0], &err_msg);
364+
auto enforcer = enforcer_create("https://demo.scitokens.org/gtest", &m_audiences_array[0], &err_msg);
362365
ASSERT_TRUE(enforcer != nullptr);
363366

364367
Acl acl;
@@ -394,11 +397,7 @@ TEST_F(SerializeTest, EnforcerScopeTest) {
394397
"https://demo.scitokens.org/", &err_msg);
395398
ASSERT_TRUE(rv == 0);
396399

397-
std::vector<const char *> audiences_array;
398-
audiences_array.push_back("https://demo.scitokens.org/");
399-
audiences_array.push_back(nullptr);
400-
401-
auto enforcer = enforcer_create("https://demo.scitokens.org/gtest", &audiences_array[0], &err_msg);
400+
auto enforcer = enforcer_create("https://demo.scitokens.org/gtest", &m_audiences_array[0], &err_msg);
402401
ASSERT_TRUE(enforcer != nullptr);
403402

404403
scitoken_set_serialize_profile(m_token.get(), SciTokenProfile::WLCG_1_0);
@@ -433,10 +432,46 @@ TEST_F(SerializeTest, EnforcerScopeTest) {
433432
}
434433
ASSERT_TRUE(found_read);
435434
ASSERT_TRUE(found_write);
435+
}
436+
437+
TEST_F(SerializeTest, ExplicitTime) {
438+
time_t now = time(NULL);
439+
char *err_msg;
440+
441+
scitoken_set_serialize_profile(m_token.get(), SciTokenProfile::WLCG_1_0);
442+
auto rv = scitoken_set_claim_string(m_token.get(), "scope",
443+
"storage.read:/", &err_msg);
444+
445+
char *token_value = nullptr;
446+
rv = scitoken_serialize(m_token.get(), &token_value, &err_msg);
447+
ASSERT_TRUE(rv == 0);
436448

449+
rv = scitoken_deserialize_v2(token_value, m_read_token.get(), nullptr, &err_msg);
450+
ASSERT_TRUE(rv == 0);
437451

452+
auto enforcer = enforcer_create("https://demo.scitokens.org/gtest", &m_audiences_array[0], &err_msg);
453+
ASSERT_TRUE(enforcer != nullptr);
454+
Acl *acls;
455+
rv = enforcer_generate_acls(enforcer, m_read_token.get(), &acls, &err_msg);
456+
if (rv) {
457+
printf("Failure when generating ACLs: %s\n", err_msg);
458+
}
459+
ASSERT_TRUE(rv == 0);
460+
ASSERT_TRUE(acls != nullptr);
461+
462+
enforcer_set_time(enforcer, time(NULL), &err_msg);
463+
rv = enforcer_generate_acls(enforcer, m_read_token.get(), &acls, &err_msg);
464+
ASSERT_TRUE(rv == 0);
438465

466+
enforcer_set_time(enforcer, time(NULL) + 100, &err_msg);
467+
rv = enforcer_generate_acls(enforcer, m_read_token.get(), &acls, &err_msg);
468+
ASSERT_FALSE(rv == 0);
469+
470+
enforcer_set_time(enforcer, time(NULL) - 100, &err_msg);
471+
rv = enforcer_generate_acls(enforcer, m_read_token.get(), &acls, &err_msg);
472+
ASSERT_FALSE(rv == 0);
439473

474+
enforcer_destroy(enforcer);
440475
}
441476

442477
}

0 commit comments

Comments
 (0)