in plugins/wasm-cpp/extensions/basic_auth/plugin.cc [80:189]
bool PluginRootContext::parsePluginConfig(const json& configuration,
BasicAuthConfigRule& rule) {
if ((configuration.find("consumers") != configuration.end()) &&
(configuration.find("credentials") != configuration.end())) {
LOG_WARN(
"The consumers field and the credentials field cannot appear at the "
"same level");
return false;
}
auto it = configuration.find("encrypted");
if (it != configuration.end()) {
auto passwd_encrypted = JsonValueAs<bool>(it.value());
if (passwd_encrypted.second != Wasm::Common::JsonParserResultDetail::OK) {
LOG_WARN("cannot parse passwd_encrypted");
return false;
}
rule.passwd_encrypted = passwd_encrypted.first.value();
}
// no consumer name
if (!JsonArrayIterate(
configuration, "credentials", [&](const json& credentials) -> bool {
auto credential = JsonValueAs<std::string>(credentials);
if (credential.second != Wasm::Common::JsonParserResultDetail::OK) {
LOG_WARN("credential cannot be parsed");
return false;
}
// Check if credential has `:` in it. If it has, it needs to be
// base64 encoded.
if (absl::StrContains(credential.first.value(), ":")) {
return addBasicAuthConfigRule(rule, credential.first.value(),
std::nullopt, false);
}
if (rule.passwd_encrypted) {
LOG_WARN("colon not found in encrypted credential");
return false;
}
// Otherwise, try base64 decode and insert into credential list if
// it can be decoded.
if (!Base64::decodeWithoutPadding(credential.first.value())
.empty()) {
return addBasicAuthConfigRule(rule, credential.first.value(),
std::nullopt, true);
}
return false;
})) {
LOG_WARN("failed to parse configuration for credentials.");
return false;
}
// with consumer name
if (!JsonArrayIterate(
configuration, "consumers", [&](const json& consumer) -> bool {
auto item = consumer.find("name");
if (item == consumer.end()) {
LOG_WARN("can't find 'name' field in consumer.");
return false;
}
auto name = JsonValueAs<std::string>(item.value());
if (name.second != Wasm::Common::JsonParserResultDetail::OK ||
!name.first) {
LOG_WARN("'name' cannot be parsed");
return false;
}
item = consumer.find("credential");
if (item == consumer.end()) {
LOG_WARN("can't find 'credential' field in consumer.");
return false;
}
auto credential = JsonValueAs<std::string>(item.value());
if (credential.second != Wasm::Common::JsonParserResultDetail::OK ||
!credential.first) {
LOG_WARN("field 'credential' cannot be parsed");
return false;
}
// Check if credential has `:` in it. If it has, it needs to be
// base64 encoded.
if (absl::StrContains(credential.first.value(), ":")) {
return addBasicAuthConfigRule(rule, credential.first.value(),
name.first, false);
}
if (rule.passwd_encrypted) {
LOG_WARN("colon not found in encrypted credential");
return false;
}
// Otherwise, try base64 decode and insert into credential list if
// it can be decoded.
if (!Base64::decodeWithoutPadding(credential.first.value())
.empty()) {
return addBasicAuthConfigRule(rule, credential.first.value(),
name.first, true);
}
return false;
})) {
LOG_WARN("failed to parse configuration for credentials.");
return false;
}
if (rule.encoded_credentials.empty() && rule.encrypted_credentials.empty()) {
LOG_INFO("at least one credential has to be configured for a rule.");
return false;
}
it = configuration.find("realm");
if (it != configuration.end()) {
auto realm_string = JsonValueAs<std::string>(it.value());
if (realm_string.second != Wasm::Common::JsonParserResultDetail::OK) {
LOG_WARN("cannot parse realm");
return false;
}
rule.realm = realm_string.first.value();
}
return true;
}