bool PluginRootContext::parsePluginConfig()

in plugins/wasm-cpp/extensions/jwt_auth/plugin.cc [83:250]


bool PluginRootContext::parsePluginConfig(const json& configuration,
                                          JwtAuthConfigRule& rule) {
  std::unordered_set<std::string> name_set;
  if (!JsonArrayIterate(
          configuration, "consumers", [&](const json& consumer) -> bool {
            Consumer c;
            JSON_FIND_FIELD(consumer, name);
            JSON_FIELD_VALUE_AS(std::string, consumer, name);
            if (name_set.count(consumer_name) != 0) {
              LOG_WARN("consumer already exists: " + consumer_name);
              return false;
            }
            c.name = consumer_name;
            JSON_FIND_FIELD(consumer, jwks);
            JSON_FIELD_VALUE_AS(std::string, consumer, jwks);
            c.jwks = google::jwt_verify::Jwks::createFrom(
                consumer_jwks, google::jwt_verify::Jwks::JWKS);
            if (c.jwks->getStatus() != Status::Ok) {
              LOG_WARN(absl::StrFormat(
                  "jwks is invalid, consumer:%s, status:%s, jwks:%s",
                  consumer_name,
                  google::jwt_verify::getStatusString(c.jwks->getStatus()),
                  consumer_jwks));
              return false;
            }
            std::unordered_map<std::string, std::string> claims;
            auto consumer_claims_json = consumer.find("claims");
            if (consumer_claims_json != consumer.end()) {
              JSON_FIELD_VALUE_AS(Wasm::Common::JsonObject, consumer, claims);
              if (!JsonObjectIterate(
                      consumer_claims, [&](std::string key) -> bool {
                        auto claims_claim_json = consumer_claims.find(key);
                        JSON_FIELD_VALUE_AS(std::string, claims, claim);
                        claims.emplace(std::make_pair(
                            key, Wasm::Common::trim(claims_claim)));
                        return true;
                      })) {
                LOG_WARN("failed to parse 'claims' in consumer: " +
                         consumer_name);
                return false;
              }
            }
            auto consumer_issuer_json = consumer.find("issuer");
            if (consumer_issuer_json != consumer.end()) {
              JSON_FIELD_VALUE_AS(std::string, consumer, issuer);
              claims.emplace(
                  std::make_pair("iss", Wasm::Common::trim(consumer_issuer)));
            }
            c.allowd_claims = std::move(claims);
            std::vector<FromHeader> from_headers;
            if (!JsonArrayIterate(
                    consumer, "from_headers",
                    [&](const json& from_header) -> bool {
                      JSON_FIND_FIELD(from_header, name);
                      JSON_FIELD_VALUE_AS(std::string, from_header, name);
                      std::string header_value_prefix;
                      auto from_header_value_prefix_json =
                          from_header.find("value_prefix");
                      if (from_header_value_prefix_json != from_header.end()) {
                        JSON_FIELD_VALUE_AS(std::string, from_header,
                                            value_prefix);
                        header_value_prefix = from_header_value_prefix;
                      }
                      from_headers.push_back(
                          FromHeader{from_header_name, header_value_prefix});
                      return true;
                    })) {
              LOG_WARN("failed to parse 'from_headers' in consumer: " +
                       consumer_name);
              return false;
            }
            std::vector<std::string> from_params;
            if (!JsonArrayIterate(consumer, "from_params",
                                  [&](const json& from_param_json) -> bool {
                                    JSON_VALUE_AS(std::string, from_param_json,
                                                  from_param, "invalid item");
                                    from_params.push_back(from_param);
                                    return true;
                                  })) {
              LOG_WARN("failed to parse 'from_params' in consumer: " +
                       consumer_name);
              return false;
            }
            std::vector<std::string> from_cookies;
            if (!JsonArrayIterate(consumer, "from_cookies",
                                  [&](const json& from_cookie_json) -> bool {
                                    JSON_VALUE_AS(std::string, from_cookie_json,
                                                  from_cookie, "invalid item");
                                    from_cookies.push_back(from_cookie);
                                    return true;
                                  })) {
              LOG_WARN("failed to parse 'from_cookies' in consumer: " +
                       consumer_name);
              return false;
            }
            if (!from_headers.empty() || !from_params.empty() ||
                !from_cookies.empty()) {
              c.from_headers = std::move(from_headers);
              c.from_params = std::move(from_params);
              c.from_cookies = std::move(from_cookies);
            }
            std::unordered_map<std::string, ClaimToHeader> claims_to_headers;
            if (!JsonArrayIterate(
                    consumer, "claims_to_headers",
                    [&](const json& item_json) -> bool {
                      JSON_VALUE_AS(Wasm::Common::JsonObject, item_json, item,
                                    "invalid item");
                      JSON_FIND_FIELD(item, claim);
                      JSON_FIELD_VALUE_AS(std::string, item, claim);
                      auto c2h_it = claims_to_headers.find(item_claim);
                      if (c2h_it != claims_to_headers.end()) {
                        LOG_WARN("claim to header already exists: " +
                                 item_claim);
                        return false;
                      }
                      auto& c2h = claims_to_headers[item_claim];
                      JSON_FIND_FIELD(item, header);
                      JSON_FIELD_VALUE_AS(std::string, item, header);
                      c2h.header = std::move(item_header);
                      auto item_override_json = item.find("override");
                      if (item_override_json != item.end()) {
                        JSON_FIELD_VALUE_AS(bool, item, override);
                        c2h.override = item_override;
                      }
                      return true;
                    })) {
              LOG_WARN("failed to parse 'claims_to_headers' in consumer: " +
                       consumer_name);
              return false;
            }
            c.claims_to_headers = std::move(claims_to_headers);
            auto consumer_clock_skew_seconds_json =
                consumer.find("clock_skew_seconds");
            if (consumer_clock_skew_seconds_json != consumer.end()) {
              JSON_FIELD_VALUE_AS(uint64_t, consumer, clock_skew_seconds);
              c.clock_skew = consumer_clock_skew_seconds;
            }
            auto consumer_keep_token_json = consumer.find("keep_token");
            if (consumer_keep_token_json != consumer.end()) {
              JSON_FIELD_VALUE_AS(bool, consumer, keep_token);
              c.keep_token = consumer_keep_token;
            }
            c.extractor = Extractor::create(c);
            rule.consumers.push_back(std::move(c));
            name_set.insert(consumer_name);
            return true;
          })) {
    LOG_WARN("failed to parse configuration for consumers.");
    return false;
  }
  if (rule.consumers.empty()) {
    LOG_INFO("at least one consumer has to be configured for a rule.");
    return false;
  }
  std::vector<std::string> enable_headers;
  if (!JsonArrayIterate(configuration, "enable_headers",
                        [&](const json& enable_header_json) -> bool {
                          JSON_VALUE_AS(std::string, enable_header_json,
                                        enable_header, "invalid item");
                          enable_headers.push_back(enable_header);
                          return true;
                        })) {
    LOG_WARN("failed to parse 'enable_headers'");
    return false;
  }
  rule.enable_headers = std::move(enable_headers);
  return true;
}