bool PluginRootContext::parsePluginConfig()

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;
}