Merge pull request #8125 from sfc-gh-jshim/knob-tokenless-tenant-access
Add a knob to allow token-less tenant data access for untrusted clients
This commit is contained in:
commit
bc47f90aff
|
@ -26,6 +26,7 @@
|
|||
#include "fdbrpc/TokenCache.h"
|
||||
#include "fdbrpc/FlowTransport.h"
|
||||
#include "flow/Arena.h"
|
||||
#include "flow/Knobs.h"
|
||||
|
||||
struct TenantInfo {
|
||||
static constexpr const int64_t INVALID_TENANT = -1;
|
||||
|
@ -69,8 +70,8 @@ struct serializable_traits<TenantInfo> : std::true_type {
|
|||
static void serialize(Archiver& ar, TenantInfo& v) {
|
||||
serializer(ar, v.name, v.tenantId, v.token, v.arena);
|
||||
if constexpr (Archiver::isDeserializing) {
|
||||
bool tenantAuthorized = false;
|
||||
if (v.name.present() && v.token.present()) {
|
||||
bool tenantAuthorized = FLOW_KNOBS->ALLOW_TOKENLESS_TENANT_ACCESS;
|
||||
if (!tenantAuthorized && v.name.present() && v.token.present()) {
|
||||
tenantAuthorized = TokenCache::instance().validate(v.name.get(), v.token.get());
|
||||
}
|
||||
v.trusted = FlowTransport::transport().currentDeliveryPeerIsTrusted();
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <array>
|
||||
|
||||
#include "flow/Knobs.h"
|
||||
#include "fdbclient/Knobs.h"
|
||||
#include "fdbclient/ServerKnobCollection.h"
|
||||
#include "fdbserver/Knobs.h"
|
||||
|
@ -52,6 +53,9 @@ void KnobProtectiveGroup::snapshotOriginalKnobs() {
|
|||
if (std::get_if<NoKnobFound>(&value)) {
|
||||
value = SERVER_KNOBS->getKnob(name);
|
||||
}
|
||||
if (std::get_if<NoKnobFound>(&value)) {
|
||||
value = FLOW_KNOBS->getKnob(name);
|
||||
}
|
||||
if (std::get_if<NoKnobFound>(&value)) {
|
||||
ASSERT(false);
|
||||
}
|
||||
|
@ -70,4 +74,4 @@ void KnobProtectiveGroup::assignKnobs(const KnobKeyValuePairs& overrideKnobs) {
|
|||
ASSERT(mutableServerKnobs.trySetKnob(name, valueRef));
|
||||
TraceEvent(SevInfo, "AssignKnobValue").detail("KnobName", name).detail("KnobValue", valueRef.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ template <class T>
|
|||
struct sfinae_true : std::true_type {};
|
||||
|
||||
template <class T>
|
||||
auto testAuthToken(int) -> sfinae_true<decltype(std::declval<T>().getAuthToken())>;
|
||||
auto testAuthToken(int) -> sfinae_true<decltype(std::declval<T>().setAuthToken(std::declval<Transaction&>()))>;
|
||||
template <class>
|
||||
auto testAuthToken(long) -> std::false_type;
|
||||
|
||||
|
@ -53,7 +53,7 @@ struct hasAuthToken : decltype(testAuthToken<T>(0)) {};
|
|||
template <class T>
|
||||
void setAuthToken(T const& self, Transaction& tr) {
|
||||
if constexpr (hasAuthToken<T>::value) {
|
||||
tr.setOption(FDBTransactionOptions::AUTHORIZATION_TOKEN, self.getAuthToken());
|
||||
self.setAuthToken(tr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1418,6 +1418,9 @@ KnobKeyValuePairs getOverriddenKnobKeyValues(const toml::value& context) {
|
|||
if (std::get_if<NoKnobFound>(&parsedValue)) {
|
||||
parsedValue = SERVER_KNOBS->parseKnobValue(key, value);
|
||||
}
|
||||
if (std::get_if<NoKnobFound>(&parsedValue)) {
|
||||
parsedValue = FLOW_KNOBS->parseKnobValue(key, value);
|
||||
}
|
||||
if (std::get_if<NoKnobFound>(&parsedValue)) {
|
||||
TraceEvent(SevError, "TestSpecUnrecognizedKnob")
|
||||
.detail("KnobName", key)
|
||||
|
|
|
@ -43,6 +43,7 @@ struct CycleMembers<true> {
|
|||
TenantName tenant;
|
||||
authz::jwt::TokenRef token;
|
||||
StringRef signedToken;
|
||||
bool useToken;
|
||||
};
|
||||
|
||||
template <bool MultiTenancy>
|
||||
|
@ -67,6 +68,7 @@ struct CycleWorkload : TestWorkload, CycleMembers<MultiTenancy> {
|
|||
minExpectedTransactionsPerSecond = transactionsPerSecond * getOption(options, "expectedRate"_sr, 0.7);
|
||||
if constexpr (MultiTenancy) {
|
||||
ASSERT(g_network->isSimulated());
|
||||
this->useToken = getOption(options, "useToken"_sr, true);
|
||||
auto k = g_simulator.authKeys.begin();
|
||||
this->tenant = getOption(options, "tenant"_sr, "CycleTenant"_sr);
|
||||
// make it comfortably longer than the timeout of the workload
|
||||
|
@ -85,11 +87,6 @@ struct CycleWorkload : TestWorkload, CycleMembers<MultiTenancy> {
|
|||
}
|
||||
}
|
||||
|
||||
template <bool MT = MultiTenancy>
|
||||
std::enable_if_t<MT, StringRef> getAuthToken() const {
|
||||
return this->signedToken;
|
||||
}
|
||||
|
||||
std::string description() const override {
|
||||
if constexpr (MultiTenancy) {
|
||||
return "TenantCycleWorkload";
|
||||
|
@ -151,12 +148,13 @@ struct CycleWorkload : TestWorkload, CycleMembers<MultiTenancy> {
|
|||
}
|
||||
|
||||
template <bool B = MultiTenancy>
|
||||
std::enable_if_t<B> setAuthToken(Transaction& tr) {
|
||||
tr.setOption(FDBTransactionOptions::AUTHORIZATION_TOKEN, this->signedToken);
|
||||
std::enable_if_t<B> setAuthToken(Transaction& tr) const {
|
||||
if (this->useToken)
|
||||
tr.setOption(FDBTransactionOptions::AUTHORIZATION_TOKEN, this->signedToken);
|
||||
}
|
||||
|
||||
template <bool B = MultiTenancy>
|
||||
std::enable_if_t<!B> setAuthToken(Transaction& tr) {}
|
||||
std::enable_if_t<!B> setAuthToken(Transaction& tr) const {}
|
||||
|
||||
ACTOR Future<Void> cycleClient(Database cx, CycleWorkload* self, double delay) {
|
||||
state double lastTime = now();
|
||||
|
|
|
@ -131,6 +131,7 @@ void FlowKnobs::initialize(Randomize randomize, IsSimulated isSimulated) {
|
|||
init( NETWORK_TEST_SCRIPT_MODE, false );
|
||||
|
||||
//Authorization
|
||||
init( ALLOW_TOKENLESS_TENANT_ACCESS, false );
|
||||
init( PUBLIC_KEY_FILE_MAX_SIZE, 1024 * 1024 );
|
||||
init( PUBLIC_KEY_FILE_REFRESH_INTERVAL_SECONDS, 30 );
|
||||
init( MAX_CACHED_EXPIRED_TOKENS, 1024 );
|
||||
|
|
|
@ -196,6 +196,7 @@ public:
|
|||
bool NETWORK_TEST_SCRIPT_MODE;
|
||||
|
||||
// Authorization
|
||||
bool ALLOW_TOKENLESS_TENANT_ACCESS;
|
||||
int PUBLIC_KEY_FILE_MAX_SIZE;
|
||||
int PUBLIC_KEY_FILE_REFRESH_INTERVAL_SECONDS;
|
||||
int MAX_CACHED_EXPIRED_TOKENS;
|
||||
|
|
|
@ -184,6 +184,7 @@ if(WITH_PYTHON)
|
|||
add_fdb_test(TEST_FILES fast/SystemRebootTestCycle.toml)
|
||||
add_fdb_test(TEST_FILES fast/TaskBucketCorrectness.toml)
|
||||
add_fdb_test(TEST_FILES fast/TenantCycle.toml)
|
||||
add_fdb_test(TEST_FILES fast/TenantCycleTokenless.toml)
|
||||
add_fdb_test(TEST_FILES fast/TenantEntryCache.toml)
|
||||
add_fdb_test(TEST_FILES fast/TimeKeeperCorrectness.toml)
|
||||
add_fdb_test(TEST_FILES fast/TxnStateStoreCycleTest.toml)
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
[configuration]
|
||||
allowDefaultTenant = false
|
||||
allowDisablingTenants = false
|
||||
|
||||
[[knobs]]
|
||||
allow_tokenless_tenant_access = true
|
||||
|
||||
[[test]]
|
||||
testTitle = 'TenantCreation'
|
||||
|
||||
[[test.workload]]
|
||||
testName = 'CreateTenant'
|
||||
name = 'First'
|
||||
|
||||
[[test.workload]]
|
||||
testName = 'CreateTenant'
|
||||
name = 'Second'
|
||||
|
||||
[[test]]
|
||||
testTitle = 'Cycle'
|
||||
|
||||
[[test.workload]]
|
||||
testName = 'TenantCycle'
|
||||
tenant = 'First'
|
||||
transactionsPerSecond = 250.0
|
||||
testDuration = 10.0
|
||||
expectedRate = 0.80
|
||||
useToken = false
|
||||
|
||||
[[test.workload]]
|
||||
testName = 'TenantCycle'
|
||||
tenant = 'Second'
|
||||
transactionsPerSecond = 2500.0
|
||||
testDuration = 10.0
|
||||
expectedRate = 0.80
|
||||
useToken = false
|
Loading…
Reference in New Issue