Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow the library user to explicitly set the "current" time. #98

Merged
merged 2 commits into from
Oct 19, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/scitokens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,18 @@ int validator_validate(Validator validator, SciToken scitoken, char **err_msg) {
}


int validator_set_time(Validator validator, time_t now, char **err_msg) {
if (validator == nullptr) {
if (err_msg) {*err_msg = strdup("Validator may not be a null pointer");}
return -1;
}
auto real_validator = reinterpret_cast<scitokens::Validator*>(validator);

real_validator->set_now(std::chrono::system_clock::from_time_t(now));

return 0;
}

Enforcer enforcer_create(const char *issuer, const char **audience_list, char **err_msg) {
if (issuer == nullptr) {
if (err_msg) {*err_msg = strdup("Issuer may not be a null pointer");}
Expand Down Expand Up @@ -388,6 +400,19 @@ void enforcer_set_validate_profile(Enforcer enf, SciTokenProfile profile) {
}


int enforcer_set_time(Enforcer enf, time_t now, char **err_msg) {
if (enf == nullptr) {
if (err_msg) {*err_msg = strdup("Enforcer may not be a null pointer");}
return -1;
}
auto real_enf = reinterpret_cast<scitokens::Enforcer*>(enf);

real_enf->set_now(std::chrono::system_clock::from_time_t(now));

return 0;
}


int enforcer_generate_acls(const Enforcer enf, const SciToken scitoken, Acl **acls, char **err_msg) {
if (enf == nullptr) {
if (err_msg) {*err_msg = strdup("Enforcer may not be a null pointer");}
Expand Down
15 changes: 15 additions & 0 deletions src/scitokens.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
*/

#ifdef __cplusplus
#include <ctime>
extern "C" {
#else
#include <time.h>
#endif

typedef void * SciTokenKey;
Expand Down Expand Up @@ -100,6 +103,12 @@ Validator validator_create();
*/
void validator_set_token_profile(Validator, SciTokenProfile profile);

/**
* Set the time to use with the validator. Useful if you want to see if the token would
* have been valid at some time in the past.
*/
int validator_set_time(Validator validator, time_t now, char **err_msg);

int validator_add(Validator validator, const char *claim, StringValidatorFunction validator_func, char **err_msg);

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

/**
* Set the time to use with the enforcer. Useful if you want to see if the token would
* have been valid at some time in the past.
*/
int enforcer_set_time(Enforcer enf, time_t now, char **err_msg);

int enforcer_generate_acls(const Enforcer enf, const SciToken scitokens, Acl **acls, char **err_msg);

void enforcer_acl_free(Acl *acls);
Expand Down
20 changes: 19 additions & 1 deletion src/scitokens_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@
#include <jwt-cpp/jwt.h>
#include <uuid/uuid.h>

namespace {

struct FixedClock {
jwt::date m_now;
jwt::date now() const {return m_now;}
};

}

namespace jwt {
template<typename json_traits>
class decoded_jwt;
Expand Down Expand Up @@ -267,6 +276,10 @@ class Validator {
typedef std::map<std::string, std::vector<std::pair<ClaimValidatorFunction, void*>>> ClaimValidatorMap;

public:
Validator() : m_now(std::chrono::system_clock::now()) {}

void set_now(std::chrono::system_clock::time_point now) {m_now = now;}

void verify(const SciToken &scitoken) {
const jwt::decoded_jwt<jwt::traits::kazuho_picojson> *jwt_decoded = scitoken.m_decoded.get();
if (!jwt_decoded) {
Expand Down Expand Up @@ -343,7 +356,8 @@ class Validator {
get_public_key_pem(jwt.get_issuer(), key_id, public_pem, algorithm);
// std::cout << "Public PEM: " << public_pem << std::endl << "Algorithm: " << algorithm << std::endl;
SciTokenKey key(key_id, algorithm, public_pem, "");
auto verifier = jwt::verify()

auto verifier = jwt::verify<FixedClock, jwt::traits::kazuho_picojson>({m_now})
.allow_algorithm(key);

verifier.verify(jwt);
Expand Down Expand Up @@ -528,6 +542,8 @@ class Validator {
ClaimStringValidatorMap m_validators;
ClaimValidatorMap m_claim_validators;

std::chrono::system_clock::time_point m_now;

std::vector<std::string> m_critical_claims;
std::vector<std::string> m_allowed_issuers;
};
Expand Down Expand Up @@ -556,6 +572,8 @@ class Enforcer {
m_validator.add_critical_claims(critical_claims);
}

void set_now(std::chrono::system_clock::time_point now) {m_validator.set_now(now);}

void set_validate_profile(SciToken::Profile profile) {
m_validate_profile = profile;
}
Expand Down
57 changes: 47 additions & 10 deletions test/main.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "../src/scitokens.h"

#include <memory>

#include <gtest/gtest.h>

namespace {
Expand Down Expand Up @@ -77,6 +79,11 @@ class SerializeTest : public ::testing::Test {
"1", ec_public, &err_msg);
ASSERT_TRUE(rv == 0);

scitoken_set_lifetime(m_token.get(), 60);

m_audiences_array.push_back("https://demo.scitokens.org/");
m_audiences_array.push_back(nullptr);

const char *groups[3] = {nullptr, nullptr, nullptr};
const char group0[] = "group0";
const char group1[] = "group1";
Expand All @@ -96,6 +103,8 @@ class SerializeTest : public ::testing::Test {
using TokenPtr = std::unique_ptr<void, decltype(&scitoken_destroy)>;
TokenPtr m_token{nullptr, scitoken_destroy};

std::vector<const char *> m_audiences_array;

TokenPtr m_read_token{nullptr, scitoken_destroy};
};

Expand Down Expand Up @@ -264,11 +273,7 @@ TEST_F(SerializeTest, EnforcerTest) {
"https://demo.scitokens.org/", &err_msg);
ASSERT_TRUE(rv == 0);

std::vector<const char *> audiences_array;
audiences_array.push_back("https://demo.scitokens.org/");
audiences_array.push_back(nullptr);

auto enforcer = enforcer_create("https://demo.scitokens.org/gtest", &audiences_array[0], &err_msg);
auto enforcer = enforcer_create("https://demo.scitokens.org/gtest", &m_audiences_array[0], &err_msg);
ASSERT_TRUE(enforcer != nullptr);

Acl acl;
Expand Down Expand Up @@ -304,11 +309,7 @@ TEST_F(SerializeTest, EnforcerScopeTest) {
"https://demo.scitokens.org/", &err_msg);
ASSERT_TRUE(rv == 0);

std::vector<const char *> audiences_array;
audiences_array.push_back("https://demo.scitokens.org/");
audiences_array.push_back(nullptr);

auto enforcer = enforcer_create("https://demo.scitokens.org/gtest", &audiences_array[0], &err_msg);
auto enforcer = enforcer_create("https://demo.scitokens.org/gtest", &m_audiences_array[0], &err_msg);
ASSERT_TRUE(enforcer != nullptr);

scitoken_set_serialize_profile(m_token.get(), SciTokenProfile::WLCG_1_0);
Expand Down Expand Up @@ -343,10 +344,46 @@ TEST_F(SerializeTest, EnforcerScopeTest) {
}
ASSERT_TRUE(found_read);
ASSERT_TRUE(found_write);
}

TEST_F(SerializeTest, ExplicitTime) {
time_t now = time(NULL);
char *err_msg;

scitoken_set_serialize_profile(m_token.get(), SciTokenProfile::WLCG_1_0);
auto rv = scitoken_set_claim_string(m_token.get(), "scope",
"storage.read:/", &err_msg);

char *token_value = nullptr;
rv = scitoken_serialize(m_token.get(), &token_value, &err_msg);
ASSERT_TRUE(rv == 0);

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

auto enforcer = enforcer_create("https://demo.scitokens.org/gtest", &m_audiences_array[0], &err_msg);
ASSERT_TRUE(enforcer != nullptr);
Acl *acls;
rv = enforcer_generate_acls(enforcer, m_read_token.get(), &acls, &err_msg);
if (rv) {
printf("Failure when generating ACLs: %s\n", err_msg);
}
ASSERT_TRUE(rv == 0);
ASSERT_TRUE(acls != nullptr);

enforcer_set_time(enforcer, time(NULL), &err_msg);
rv = enforcer_generate_acls(enforcer, m_read_token.get(), &acls, &err_msg);
ASSERT_TRUE(rv == 0);

enforcer_set_time(enforcer, time(NULL) + 100, &err_msg);
rv = enforcer_generate_acls(enforcer, m_read_token.get(), &acls, &err_msg);
ASSERT_FALSE(rv == 0);

enforcer_set_time(enforcer, time(NULL) - 100, &err_msg);
rv = enforcer_generate_acls(enforcer, m_read_token.get(), &acls, &err_msg);
ASSERT_FALSE(rv == 0);

enforcer_destroy(enforcer);
}

}
Expand Down