Merge pull request #7738 from sfc-gh-mpilman/bugfixes/investigate-token-cache-segfaults

fix token cache unit test
This commit is contained in:
Markus Pilman 2022-07-29 13:55:51 -06:00 committed by GitHub
commit 50fd0f11dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 9 deletions

View File

@ -13,6 +13,8 @@
#include <list> #include <list>
#include <deque> #include <deque>
#include "flow/actorcompiler.h" // has to be last include
template <class Key, class Value> template <class Key, class Value>
class LRUCache { class LRUCache {
public: public:
@ -156,6 +158,7 @@ bool TokenCache::validate(TenantNameRef name, StringRef token) {
TraceEvent(SevWarn, "InvalidToken") \ TraceEvent(SevWarn, "InvalidToken") \
.detail("From", peer) \ .detail("From", peer) \
.detail("Reason", reason) \ .detail("Reason", reason) \
.detail("CurrentTime", currentTime) \
.detail("Token", token.toStringRef(arena).toStringView()) .detail("Token", token.toStringRef(arena).toStringView())
bool TokenCacheImpl::validateAndAdd(double currentTime, StringRef token, NetworkAddress const& peer) { bool TokenCacheImpl::validateAndAdd(double currentTime, StringRef token, NetworkAddress const& peer) {
@ -324,23 +327,25 @@ TEST_CASE("/fdbrpc/authz/TokenCache/BadTokens") {
TEST_CASE("/fdbrpc/authz/TokenCache/GoodTokens") { TEST_CASE("/fdbrpc/authz/TokenCache/GoodTokens") {
// Don't repeat because token expiry is at seconds granularity and sleeps are costly in unit tests // Don't repeat because token expiry is at seconds granularity and sleeps are costly in unit tests
auto arena = Arena(); state Arena arena;
auto privateKey = mkcert::makeEcP256(); state PrivateKey privateKey = mkcert::makeEcP256();
auto const pubKeyName = "somePublicKey"_sr; state StringRef pubKeyName = "somePublicKey"_sr;
state ScopeExit<std::function<void()>> publicKeyClearGuard(
[pubKeyName = pubKeyName]() { FlowTransport::transport().removePublicKey(pubKeyName); });
state authz::jwt::TokenRef tokenSpec =
authz::jwt::makeRandomTokenSpec(arena, *deterministicRandom(), authz::Algorithm::ES256);
state StringRef signedToken;
FlowTransport::transport().addPublicKey(pubKeyName, privateKey.toPublic()); FlowTransport::transport().addPublicKey(pubKeyName, privateKey.toPublic());
auto publicKeyClearGuard = ScopeExit([pubKeyName]() { FlowTransport::transport().removePublicKey(pubKeyName); });
auto& rng = *deterministicRandom();
auto tokenSpec = authz::jwt::makeRandomTokenSpec(arena, rng, authz::Algorithm::ES256);
tokenSpec.expiresAtUnixTime = static_cast<uint64_t>(g_network->timer() + 2.0); tokenSpec.expiresAtUnixTime = static_cast<uint64_t>(g_network->timer() + 2.0);
tokenSpec.keyId = pubKeyName; tokenSpec.keyId = pubKeyName;
auto signedToken = authz::jwt::signToken(arena, tokenSpec, privateKey); signedToken = authz::jwt::signToken(arena, tokenSpec, privateKey);
if (!TokenCache::instance().validate(tokenSpec.tenants.get()[0], signedToken)) { if (!TokenCache::instance().validate(tokenSpec.tenants.get()[0], signedToken)) {
fmt::print("Unexpected failed token validation, token spec: {}, now: {}\n", fmt::print("Unexpected failed token validation, token spec: {}, now: {}\n",
tokenSpec.toStringRef(arena).toStringView(), tokenSpec.toStringRef(arena).toStringView(),
g_network->timer()); g_network->timer());
ASSERT(false); ASSERT(false);
} }
threadSleep(3.5); wait(delay(3.5));
if (TokenCache::instance().validate(tokenSpec.tenants.get()[0], signedToken)) { if (TokenCache::instance().validate(tokenSpec.tenants.get()[0], signedToken)) {
fmt::print( fmt::print(
"Unexpected successful token validation after supposedly expiring in cache, token spec: {}, now: {}\n", "Unexpected successful token validation after supposedly expiring in cache, token spec: {}, now: {}\n",

View File

@ -460,7 +460,7 @@ TokenRef makeRandomTokenSpec(Arena& arena, IRandom& rng, Algorithm alg) {
for (auto i = 0; i < numAudience; i++) for (auto i = 0; i < numAudience; i++)
aud[i] = genRandomAlphanumStringRef(arena, rng, MaxTenantNameLenPlus1); aud[i] = genRandomAlphanumStringRef(arena, rng, MaxTenantNameLenPlus1);
ret.audience = VectorRef<StringRef>(aud, numAudience); ret.audience = VectorRef<StringRef>(aud, numAudience);
ret.issuedAtUnixTime = timer_int() / 1'000'000'000ul; ret.issuedAtUnixTime = uint64_t(std::floor(g_network->timer()));
ret.notBeforeUnixTime = ret.issuedAtUnixTime.get(); ret.notBeforeUnixTime = ret.issuedAtUnixTime.get();
ret.expiresAtUnixTime = ret.issuedAtUnixTime.get() + rng.randomInt(360, 1080 + 1); ret.expiresAtUnixTime = ret.issuedAtUnixTime.get() + rng.randomInt(360, 1080 + 1);
auto numTenants = rng.randomInt(1, 3); auto numTenants = rng.randomInt(1, 3);