Revert "[Audit Logging] Audit logging config translation by rbac service config parser" (#33178)

Reverts grpc/grpc#33145

It causes internal breakages.
pull/33183/head
Eugene Ostroukhov 2 years ago committed by GitHub
parent 57cd079310
commit 922b18f71b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      include/grpc/grpc_audit_logging.h
  2. 1
      src/core/BUILD
  3. 98
      src/core/ext/filters/rbac/rbac_service_config_parser.cc
  4. 8
      src/core/lib/security/authorization/grpc_authorization_engine.h
  5. 1
      src/core/lib/security/authorization/stdout_logger.h
  6. 300
      test/core/ext/filters/rbac/rbac_service_config_parser_test.cc
  7. 1
      test/core/security/grpc_audit_logging_test.cc
  8. 1
      test/core/security/grpc_authorization_engine_test.cc

@ -62,7 +62,6 @@ class AuditContext {
class AuditLogger {
public:
virtual ~AuditLogger() = default;
virtual absl::string_view name() const = 0;
virtual void Log(const AuditContext& audit_context) = 0;
};

@ -3697,7 +3697,6 @@ grpc_cc_library(
"channel_fwd",
"closure",
"error",
"grpc_audit_logging",
"grpc_authorization_base",
"grpc_matchers",
"grpc_rbac_engine",

@ -20,29 +20,21 @@
#include <cstdint>
#include <map>
#include <memory>
#include <string>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/types/optional.h"
#include <grpc/grpc_audit_logging.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/json/json_args.h"
#include "src/core/lib/json/json_object_loader.h"
#include "src/core/lib/matchers/matchers.h"
#include "src/core/lib/security/authorization/audit_logging.h"
namespace grpc_core {
namespace {
using experimental::AuditLoggerFactory;
using experimental::AuditLoggerRegistry;
// RbacConfig: one or more RbacPolicy structs
struct RbacConfig {
// RbacPolicy: optional Rules
@ -187,21 +179,8 @@ struct RbacConfig {
static const JsonLoaderInterface* JsonLoader(const JsonArgs&);
};
// AuditLogger: the name of logger and its config in json
struct AuditLogger {
std::string name;
Json::Object config;
static const JsonLoaderInterface* JsonLoader(const JsonArgs&);
void JsonPostLoad(const Json&, const JsonArgs&,
ValidationErrors* errors);
};
int action;
std::map<std::string, Policy> policies;
// Defaults to kNone since its json field is optional.
Rbac::AuditCondition audit_condition = Rbac::AuditCondition::kNone;
std::vector<std::unique_ptr<AuditLoggerFactory::Config>> logger_configs;
Rules() = default;
Rules(const Rules&) = delete;
@ -209,7 +188,7 @@ struct RbacConfig {
Rules(Rules&&) = default;
Rules& operator=(Rules&&) = default;
Rbac TakeAsRbac(std::string name);
Rbac TakeAsRbac();
static const JsonLoaderInterface* JsonLoader(const JsonArgs&);
void JsonPostLoad(const Json&, const JsonArgs&, ValidationErrors* errors);
};
@ -737,51 +716,24 @@ const JsonLoaderInterface* RbacConfig::RbacPolicy::Rules::Policy::JsonLoader(
return loader;
}
//
// RbacConfig::RbacPolicy::Rules::AuditLogger
//
const JsonLoaderInterface*
RbacConfig::RbacPolicy::Rules::AuditLogger::JsonLoader(const JsonArgs&) {
// All fields handled in JsonPostLoad().
static const auto* loader = JsonObjectLoader<AuditLogger>().Finish();
return loader;
}
void RbacConfig::RbacPolicy::Rules::AuditLogger::JsonPostLoad(
const Json& json, const JsonArgs& args, ValidationErrors* errors) {
// Should have exactly one field as the logger name.
if (json.object().size() != 1) {
errors->AddError("audit logger should have exactly one field");
return;
}
name = json.object().begin()->first;
auto config_or =
LoadJsonObjectField<Json::Object>(json.object(), args, name, errors);
if (config_or.has_value()) {
config = std::move(*config_or);
}
}
//
// RbacConfig::RbacPolicy::Rules
//
Rbac RbacConfig::RbacPolicy::Rules::TakeAsRbac(std::string name) {
Rbac RbacConfig::RbacPolicy::Rules::TakeAsRbac() {
Rbac rbac;
rbac.name = std::move(name);
// TODO(lwge): This is to fix msan failure for now. Add proper conversion once
// audit logging support is added.
rbac.audit_condition = Rbac::AuditCondition::kNone;
rbac.action = static_cast<Rbac::Action>(action);
rbac.audit_condition = audit_condition;
for (auto& p : policies) {
rbac.policies.emplace(p.first, p.second.TakeAsRbacPolicy());
}
rbac.logger_configs = std::move(logger_configs);
return rbac;
}
const JsonLoaderInterface* RbacConfig::RbacPolicy::Rules::JsonLoader(
const JsonArgs&) {
// Audit logger configs handled in post load.
static const auto* loader = JsonObjectLoader<Rules>()
.Field("action", &Rules::action)
.OptionalField("policies", &Rules::policies)
@ -789,8 +741,7 @@ const JsonLoaderInterface* RbacConfig::RbacPolicy::Rules::JsonLoader(
return loader;
}
void RbacConfig::RbacPolicy::Rules::JsonPostLoad(const Json& json,
const JsonArgs& args,
void RbacConfig::RbacPolicy::Rules::JsonPostLoad(const Json&, const JsonArgs&,
ValidationErrors* errors) {
// Validate action field.
auto rbac_action = static_cast<Rbac::Action>(action);
@ -799,40 +750,6 @@ void RbacConfig::RbacPolicy::Rules::JsonPostLoad(const Json& json,
ValidationErrors::ScopedField field(errors, ".action");
errors->AddError("unknown action");
}
// Parse and validate audit_condition field.
auto condition = LoadJsonObjectField<int>(json.object(), args,
"audit_condition", errors, false);
if (condition.has_value()) {
switch (*condition) {
case static_cast<int>(Rbac::AuditCondition::kNone):
case static_cast<int>(Rbac::AuditCondition::kOnAllow):
case static_cast<int>(Rbac::AuditCondition::kOnDeny):
case static_cast<int>(Rbac::AuditCondition::kOnDenyAndAllow):
audit_condition = static_cast<Rbac::AuditCondition>(*condition);
break;
default: {
ValidationErrors::ScopedField field(errors, ".audit_condition");
errors->AddError("unknown audit condition");
}
}
}
// Parse and validate audit logger configs.
auto configs = LoadJsonObjectField<std::vector<AuditLogger>>(
json.object(), args, "audit_loggers", errors, false);
if (configs.has_value()) {
for (size_t i = 0; i < configs->size(); ++i) {
auto& logger = (*configs)[i];
auto config = AuditLoggerRegistry::ParseConfig(
logger.name, Json::FromObject(std::move(logger.config)));
if (!config.ok()) {
ValidationErrors::ScopedField field(
errors, absl::StrCat(".audit_loggers[", i, "]"));
errors->AddError(config.status().message());
continue;
}
logger_configs.push_back(std::move(*config));
}
}
}
//
@ -845,7 +762,8 @@ Rbac RbacConfig::RbacPolicy::TakeAsRbac() {
// is equivalent to no enforcing.
return Rbac(std::move(name), Rbac::Action::kDeny, {});
}
return rules->TakeAsRbac(std::move(name));
// TODO(lwge): This also needs to take the name.
return rules->TakeAsRbac();
}
const JsonLoaderInterface* RbacConfig::RbacPolicy::JsonLoader(const JsonArgs&) {

@ -56,14 +56,6 @@ class GrpcAuthorizationEngine : public AuthorizationEngine {
// Required only for testing purpose.
size_t num_policies() const { return policies_.size(); }
// Required only for testing purpose.
Rbac::AuditCondition audit_condition() const { return audit_condition_; }
// Required only for testing purpose.
const std::vector<std::unique_ptr<AuditLogger>>& audit_loggers() const {
return audit_loggers_;
}
// Evaluates incoming request against RBAC policy and makes a decision to
// whether allow/deny this request.
Decision Evaluate(const EvaluateArgs& args) const override;

@ -32,7 +32,6 @@ namespace experimental {
class StdoutAuditLogger : public AuditLogger {
public:
StdoutAuditLogger() = default;
absl::string_view name() const override { return "stdout_logger"; }
void Log(const AuditContext&) override;
};

@ -14,23 +14,14 @@
#include "src/core/ext/filters/rbac/rbac_service_config_parser.h"
#include <map>
#include <memory>
#include <string>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <grpc/grpc.h>
#include <grpc/grpc_audit_logging.h>
#include <grpc/slice.h>
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/json/json_writer.h"
#include "src/core/lib/security/authorization/audit_logging.h"
#include "src/core/lib/service_config/service_config.h"
#include "src/core/lib/service_config/service_config_impl.h"
#include "test/core/util/test_config.h"
@ -39,68 +30,8 @@ namespace grpc_core {
namespace testing {
namespace {
using experimental::AuditContext;
using experimental::AuditLogger;
using experimental::AuditLoggerFactory;
using experimental::AuditLoggerRegistry;
using experimental::RegisterAuditLoggerFactory;
constexpr absl::string_view kLoggerName = "test_logger";
class TestAuditLogger : public AuditLogger {
public:
TestAuditLogger() = default;
absl::string_view name() const override { return kLoggerName; }
void Log(const AuditContext&) override {}
};
class TestAuditLoggerFactory : public AuditLoggerFactory {
public:
class Config : public AuditLoggerFactory::Config {
public:
explicit Config(const Json& json) : config_(JsonDump(json)) {}
absl::string_view name() const override { return kLoggerName; }
std::string ToString() const override { return config_; }
private:
std::string config_;
};
explicit TestAuditLoggerFactory(
std::map<absl::string_view, std::string>* configs)
: configs_(configs) {}
absl::string_view name() const override { return kLoggerName; }
absl::StatusOr<std::unique_ptr<AuditLoggerFactory::Config>>
ParseAuditLoggerConfig(const Json& json) override {
// Invalidate configs with "bad" field in it.
if (json.object().find("bad") != json.object().end()) {
return absl::InvalidArgumentError("bad logger config");
}
return std::make_unique<Config>(json);
}
std::unique_ptr<AuditLogger> CreateAuditLogger(
std::unique_ptr<AuditLoggerFactory::Config> config) override {
// Only insert entry to the map when logger is created.
configs_->emplace(name(), config->ToString());
return std::make_unique<TestAuditLogger>();
}
private:
std::map<absl::string_view, std::string>* configs_;
};
class RbacServiceConfigParsingTest : public ::testing::Test {
protected:
void SetUp() override {
RegisterAuditLoggerFactory(
std::make_unique<TestAuditLoggerFactory>(&logger_configs_));
}
void TearDown() override { AuditLoggerRegistry::TestOnlyResetRegistry(); }
std::map<absl::string_view, std::string> logger_configs_;
};
// Filter name is required in RBAC policy.
TEST_F(RbacServiceConfigParsingTest, EmptyRbacPolicy) {
TEST(RbacServiceConfigParsingTest, EmptyRbacPolicy) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
@ -122,7 +53,7 @@ TEST_F(RbacServiceConfigParsingTest, EmptyRbacPolicy) {
}
// Test basic parsing of RBAC policy
TEST_F(RbacServiceConfigParsingTest, RbacPolicyWithoutRules) {
TEST(RbacServiceConfigParsingTest, RbacPolicyWithoutRules) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
@ -149,7 +80,7 @@ TEST_F(RbacServiceConfigParsingTest, RbacPolicyWithoutRules) {
// Test that RBAC policies are not parsed if the channel arg
// GRPC_ARG_PARSE_RBAC_METHOD_CONFIG is not present
TEST_F(RbacServiceConfigParsingTest, MissingChannelArg) {
TEST(RbacServiceConfigParsingTest, MissingChannelArg) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
@ -171,7 +102,7 @@ TEST_F(RbacServiceConfigParsingTest, MissingChannelArg) {
}
// Test an empty rbacPolicy array
TEST_F(RbacServiceConfigParsingTest, EmptyRbacPolicyArray) {
TEST(RbacServiceConfigParsingTest, EmptyRbacPolicyArray) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
@ -193,7 +124,7 @@ TEST_F(RbacServiceConfigParsingTest, EmptyRbacPolicyArray) {
}
// Test presence of multiple RBAC policies in the array
TEST_F(RbacServiceConfigParsingTest, MultipleRbacPolicies) {
TEST(RbacServiceConfigParsingTest, MultipleRbacPolicies) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
@ -224,7 +155,7 @@ TEST_F(RbacServiceConfigParsingTest, MultipleRbacPolicies) {
}
}
TEST_F(RbacServiceConfigParsingTest, BadRbacPolicyType) {
TEST(RbacServiceConfigParsingTest, BadRbacPolicyType) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
@ -243,7 +174,7 @@ TEST_F(RbacServiceConfigParsingTest, BadRbacPolicyType) {
<< service_config.status();
}
TEST_F(RbacServiceConfigParsingTest, BadRulesType) {
TEST(RbacServiceConfigParsingTest, BadRulesType) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
@ -262,7 +193,7 @@ TEST_F(RbacServiceConfigParsingTest, BadRulesType) {
<< service_config.status();
}
TEST_F(RbacServiceConfigParsingTest, BadActionAndPolicyType) {
TEST(RbacServiceConfigParsingTest, BadActionAndPolicyType) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
@ -290,7 +221,7 @@ TEST_F(RbacServiceConfigParsingTest, BadActionAndPolicyType) {
<< service_config.status();
}
TEST_F(RbacServiceConfigParsingTest, MissingPermissionAndPrincipals) {
TEST(RbacServiceConfigParsingTest, MissingPermissionAndPrincipals) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
@ -321,7 +252,7 @@ TEST_F(RbacServiceConfigParsingTest, MissingPermissionAndPrincipals) {
<< service_config.status();
}
TEST_F(RbacServiceConfigParsingTest, EmptyPrincipalAndPermission) {
TEST(RbacServiceConfigParsingTest, EmptyPrincipalAndPermission) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
@ -354,7 +285,7 @@ TEST_F(RbacServiceConfigParsingTest, EmptyPrincipalAndPermission) {
<< service_config.status();
}
TEST_F(RbacServiceConfigParsingTest, VariousPermissionsAndPrincipalsTypes) {
TEST(RbacServiceConfigParsingTest, VariousPermissionsAndPrincipalsTypes) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
@ -412,7 +343,7 @@ TEST_F(RbacServiceConfigParsingTest, VariousPermissionsAndPrincipalsTypes) {
EXPECT_EQ(parsed_rbac_config->authorization_engine(0)->num_policies(), 1);
}
TEST_F(RbacServiceConfigParsingTest, VariousPermissionsAndPrincipalsBadTypes) {
TEST(RbacServiceConfigParsingTest, VariousPermissionsAndPrincipalsBadTypes) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
@ -507,7 +438,7 @@ TEST_F(RbacServiceConfigParsingTest, VariousPermissionsAndPrincipalsBadTypes) {
<< service_config.status();
}
TEST_F(RbacServiceConfigParsingTest, HeaderMatcherVariousTypes) {
TEST(RbacServiceConfigParsingTest, HeaderMatcherVariousTypes) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
@ -552,7 +483,7 @@ TEST_F(RbacServiceConfigParsingTest, HeaderMatcherVariousTypes) {
EXPECT_EQ(parsed_rbac_config->authorization_engine(0)->num_policies(), 1);
}
TEST_F(RbacServiceConfigParsingTest, HeaderMatcherBadTypes) {
TEST(RbacServiceConfigParsingTest, HeaderMatcherBadTypes) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
@ -609,7 +540,7 @@ TEST_F(RbacServiceConfigParsingTest, HeaderMatcherBadTypes) {
<< service_config.status();
}
TEST_F(RbacServiceConfigParsingTest, StringMatcherVariousTypes) {
TEST(RbacServiceConfigParsingTest, StringMatcherVariousTypes) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
@ -651,7 +582,7 @@ TEST_F(RbacServiceConfigParsingTest, StringMatcherVariousTypes) {
EXPECT_EQ(parsed_rbac_config->authorization_engine(0)->num_policies(), 1);
}
TEST_F(RbacServiceConfigParsingTest, StringMatcherBadTypes) {
TEST(RbacServiceConfigParsingTest, StringMatcherBadTypes) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
@ -707,205 +638,6 @@ TEST_F(RbacServiceConfigParsingTest, StringMatcherBadTypes) {
<< service_config.status();
}
TEST_F(RbacServiceConfigParsingTest, AuditConditionOnDenyWithMultipleLoggers) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
" \"name\": [\n"
" {}\n"
" ],\n"
" \"rbacPolicy\": [ {\n"
" \"filter_name\": \"rbac\",\n"
" \"rules\":{\n"
" \"action\":1,\n"
" \"audit_condition\":1,\n"
" \"audit_loggers\":[ \n"
" {\n"
" \"stdout_logger\": {}\n"
" },\n"
" {\n"
" \"test_logger\": {\"foo\": \"bar\"}\n"
" }\n"
" ]\n"
" }\n"
" } ]\n"
" } ]\n"
"}";
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto service_config = ServiceConfigImpl::Create(args, test_json);
ASSERT_TRUE(service_config.status().ok());
const auto* vector_ptr =
(*service_config)->GetMethodParsedConfigVector(grpc_empty_slice());
ASSERT_NE(vector_ptr, nullptr);
auto* parsed_rbac_config = static_cast<RbacMethodParsedConfig*>(
((*vector_ptr)[RbacServiceConfigParser::ParserIndex()]).get());
ASSERT_NE(parsed_rbac_config, nullptr);
ASSERT_NE(parsed_rbac_config->authorization_engine(0), nullptr);
EXPECT_EQ(parsed_rbac_config->authorization_engine(0)->audit_condition(),
Rbac::AuditCondition::kOnDeny);
EXPECT_THAT(parsed_rbac_config->authorization_engine(0)->audit_loggers(),
::testing::ElementsAre(::testing::Pointee(::testing::Property(
&AuditLogger::name, "stdout_logger")),
::testing::Pointee(::testing::Property(
&AuditLogger::name, kLoggerName))));
EXPECT_THAT(logger_configs_, ::testing::ElementsAre(::testing::Pair(
"test_logger", "{\"foo\":\"bar\"}")));
}
TEST_F(RbacServiceConfigParsingTest, BadAuditLoggerConfig) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
" \"name\": [\n"
" {}\n"
" ],\n"
" \"rbacPolicy\": [ {\n"
" \"filter_name\": \"rbac\",\n"
" \"rules\":{\n"
" \"action\":1,\n"
" \"audit_condition\":1,\n"
" \"audit_loggers\":[ \n"
" {\n"
" \"test_logger\": {\"bad\": \"bar\"}\n"
" }\n"
" ]\n"
" }\n"
" } ]\n"
" } ]\n"
"}";
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto service_config = ServiceConfigImpl::Create(args, test_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_EQ(service_config.status().message(),
"errors validating service config: ["
"field:methodConfig[0].rbacPolicy[0].rules.audit_loggers[0] "
"error:bad logger config]")
<< service_config.status();
}
TEST_F(RbacServiceConfigParsingTest, UnknownAuditLoggerConfig) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
" \"name\": [\n"
" {}\n"
" ],\n"
" \"rbacPolicy\": [ {\n"
" \"filter_name\": \"rbac\",\n"
" \"rules\":{\n"
" \"action\":1,\n"
" \"audit_condition\":1,\n"
" \"audit_loggers\":[ \n"
" {\n"
" \"unknown_logger\": {}\n"
" }\n"
" ]\n"
" }\n"
" } ]\n"
" } ]\n"
"}";
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto service_config = ServiceConfigImpl::Create(args, test_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_EQ(service_config.status().message(),
"errors validating service config: ["
"field:methodConfig[0].rbacPolicy[0].rules.audit_loggers[0] "
"error:audit logger factory for unknown_logger does not exist]")
<< service_config.status();
}
TEST_F(RbacServiceConfigParsingTest, BadAuditConditionAndLoggersTypes) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
" \"name\": [\n"
" {}\n"
" ],\n"
" \"rbacPolicy\": [ {\n"
" \"filter_name\": \"rbac\",\n"
" \"rules\":{\n"
" \"action\":1,\n"
" \"audit_condition\":{},\n"
" \"audit_loggers\":{}\n"
" }\n"
" } ]\n"
" } ]\n"
"}";
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto service_config = ServiceConfigImpl::Create(args, test_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_EQ(service_config.status().message(),
"errors validating service config: ["
"field:methodConfig[0].rbacPolicy[0].rules.audit_condition "
"error:is not a number; "
"field:methodConfig[0].rbacPolicy[0].rules.audit_loggers "
"error:is not an array]")
<< service_config.status();
}
TEST_F(RbacServiceConfigParsingTest, BadAuditConditionEnum) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
" \"name\": [\n"
" {}\n"
" ],\n"
" \"rbacPolicy\": [ {\n"
" \"filter_name\": \"rbac\",\n"
" \"rules\":{\n"
" \"action\":1,\n"
" \"audit_condition\":100\n"
" }\n"
" } ]\n"
" } ]\n"
"}";
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto service_config = ServiceConfigImpl::Create(args, test_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_EQ(service_config.status().message(),
"errors validating service config: ["
"field:methodConfig[0].rbacPolicy[0].rules.audit_condition "
"error:unknown audit condition]")
<< service_config.status();
}
TEST_F(RbacServiceConfigParsingTest, BadAuditLoggerObject) {
const char* test_json =
"{\n"
" \"methodConfig\": [ {\n"
" \"name\": [\n"
" {}\n"
" ],\n"
" \"rbacPolicy\": [ {\n"
" \"filter_name\": \"rbac\",\n"
" \"rules\":{\n"
" \"action\":1,\n"
" \"audit_condition\":1,\n"
" \"audit_loggers\":[ \n"
" {\n"
" \"stdout_logger\": {},\n"
" \"foo\": {}\n"
" },\n"
" {\n"
" \"stdout_logger\": 123\n"
" }\n"
" ]\n"
" }\n"
" } ]\n"
" } ]\n"
"}";
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto service_config = ServiceConfigImpl::Create(args, test_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_EQ(service_config.status().message(),
"errors validating service config: "
"[field:methodConfig[0].rbacPolicy[0].rules.audit_loggers[0] "
"error:audit logger should have exactly one field; "
"field:methodConfig[0].rbacPolicy[0].rules.audit_loggers[1].stdout_"
"logger error:is not an object]")
<< service_config.status();
}
} // namespace
} // namespace testing
} // namespace grpc_core

@ -54,7 +54,6 @@ namespace {
class TestAuditLogger : public AuditLogger {
public:
absl::string_view name() const override { return "test_logger"; }
void Log(const AuditContext&) override {}
};

@ -65,7 +65,6 @@ class TestAuditLogger : public AuditLogger {
std::vector<std::unique_ptr<TestAuditContext>>* contexts)
: contexts_(contexts) {}
absl::string_view name() const override { return kLoggerName; }
void Log(const AuditContext& context) override {
contexts_->push_back(std::make_unique<TestAuditContext>(context));
}

Loading…
Cancel
Save