Skip to content

Commit 6d2490a

Browse files
authored
Merge pull request #92 from bbockelm/scitokens_async
First attempt at an async refactoring of the SciTokens library.
2 parents aec994e + 28c6784 commit 6d2490a

File tree

5 files changed

+919
-160
lines changed

5 files changed

+919
-160
lines changed

src/scitokens.cpp

Lines changed: 272 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,84 @@ int scitoken_deserialize_v2(const char *value, SciToken token, char const* const
255255
return 0;
256256
}
257257

258+
int scitoken_deserialize_start(const char *value, SciToken *token, char const* const* allowed_issuers, SciTokenStatus *status_out, char **err_msg) {
259+
if (value == nullptr) {
260+
if (err_msg) {*err_msg = strdup("Token may not be NULL");}
261+
return -1;
262+
}
263+
if (token == nullptr) {
264+
if (err_msg) {*err_msg = strdup("Output token not provided");}
265+
return -1;
266+
}
267+
268+
scitokens::SciTokenKey key;
269+
scitokens::SciToken *real_token = new scitokens::SciToken(key);
270+
271+
272+
std::vector<std::string> allowed_issuers_vec;
273+
if (allowed_issuers != nullptr) {
274+
for (int idx=0; allowed_issuers[idx]; idx++) {
275+
allowed_issuers_vec.push_back(allowed_issuers[idx]);
276+
}
277+
}
278+
279+
std::unique_ptr<scitokens::SciTokenAsyncStatus> status;
280+
try {
281+
status = real_token->deserialize_start(value, allowed_issuers_vec);
282+
} catch (std::exception &exc) {
283+
if (err_msg) {
284+
*err_msg = strdup(exc.what());
285+
}
286+
delete real_token;
287+
*status_out = nullptr;
288+
return -1;
289+
}
290+
291+
// Check if we're done
292+
if (status->m_status->m_done) {
293+
*token = real_token;
294+
*status_out = nullptr;
295+
return 0;
296+
}
297+
298+
*token = real_token;
299+
*status_out = status.release();
300+
return 0;
301+
}
302+
303+
int scitoken_deserialize_continue(SciToken *token, SciTokenStatus *status, char **err_msg) {
304+
if (token == nullptr) {
305+
if (err_msg) {*err_msg = strdup("Output token not provided");}
306+
return -1;
307+
}
308+
309+
310+
scitokens::SciToken *real_token = reinterpret_cast<scitokens::SciToken*>(token);
311+
std::unique_ptr<scitokens::SciTokenAsyncStatus> real_status(reinterpret_cast<scitokens::SciTokenAsyncStatus*>(*status));
312+
313+
if (*status == nullptr || real_status->m_status->m_done) {
314+
*status = nullptr;
315+
return 0;
316+
}
317+
318+
try {
319+
real_status = real_token->deserialize_continue(std::move(real_status));
320+
} catch (std::exception &exc) {
321+
*status = nullptr;
322+
if (err_msg) {
323+
*err_msg = strdup(exc.what());
324+
}
325+
return -1;
326+
}
327+
328+
if (real_status->m_status->m_done) {
329+
*status = nullptr;
330+
} else {
331+
*status = real_status.release();
332+
}
333+
return 0;
334+
}
335+
258336
int scitoken_store_public_ec_key(const char *issuer, const char *keyid, const char *key, char **err_msg)
259337
{
260338
bool success;
@@ -338,7 +416,7 @@ int validator_validate(Validator validator, SciToken scitoken, char **err_msg) {
338416
auto real_scitoken = reinterpret_cast<scitokens::SciToken*>(scitoken);
339417

340418
try {
341-
real_validator->verify(*real_scitoken);
419+
real_validator->verify(*real_scitoken, time(NULL) + 20);
342420
} catch (std::exception &exc) {
343421
if (err_msg) {*err_msg = strdup(exc.what());}
344422
return -1;
@@ -400,6 +478,34 @@ void enforcer_set_validate_profile(Enforcer enf, SciTokenProfile profile) {
400478
}
401479

402480

481+
namespace {
482+
483+
Acl *convert_acls(scitokens::Enforcer::AclsList &acls_list, char **err_msg)
484+
{
485+
Acl *acl_result = static_cast<Acl*>(malloc((acls_list.size() + 1)*sizeof(Acl)));
486+
size_t idx = 0;
487+
for (const auto &acl : acls_list) {
488+
acl_result[idx].authz = strdup(acl.first.c_str());
489+
acl_result[idx].resource = strdup(acl.second.c_str());
490+
if (acl_result[idx].authz == nullptr) {
491+
enforcer_acl_free(acl_result);
492+
if (err_msg) {*err_msg = strdup("ACL was generated without an authorization set.");}
493+
return nullptr;
494+
}
495+
if (acl_result[idx].resource == nullptr) {
496+
enforcer_acl_free(acl_result);
497+
if (err_msg) {*err_msg = strdup("ACL was generated without a resource set.");}
498+
return nullptr;
499+
}
500+
idx++;
501+
}
502+
acl_result[idx].authz = nullptr;
503+
acl_result[idx].resource = nullptr;
504+
return acl_result;
505+
}
506+
507+
}
508+
403509
int enforcer_set_time(Enforcer enf, time_t now, char **err_msg) {
404510
if (enf == nullptr) {
405511
if (err_msg) {*err_msg = strdup("Enforcer may not be a null pointer");}
@@ -432,26 +538,78 @@ int enforcer_generate_acls(const Enforcer enf, const SciToken scitoken, Acl **ac
432538
if (err_msg) {*err_msg = strdup(exc.what());}
433539
return -1;
434540
}
435-
Acl *acl_result = static_cast<Acl*>(malloc((acls_list.size() + 1)*sizeof(Acl)));
436-
size_t idx = 0;
437-
for (const auto &acl : acls_list) {
438-
acl_result[idx].authz = strdup(acl.first.c_str());
439-
acl_result[idx].resource = strdup(acl.second.c_str());
440-
if (acl_result[idx].authz == nullptr) {
441-
enforcer_acl_free(acl_result);
442-
if (err_msg) {*err_msg = strdup("ACL was generated without an authorization set.");}
443-
return -1;
444-
}
445-
if (acl_result[idx].resource == nullptr) {
446-
enforcer_acl_free(acl_result);
447-
if (err_msg) {*err_msg = strdup("ACL was generated without a resource set.");}
448-
return -1;
449-
}
450-
idx++;
541+
auto result_acls = convert_acls(acls_list, err_msg);
542+
if (!result_acls) {return -1;}
543+
*acls = result_acls;
544+
return 0;
545+
}
546+
547+
548+
int enforcer_generate_acls_start(const Enforcer enf, const SciToken scitoken,
549+
SciTokenStatus *status_out, Acl **acls, char **err_msg)
550+
{
551+
if (enf == nullptr) {
552+
if (err_msg) {*err_msg = strdup("Enforcer may not be a null pointer");}
553+
return -1;
451554
}
452-
acl_result[idx].authz = nullptr;
453-
acl_result[idx].resource = nullptr;
454-
*acls = acl_result;
555+
auto real_enf = reinterpret_cast<scitokens::Enforcer*>(enf);
556+
if (scitoken == nullptr) {
557+
if (err_msg) {*err_msg = strdup("SciToken may not be a null pointer");}
558+
return -1;
559+
}
560+
auto real_scitoken = reinterpret_cast<scitokens::SciToken*>(scitoken);
561+
562+
scitokens::Enforcer::AclsList acls_list;
563+
std::unique_ptr<scitokens::AsyncStatus> status;
564+
try {
565+
status = real_enf->generate_acls_start(*real_scitoken, acls_list);
566+
} catch (std::exception &exc) {
567+
if (err_msg) {*err_msg = strdup(exc.what());}
568+
return -1;
569+
}
570+
if (status->m_done) {
571+
auto result_acls = convert_acls(acls_list, err_msg);
572+
if (!result_acls) {return -1;}
573+
*acls = result_acls;
574+
*status_out = nullptr;
575+
return 0;
576+
}
577+
*status_out = status.release();
578+
return 0;
579+
}
580+
581+
582+
int enforcer_generate_acls_continue(const Enforcer enf, SciTokenStatus *status,
583+
Acl **acls, char **err_msg)
584+
{
585+
if (enf == nullptr) {
586+
if (err_msg) {*err_msg = strdup("Enforcer may not be a null pointer");}
587+
return -1;
588+
}
589+
auto real_enf = reinterpret_cast<scitokens::Enforcer*>(enf);
590+
if (status == nullptr) {
591+
if (err_msg) {*err_msg = strdup("Status may not be a null pointer");}
592+
return -1;
593+
}
594+
595+
scitokens::Enforcer::AclsList acls_list;
596+
std::unique_ptr<scitokens::AsyncStatus> status_internal(
597+
reinterpret_cast<scitokens::AsyncStatus*>(*status));
598+
try {
599+
status_internal = real_enf->generate_acls_continue(std::move(status_internal), acls_list);
600+
} catch (std::exception &exc) {
601+
*status = nullptr;
602+
if (err_msg) {*err_msg = strdup(exc.what());}
603+
return -1;
604+
}
605+
if (status_internal->m_done) {
606+
auto result_acls = convert_acls(acls_list, err_msg);
607+
if (!result_acls) {return -1;}
608+
*acls = result_acls;
609+
*status = nullptr;
610+
return 0;
611+
}
612+
*status = status_internal.release();
455613
return 0;
456614
}
457615

@@ -482,6 +640,99 @@ int enforcer_test(const Enforcer enf, const SciToken scitoken, const Acl *acl, c
482640
}
483641

484642

643+
void scitoken_status_free(SciTokenStatus status) {
644+
std::unique_ptr<scitokens::AsyncStatus> status_real(
645+
reinterpret_cast<scitokens::AsyncStatus*>(status));
646+
}
647+
648+
649+
int scitoken_status_get_timeout_val(const SciTokenStatus *status, time_t expiry_time, struct timeval *timeout, char **err_msg)
650+
{
651+
if (status == nullptr) {
652+
if (err_msg) {*err_msg = strdup("Status object may not be a null pointer");}
653+
return -1;
654+
}
655+
if (timeout == nullptr) {
656+
if (err_msg) {*err_msg = strdup("Timeout object may not be a null pointer");}
657+
return -1;
658+
}
659+
660+
auto real_status = reinterpret_cast<const scitokens::AsyncStatus*>(status);
661+
struct timeval timeout_internal = real_status->get_timeout_val(expiry_time);
662+
timeout->tv_sec = timeout_internal.tv_sec;
663+
timeout->tv_usec = timeout_internal.tv_usec;
664+
return 0;
665+
}
666+
667+
668+
int scitoken_status_get_read_fd_set(SciTokenStatus *status, fd_set **read_fd_set, char **err_msg)
669+
{
670+
if (status == nullptr) {
671+
if (err_msg) {*err_msg = strdup("Status object may not be a null pointer");}
672+
return -1;
673+
}
674+
if (read_fd_set == nullptr) {
675+
if (err_msg) {*err_msg = strdup("Read fd_set object may not be a null pointer");}
676+
return -1;
677+
}
678+
679+
auto real_status = reinterpret_cast<scitokens::AsyncStatus*>(status);
680+
*read_fd_set = real_status->get_read_fd_set();
681+
return 0;
682+
}
683+
684+
685+
int scitoken_status_get_write_fd_set(SciTokenStatus *status, fd_set **write_fd_set, char **err_msg)
686+
{
687+
if (status == nullptr) {
688+
if (err_msg) {*err_msg = strdup("Status object may not be a null pointer");}
689+
return -1;
690+
}
691+
if (write_fd_set == nullptr) {
692+
if (err_msg) {*err_msg = strdup("Write fd_set object may not be a null pointer");}
693+
return -1;
694+
}
695+
696+
auto real_status = reinterpret_cast<scitokens::AsyncStatus*>(status);
697+
*write_fd_set = real_status->get_write_fd_set();
698+
return 0;
699+
}
700+
701+
702+
int scitoken_status_get_exc_fd_set(SciTokenStatus *status, fd_set **exc_fd_set, char **err_msg)
703+
{
704+
if (status == nullptr) {
705+
if (err_msg) {*err_msg = strdup("Status object may not be a null pointer");}
706+
return -1;
707+
}
708+
if (exc_fd_set == nullptr) {
709+
if (err_msg) {*err_msg = strdup("Read fd_set object may not be a null pointer");}
710+
return -1;
711+
}
712+
713+
auto real_status = reinterpret_cast<scitokens::AsyncStatus*>(status);
714+
*exc_fd_set = real_status->get_exc_fd_set();
715+
return 0;
716+
}
717+
718+
719+
int scitoken_status_get_max_fd(const SciTokenStatus *status, int *max_fd, char **err_msg)
720+
{
721+
if (status == nullptr) {
722+
if (err_msg) {*err_msg = strdup("Status object may not be a null pointer");}
723+
return -1;
724+
}
725+
if (max_fd == nullptr) {
726+
if (err_msg) {*err_msg = strdup("Max FD may not be a null pointer");}
727+
return -1;
728+
}
729+
730+
auto real_status = reinterpret_cast<const scitokens::AsyncStatus*>(status);
731+
*max_fd = real_status->get_max_fd();
732+
return 0;
733+
}
734+
735+
485736
int keycache_refresh_jwks(const char *issuer, char **err_msg)
486737
{
487738
if (!issuer) {
@@ -542,3 +793,4 @@ int keycache_set_jwks(const char *issuer, const char *jwks, char **err_msg)
542793
}
543794
return 0;
544795
}
796+

0 commit comments

Comments
 (0)