@ -14,15 +14,33 @@
# include "src/core/lib/security/authorization/rbac_translator.h"
# include <memory>
# include <gmock/gmock.h>
# include <gtest/gtest.h>
# include "absl/strings/match.h"
# include "absl/strings/string_view.h"
# include <grpc/grpc_audit_logging.h>
# include "src/core/lib/gprpp/crash.h"
# include "src/core/lib/json/json.h"
# include "src/core/lib/json/json_writer.h"
# include "src/core/lib/security/authorization/audit_logging.h"
# include "test/core/util/test_config.h"
namespace grpc_core {
namespace {
constexpr absl : : string_view kLoggerName = " test_logger " ;
using experimental : : AuditLogger ;
using experimental : : AuditLoggerFactory ;
using experimental : : AuditLoggerRegistry ;
using experimental : : RegisterAuditLoggerFactory ;
MATCHER_P3 ( EqualsPrincipalName , expected_matcher_type , expected_matcher_value ,
is_regex , " " ) {
return arg - > type = = Rbac : : Principal : : RuleType : : kPrincipalName & &
@ -53,9 +71,47 @@ MATCHER_P4(EqualsHeader, expected_name, expected_matcher_type,
: arg - > header_matcher . string_matcher ( ) = = expected_matcher_value ;
}
class TestAuditLoggerFactory : public AuditLoggerFactory {
public :
class TestAuditLoggerConfig : public AuditLoggerFactory : : Config {
public :
explicit TestAuditLoggerConfig ( std : : string config_dump )
: config_dump_ ( std : : move ( config_dump ) ) { }
absl : : string_view name ( ) const override { return kLoggerName ; }
std : : string ToString ( ) const override { return config_dump_ ; }
private :
std : : string config_dump_ ;
} ;
absl : : string_view name ( ) const override { return kLoggerName ; }
absl : : StatusOr < std : : unique_ptr < AuditLoggerFactory : : Config > >
ParseAuditLoggerConfig ( const Json & json ) override {
// Config with a field "bad" will be considered invalid.
if ( json . object ( ) . find ( " bad " ) ! = json . object ( ) . end ( ) ) {
return absl : : InvalidArgumentError ( " bad logger config. " ) ;
}
return std : : make_unique < TestAuditLoggerConfig > ( JsonDump ( json ) ) ;
}
std : : unique_ptr < AuditLogger > CreateAuditLogger (
std : : unique_ptr < AuditLoggerFactory : : Config > ) override {
// This test target should never need to create a logger.
Crash ( " unreachable " ) ;
return nullptr ;
}
} ;
class GenerateRbacPoliciesTest : public : : testing : : Test {
protected :
void SetUp ( ) override {
RegisterAuditLoggerFactory ( std : : make_unique < TestAuditLoggerFactory > ( ) ) ;
}
void TearDown ( ) override { AuditLoggerRegistry : : TestOnlyResetRegistry ( ) ; }
} ;
} // namespace
TEST ( GenerateRbacPoliciesTest , InvalidPolicy ) {
TEST_F ( GenerateRbacPoliciesTest , InvalidPolicy ) {
const char * authz_policy =
" { "
" \" name \" : \" authz-policy \" ,, "
@ -67,14 +123,14 @@ TEST(GenerateRbacPoliciesTest, InvalidPolicy) {
: : testing : : StartsWith ( " Failed to parse gRPC authorization policy. " ) ) ;
}
TEST ( GenerateRbacPoliciesTest , MissingAuthorizationPolicyName ) {
TEST_F ( GenerateRbacPoliciesTest , MissingAuthorizationPolicyName ) {
const char * authz_policy = " {} " ;
auto rbac_policies = GenerateRbacPolicies ( authz_policy ) ;
EXPECT_EQ ( rbac_policies . status ( ) . code ( ) , absl : : StatusCode : : kInvalidArgument ) ;
EXPECT_EQ ( rbac_policies . status ( ) . message ( ) , " \" name \" field is not present. " ) ;
}
TEST ( GenerateRbacPoliciesTest , IncorrectAuthorizationPolicyNameType ) {
TEST_F ( GenerateRbacPoliciesTest , IncorrectAuthorizationPolicyNameType ) {
const char * authz_policy =
" { "
" \" name \" : [ \" authz_policy \" ] "
@ -84,7 +140,7 @@ TEST(GenerateRbacPoliciesTest, IncorrectAuthorizationPolicyNameType) {
EXPECT_EQ ( rbac_policies . status ( ) . message ( ) , " \" name \" is not a string. " ) ;
}
TEST ( GenerateRbacPoliciesTest , MissingAllowRules ) {
TEST_F ( GenerateRbacPoliciesTest , MissingAllowRules ) {
const char * authz_policy =
" { "
" \" name \" : \" authz_policy \" "
@ -95,7 +151,7 @@ TEST(GenerateRbacPoliciesTest, MissingAllowRules) {
" \" allow_rules \" is not present. " ) ;
}
TEST ( GenerateRbacPoliciesTest , MissingDenyRules ) {
TEST_F ( GenerateRbacPoliciesTest , MissingDenyRules ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -107,10 +163,11 @@ TEST(GenerateRbacPoliciesTest, MissingDenyRules) {
" } " ;
auto rbac_policies = GenerateRbacPolicies ( authz_policy ) ;
ASSERT_TRUE ( rbac_policies . ok ( ) ) ;
EXPECT_EQ ( rbac_policies - > allow_policy . name , " authz " ) ;
EXPECT_FALSE ( rbac_policies - > deny_policy . has_value ( ) ) ;
}
TEST ( GenerateRbacPoliciesTest , IncorrectAllowRulesType ) {
TEST_F ( GenerateRbacPoliciesTest , IncorrectAllowRulesType ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -122,7 +179,7 @@ TEST(GenerateRbacPoliciesTest, IncorrectAllowRulesType) {
" \" allow_rules \" is not an array. " ) ;
}
TEST ( GenerateRbacPoliciesTest , IncorrectDenyRulesType ) {
TEST_F ( GenerateRbacPoliciesTest , IncorrectDenyRulesType ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -134,7 +191,7 @@ TEST(GenerateRbacPoliciesTest, IncorrectDenyRulesType) {
" \" deny_rules \" is not an array. " ) ;
}
TEST ( GenerateRbacPoliciesTest , IncorrectRuleType ) {
TEST_F ( GenerateRbacPoliciesTest , IncorrectRuleType ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -146,7 +203,7 @@ TEST(GenerateRbacPoliciesTest, IncorrectRuleType) {
" allow_rules 0: is not an object. " ) ;
}
TEST ( GenerateRbacPoliciesTest , EmptyRuleArray ) {
TEST_F ( GenerateRbacPoliciesTest , EmptyRuleArray ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -157,7 +214,7 @@ TEST(GenerateRbacPoliciesTest, EmptyRuleArray) {
EXPECT_EQ ( rbac_policies . status ( ) . message ( ) , " allow_rules is empty. " ) ;
}
TEST ( GenerateRbacPoliciesTest , MissingRuleNameField ) {
TEST_F ( GenerateRbacPoliciesTest , MissingRuleNameField ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -169,7 +226,7 @@ TEST(GenerateRbacPoliciesTest, MissingRuleNameField) {
" allow_rules 0: \" name \" is not present. " ) ;
}
TEST ( GenerateRbacPoliciesTest , IncorrectRuleNameType ) {
TEST_F ( GenerateRbacPoliciesTest , IncorrectRuleNameType ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -185,7 +242,7 @@ TEST(GenerateRbacPoliciesTest, IncorrectRuleNameType) {
" allow_rules 0: \" name \" is not a string. " ) ;
}
TEST ( GenerateRbacPoliciesTest , MissingSourceAndRequest ) {
TEST_F ( GenerateRbacPoliciesTest , MissingSourceAndRequest ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -197,11 +254,12 @@ TEST(GenerateRbacPoliciesTest, MissingSourceAndRequest) {
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
ASSERT_TRUE ( rbacs . ok ( ) ) ;
EXPECT_EQ ( rbacs - > allow_policy . name , " authz " ) ;
EXPECT_EQ ( rbacs - > allow_policy . action , Rbac : : Action : : kAllow ) ;
EXPECT_THAT (
rbacs - > allow_policy . policies ,
: : testing : : ElementsAre ( : : testing : : Pair (
" authz_a llow_policy " ,
" allow_policy " ,
: : testing : : AllOf (
: : testing : : Field (
& Rbac : : Policy : : permissions ,
@ -213,7 +271,7 @@ TEST(GenerateRbacPoliciesTest, MissingSourceAndRequest) {
Rbac : : Principal : : RuleType : : kAny ) ) ) ) ) ) ;
}
TEST ( GenerateRbacPoliciesTest , EmptySourceAndRequest ) {
TEST_F ( GenerateRbacPoliciesTest , EmptySourceAndRequest ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -227,11 +285,12 @@ TEST(GenerateRbacPoliciesTest, EmptySourceAndRequest) {
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
ASSERT_TRUE ( rbacs . ok ( ) ) ;
EXPECT_EQ ( rbacs - > allow_policy . name , " authz " ) ;
EXPECT_EQ ( rbacs - > allow_policy . action , Rbac : : Action : : kAllow ) ;
EXPECT_THAT (
rbacs - > allow_policy . policies ,
: : testing : : ElementsAre ( : : testing : : Pair (
" authz_a llow_policy " ,
" allow_policy " ,
: : testing : : AllOf (
: : testing : : Field (
& Rbac : : Policy : : permissions ,
@ -243,7 +302,7 @@ TEST(GenerateRbacPoliciesTest, EmptySourceAndRequest) {
Rbac : : Principal : : RuleType : : kAny ) ) ) ) ) ) ;
}
TEST ( GenerateRbacPoliciesTest , IncorrectSourceType ) {
TEST_F ( GenerateRbacPoliciesTest , IncorrectSourceType ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -260,7 +319,7 @@ TEST(GenerateRbacPoliciesTest, IncorrectSourceType) {
" allow_rules 0: \" source \" is not an object. " ) ;
}
TEST ( GenerateRbacPoliciesTest , IncorrectPrincipalsType ) {
TEST_F ( GenerateRbacPoliciesTest , IncorrectPrincipalsType ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -282,7 +341,7 @@ TEST(GenerateRbacPoliciesTest, IncorrectPrincipalsType) {
" allow_rules 0: \" principals \" 1: is not a string. " ) ;
}
TEST ( GenerateRbacPoliciesTest , ParseSourceSuccess ) {
TEST_F ( GenerateRbacPoliciesTest , ParseSourceSuccess ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -312,10 +371,12 @@ TEST(GenerateRbacPoliciesTest, ParseSourceSuccess) {
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
ASSERT_TRUE ( rbacs . ok ( ) ) ;
EXPECT_EQ ( rbacs - > allow_policy . name , " authz " ) ;
EXPECT_EQ ( rbacs - > deny_policy - > name , " authz " ) ;
EXPECT_EQ ( rbacs - > allow_policy . action , Rbac : : Action : : kAllow ) ;
EXPECT_THAT ( rbacs - > allow_policy . policies ,
: : testing : : ElementsAre ( : : testing : : Pair (
" authz_a llow_policy " ,
" allow_policy " ,
: : testing : : AllOf (
: : testing : : Field (
& Rbac : : Policy : : permissions ,
@ -353,7 +414,7 @@ TEST(GenerateRbacPoliciesTest, ParseSourceSuccess) {
EXPECT_THAT (
rbacs - > deny_policy - > policies ,
: : testing : : ElementsAre ( : : testing : : Pair (
" authz_ deny_policy" ,
" deny_policy " ,
: : testing : : AllOf (
: : testing : : Field (
& Rbac : : Policy : : permissions ,
@ -377,7 +438,7 @@ TEST(GenerateRbacPoliciesTest, ParseSourceSuccess) {
true ) ) ) ) ) ) ) ) ) ) ) ) ) ;
}
TEST ( GenerateRbacPoliciesTest , IncorrectRequestType ) {
TEST_F ( GenerateRbacPoliciesTest , IncorrectRequestType ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -394,7 +455,7 @@ TEST(GenerateRbacPoliciesTest, IncorrectRequestType) {
" deny_rules 0: \" request \" is not an object. " ) ;
}
TEST ( GenerateRbacPoliciesTest , IncorrectPathType ) {
TEST_F ( GenerateRbacPoliciesTest , IncorrectPathType ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -416,7 +477,7 @@ TEST(GenerateRbacPoliciesTest, IncorrectPathType) {
" deny_rules 0: \" paths \" 1: is not a string. " ) ;
}
TEST ( GenerateRbacPoliciesTest , ParseRequestPathsSuccess ) {
TEST_F ( GenerateRbacPoliciesTest , ParseRequestPathsSuccess ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -445,12 +506,14 @@ TEST(GenerateRbacPoliciesTest, ParseRequestPathsSuccess) {
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
ASSERT_TRUE ( rbacs . ok ( ) ) ;
EXPECT_EQ ( rbacs - > allow_policy . name , " authz " ) ;
EXPECT_EQ ( rbacs - > deny_policy - > name , " authz " ) ;
ASSERT_TRUE ( rbacs - > deny_policy . has_value ( ) ) ;
EXPECT_EQ ( rbacs - > deny_policy - > action , Rbac : : Action : : kDeny ) ;
EXPECT_THAT (
rbacs - > deny_policy - > policies ,
: : testing : : ElementsAre ( : : testing : : Pair (
" authz_ deny_policy" ,
" deny_policy " ,
: : testing : : AllOf (
: : testing : : Field (
& Rbac : : Policy : : principals ,
@ -480,7 +543,7 @@ TEST(GenerateRbacPoliciesTest, ParseRequestPathsSuccess) {
EXPECT_THAT (
rbacs - > allow_policy . policies ,
: : testing : : ElementsAre ( : : testing : : Pair (
" authz_a llow_policy " ,
" allow_policy " ,
: : testing : : AllOf (
: : testing : : Field (
& Rbac : : Policy : : principals ,
@ -504,7 +567,7 @@ TEST(GenerateRbacPoliciesTest, ParseRequestPathsSuccess) {
true ) ) ) ) ) ) ) ) ) ) ) ) ) ;
}
TEST ( GenerateRbacPoliciesTest , IncorrectHeaderType ) {
TEST_F ( GenerateRbacPoliciesTest , IncorrectHeaderType ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -525,7 +588,7 @@ TEST(GenerateRbacPoliciesTest, IncorrectHeaderType) {
" deny_rules 0: \" headers \" 0: is not an object. " ) ;
}
TEST ( GenerateRbacPoliciesTest , MissingHeaderKey ) {
TEST_F ( GenerateRbacPoliciesTest , MissingHeaderKey ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -546,7 +609,7 @@ TEST(GenerateRbacPoliciesTest, MissingHeaderKey) {
" allow_rules 0: \" headers \" 0: \" key \" is not present. " ) ;
}
TEST ( GenerateRbacPoliciesTest , MissingHeaderValues ) {
TEST_F ( GenerateRbacPoliciesTest , MissingHeaderValues ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -569,7 +632,7 @@ TEST(GenerateRbacPoliciesTest, MissingHeaderValues) {
" allow_rules 0: \" headers \" 0: \" values \" is not present. " ) ;
}
TEST ( GenerateRbacPoliciesTest , IncorrectHeaderKeyType ) {
TEST_F ( GenerateRbacPoliciesTest , IncorrectHeaderKeyType ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -593,7 +656,7 @@ TEST(GenerateRbacPoliciesTest, IncorrectHeaderKeyType) {
" allow_rules 0: \" headers \" 0: \" key \" is not a string. " ) ;
}
TEST ( GenerateRbacPoliciesTest , IncorrectHeaderValuesType ) {
TEST_F ( GenerateRbacPoliciesTest , IncorrectHeaderValuesType ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -617,7 +680,7 @@ TEST(GenerateRbacPoliciesTest, IncorrectHeaderValuesType) {
" allow_rules 0: \" headers \" 0: \" values \" is not an array. " ) ;
}
TEST ( GenerateRbacPoliciesTest , UnsupportedGrpcHeaders ) {
TEST_F ( GenerateRbacPoliciesTest , UnsupportedGrpcHeaders ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -643,7 +706,7 @@ TEST(GenerateRbacPoliciesTest, UnsupportedGrpcHeaders) {
" deny_rules 0: \" headers \" 0: Unsupported \" key \" grpc-xxx. " ) ;
}
TEST ( GenerateRbacPoliciesTest , UnsupportedPseudoHeaders ) {
TEST_F ( GenerateRbacPoliciesTest , UnsupportedPseudoHeaders ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -669,7 +732,7 @@ TEST(GenerateRbacPoliciesTest, UnsupportedPseudoHeaders) {
" allow_rules 0: \" headers \" 0: Unsupported \" key \" :method. " ) ;
}
TEST ( GenerateRbacPoliciesTest , UnsupportedHostHeader ) {
TEST_F ( GenerateRbacPoliciesTest , UnsupportedHostHeader ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -695,7 +758,7 @@ TEST(GenerateRbacPoliciesTest, UnsupportedHostHeader) {
" allow_rules 0: \" headers \" 0: Unsupported \" key \" Host. " ) ;
}
TEST ( GenerateRbacPoliciesTest , EmptyHeaderValuesList ) {
TEST_F ( GenerateRbacPoliciesTest , EmptyHeaderValuesList ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -720,7 +783,7 @@ TEST(GenerateRbacPoliciesTest, EmptyHeaderValuesList) {
" allow_rules 0: \" headers \" 0: \" values \" list is empty. " ) ;
}
TEST ( GenerateRbacPoliciesTest , ParseRequestHeadersSuccess ) {
TEST_F ( GenerateRbacPoliciesTest , ParseRequestHeadersSuccess ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -750,11 +813,12 @@ TEST(GenerateRbacPoliciesTest, ParseRequestHeadersSuccess) {
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
ASSERT_TRUE ( rbacs . ok ( ) ) ;
EXPECT_EQ ( rbacs - > allow_policy . name , " authz " ) ;
EXPECT_EQ ( rbacs - > allow_policy . action , Rbac : : Action : : kAllow ) ;
EXPECT_THAT (
rbacs - > allow_policy . policies ,
: : testing : : ElementsAre ( : : testing : : Pair (
" authz_a llow_policy " ,
" allow_policy " ,
: : testing : : AllOf (
: : testing : : Field (
& Rbac : : Policy : : principals ,
@ -810,7 +874,7 @@ TEST(GenerateRbacPoliciesTest, ParseRequestHeadersSuccess) {
false ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ;
}
TEST ( GenerateRbacPoliciesTest , ParseRulesArraySuccess ) {
TEST_F ( GenerateRbacPoliciesTest , ParseRulesArraySuccess ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -835,12 +899,13 @@ TEST(GenerateRbacPoliciesTest, ParseRulesArraySuccess) {
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
ASSERT_TRUE ( rbacs . ok ( ) ) ;
EXPECT_EQ ( rbacs - > allow_policy . name , " authz " ) ;
EXPECT_EQ ( rbacs - > allow_policy . action , Rbac : : Action : : kAllow ) ;
EXPECT_THAT (
rbacs - > allow_policy . policies ,
: : testing : : ElementsAre (
: : testing : : Pair (
" authz_a llow_policy_1 " ,
" allow_policy_1 " ,
: : testing : : AllOf (
: : testing : : Field (
& Rbac : : Policy : : permissions ,
@ -877,7 +942,7 @@ TEST(GenerateRbacPoliciesTest, ParseRulesArraySuccess) {
" spiffe://foo.abc " ,
false ) ) ) ) ) ) ) ) ) ) ) ,
: : testing : : Pair (
" authz_a llow_policy_2 " ,
" allow_policy_2 " ,
: : testing : : AllOf (
: : testing : : Field (
& Rbac : : Policy : : permissions ,
@ -889,7 +954,7 @@ TEST(GenerateRbacPoliciesTest, ParseRulesArraySuccess) {
Rbac : : Principal : : RuleType : : kAny ) ) ) ) ) ) ;
}
TEST ( GenerateRbacPoliciesTest , UnknownFieldInTopLayer ) {
TEST_F ( GenerateRbacPoliciesTest , UnknownFieldInTopLayer ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -906,7 +971,7 @@ TEST(GenerateRbacPoliciesTest, UnknownFieldInTopLayer) {
" policy contains unknown field \" foo \" . " ) ;
}
TEST ( GenerateRbacPoliciesTest , UnknownFieldInRule ) {
TEST_F ( GenerateRbacPoliciesTest , UnknownFieldInRule ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -924,7 +989,7 @@ TEST(GenerateRbacPoliciesTest, UnknownFieldInRule) {
" allow_rules 0: policy contains unknown field \" foo \" in \" rule \" . " ) ;
}
TEST ( GenerateRbacPoliciesTest , UnknownFieldInSource ) {
TEST_F ( GenerateRbacPoliciesTest , UnknownFieldInSource ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -946,7 +1011,7 @@ TEST(GenerateRbacPoliciesTest, UnknownFieldInSource) {
" allow_rules 0: policy contains unknown field \" foo \" in \" source \" . " ) ;
}
TEST ( GenerateRbacPoliciesTest , UnknownFieldInRequest ) {
TEST_F ( GenerateRbacPoliciesTest , UnknownFieldInRequest ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -964,7 +1029,7 @@ TEST(GenerateRbacPoliciesTest, UnknownFieldInRequest) {
" allow_rules 0: policy contains unknown field \" foo \" in \" request \" . " ) ;
}
TEST ( GenerateRbacPoliciesTest , UnknownFieldInHeaders ) {
TEST_F ( GenerateRbacPoliciesTest , UnknownFieldInHeaders ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
@ -984,6 +1049,452 @@ TEST(GenerateRbacPoliciesTest, UnknownFieldInHeaders) {
" \" foo \" . " ) ;
}
TEST_F ( GenerateRbacPoliciesTest , EmptyAuditLoggingOptions ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" audit_logging_options \" : {} "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
ASSERT_TRUE ( rbacs . ok ( ) ) ;
EXPECT_EQ ( rbacs - > allow_policy . name , " authz " ) ;
}
TEST_F ( GenerateRbacPoliciesTest , AuditConditionNone ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" audit_logging_options \" : { "
" \" audit_condition \" : \" NONE \" "
" } "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
ASSERT_TRUE ( rbacs . ok ( ) ) ;
EXPECT_EQ ( rbacs - > allow_policy . name , " authz " ) ;
EXPECT_EQ ( rbacs - > allow_policy . audit_condition , Rbac : : AuditCondition : : kNone ) ;
EXPECT_TRUE (
absl : : StartsWith ( rbacs - > allow_policy . ToString ( ) ,
" Rbac name=authz action=Allow audit_condition=None " ) ) ;
}
TEST_F ( GenerateRbacPoliciesTest , AuditConditionOnDeny ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" deny_rules \" : [ "
" { "
" \" name \" : \" deny_policy \" "
" } "
" ], "
" \" audit_logging_options \" : { "
" \" audit_condition \" : \" ON_DENY \" "
" } "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
ASSERT_TRUE ( rbacs . ok ( ) ) ;
EXPECT_EQ ( rbacs - > allow_policy . name , " authz " ) ;
EXPECT_EQ ( rbacs - > deny_policy - > name , " authz " ) ;
EXPECT_EQ ( rbacs - > allow_policy . audit_condition , Rbac : : AuditCondition : : kOnDeny ) ;
EXPECT_EQ ( rbacs - > deny_policy - > audit_condition , Rbac : : AuditCondition : : kOnDeny ) ;
}
TEST_F ( GenerateRbacPoliciesTest , AuditConditionOnAllowWithAuditLoggers ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" deny_rules \" : [ "
" { "
" \" name \" : \" deny_policy \" "
" } "
" ], "
" \" audit_logging_options \" : { "
" \" audit_condition \" : \" ON_ALLOW \" , "
" \" audit_loggers \" : [ "
" { "
" \" name \" : \" test_logger \" , "
" \" config \" : { "
" \" foo \" : true "
" } "
" }, "
" { "
" \" name \" : \" test_logger \" , "
" \" config \" : { "
" \" bar \" : true "
" } "
" } "
" ] "
" } "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
ASSERT_TRUE ( rbacs . ok ( ) ) ;
EXPECT_EQ ( rbacs - > allow_policy . name , " authz " ) ;
EXPECT_EQ ( rbacs - > deny_policy - > name , " authz " ) ;
EXPECT_EQ ( rbacs - > allow_policy . audit_condition ,
Rbac : : AuditCondition : : kOnAllow ) ;
EXPECT_EQ ( rbacs - > deny_policy - > audit_condition , Rbac : : AuditCondition : : kNone ) ;
ASSERT_EQ ( rbacs - > allow_policy . logger_configs . size ( ) , 2 ) ;
EXPECT_EQ ( rbacs - > deny_policy - > logger_configs . size ( ) , 0 ) ;
EXPECT_EQ ( rbacs - > allow_policy . logger_configs . at ( 0 ) - > name ( ) , kLoggerName ) ;
EXPECT_EQ ( rbacs - > allow_policy . logger_configs . at ( 1 ) - > name ( ) , kLoggerName ) ;
EXPECT_EQ ( rbacs - > allow_policy . logger_configs . at ( 0 ) - > ToString ( ) ,
" { \" foo \" :true} " ) ;
EXPECT_EQ ( rbacs - > allow_policy . logger_configs . at ( 1 ) - > ToString ( ) ,
" { \" bar \" :true} " ) ;
EXPECT_EQ ( rbacs - > allow_policy . ToString ( ) ,
" Rbac name=authz action=Allow audit_condition=OnAllow{ \n { \n "
" policy_name=allow_policy \n Policy { \n Permissions{any} \n "
" Principals{any} \n } \n } \n { \n "
" audit_logger=test_logger \n { \" foo \" :true} \n } \n { \n "
" audit_logger=test_logger \n { \" bar \" :true} \n } \n } " ) ;
}
TEST_F ( GenerateRbacPoliciesTest ,
AuditConditionOnDenyAndAllowWithUnsupportedButOptionalLogger ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" deny_rules \" : [ "
" { "
" \" name \" : \" deny_policy \" "
" } "
" ], "
" \" audit_logging_options \" : { "
" \" audit_condition \" : \" ON_DENY_AND_ALLOW \" , "
" \" audit_loggers \" : [ "
" { "
" \" name \" : \" unknown_logger \" , "
" \" is_optional \" : true, "
" \" config \" : {} "
" } "
" ] "
" } "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
ASSERT_TRUE ( rbacs . ok ( ) ) ;
EXPECT_EQ ( rbacs - > allow_policy . name , " authz " ) ;
EXPECT_EQ ( rbacs - > deny_policy - > name , " authz " ) ;
EXPECT_EQ ( rbacs - > allow_policy . audit_condition ,
Rbac : : AuditCondition : : kOnDenyAndAllow ) ;
EXPECT_EQ ( rbacs - > deny_policy - > audit_condition , Rbac : : AuditCondition : : kOnDeny ) ;
EXPECT_EQ ( rbacs - > allow_policy . logger_configs . size ( ) , 0 ) ;
EXPECT_EQ ( rbacs - > deny_policy - > logger_configs . size ( ) , 0 ) ;
}
TEST_F ( GenerateRbacPoliciesTest , UnknownFieldInAuditLoggingOptions ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" audit_logging_options \" : { "
" \" foo \" : 123 "
" } "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
EXPECT_EQ ( rbacs . status ( ) . code ( ) , absl : : StatusCode : : kInvalidArgument ) ;
EXPECT_THAT (
rbacs . status ( ) . message ( ) ,
" policy contains unknown field \" foo \" in \" audit_logging_options \" . " ) ;
}
TEST_F ( GenerateRbacPoliciesTest , AuditConditionIsNotString ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" audit_logging_options \" : { "
" \" audit_condition \" : 123 "
" } "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
EXPECT_EQ ( rbacs . status ( ) . code ( ) , absl : : StatusCode : : kInvalidArgument ) ;
EXPECT_THAT ( rbacs . status ( ) . message ( ) , " \" audit_condition \" is not a string. " ) ;
}
TEST_F ( GenerateRbacPoliciesTest , IncorrectAuditConditionValue ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" audit_logging_options \" : { "
" \" audit_condition \" : \" UNKNOWN \" "
" } "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
EXPECT_EQ ( rbacs . status ( ) . code ( ) , absl : : StatusCode : : kInvalidArgument ) ;
EXPECT_THAT ( rbacs . status ( ) . message ( ) ,
" Unsupported \" audit_condition \" value UNKNOWN. " ) ;
}
TEST_F ( GenerateRbacPoliciesTest , IncorrectAuditLoggersType ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" audit_logging_options \" : { "
" \" audit_loggers \" : 123 "
" } "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
EXPECT_EQ ( rbacs . status ( ) . code ( ) , absl : : StatusCode : : kInvalidArgument ) ;
EXPECT_THAT ( rbacs . status ( ) . message ( ) , " \" audit_loggers \" is not an array. " ) ;
}
TEST_F ( GenerateRbacPoliciesTest , IncorrectAuditLoggerType ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" audit_logging_options \" : { "
" \" audit_loggers \" : [123] "
" } "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
EXPECT_EQ ( rbacs . status ( ) . code ( ) , absl : : StatusCode : : kInvalidArgument ) ;
EXPECT_THAT ( rbacs . status ( ) . message ( ) ,
" \" audit_loggers[0] \" is not an object. " ) ;
}
TEST_F ( GenerateRbacPoliciesTest , UnknownFieldInAuditLoggers ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" audit_logging_options \" : { "
" \" audit_loggers \" : [ "
" { "
" \" foo \" : 123 "
" } "
" ] "
" } "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
EXPECT_EQ ( rbacs . status ( ) . code ( ) , absl : : StatusCode : : kInvalidArgument ) ;
EXPECT_THAT ( rbacs . status ( ) . message ( ) ,
" policy contains unknown field \" foo \" in "
" \" audit_logging_options.audit_loggers[0] \" . " ) ;
}
TEST_F ( GenerateRbacPoliciesTest , IncorrectAuditLoggerConfigType ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" audit_logging_options \" : { "
" \" audit_loggers \" : [ "
" { "
" \" name \" : \" unknown_logger \" , "
" \" config \" : 123 "
" } "
" ] "
" } "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
EXPECT_EQ ( rbacs . status ( ) . code ( ) , absl : : StatusCode : : kInvalidArgument ) ;
EXPECT_THAT ( rbacs . status ( ) . message ( ) ,
" \" audit_loggers[0].config \" is not an object. " ) ;
}
TEST_F ( GenerateRbacPoliciesTest , BadAuditLoggerConfig ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" audit_logging_options \" : { "
" \" audit_loggers \" : [ "
" { "
" \" name \" : \" test_logger \" , "
" \" config \" : { \" bad \" : true} "
" } "
" ] "
" } "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
EXPECT_EQ ( rbacs . status ( ) . code ( ) , absl : : StatusCode : : kInvalidArgument ) ;
EXPECT_THAT ( rbacs . status ( ) . message ( ) ,
" \" audit_loggers[0] \" bad logger config. " ) ;
}
TEST_F ( GenerateRbacPoliciesTest , IncorrectAuditLoggerNameType ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" audit_logging_options \" : { "
" \" audit_loggers \" : [ "
" { "
" \" name \" : 123, "
" \" config \" : {} "
" } "
" ] "
" } "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
EXPECT_EQ ( rbacs . status ( ) . code ( ) , absl : : StatusCode : : kInvalidArgument ) ;
EXPECT_THAT ( rbacs . status ( ) . message ( ) ,
" \" audit_loggers[0].name \" is not a string. " ) ;
}
TEST_F ( GenerateRbacPoliciesTest , IncorrectAuditLoggerIsOptionalType ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" audit_logging_options \" : { "
" \" audit_loggers \" : [ "
" { "
" \" name \" : \" test_logger \" , "
" \" is_optional \" : 123, "
" \" config \" : {} "
" } "
" ] "
" } "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
EXPECT_EQ ( rbacs . status ( ) . code ( ) , absl : : StatusCode : : kInvalidArgument ) ;
EXPECT_THAT ( rbacs . status ( ) . message ( ) ,
" \" audit_loggers[0].is_optional \" is not a boolean. " ) ;
}
TEST_F ( GenerateRbacPoliciesTest , MissingAuditLoggerName ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" audit_logging_options \" : { "
" \" audit_loggers \" : [ "
" { "
" \" config \" : {} "
" } "
" ] "
" } "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
EXPECT_EQ ( rbacs . status ( ) . code ( ) , absl : : StatusCode : : kInvalidArgument ) ;
EXPECT_THAT ( rbacs . status ( ) . message ( ) ,
" \" audit_loggers[0].name \" is required. " ) ;
}
TEST_F ( GenerateRbacPoliciesTest , MissingAuditLoggerConfig ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" audit_logging_options \" : { "
" \" audit_condition \" : \" ON_DENY \" , "
" \" audit_loggers \" : [ "
" { "
" \" name \" : \" test_logger \" "
" } "
" ] "
" } "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
ASSERT_TRUE ( rbacs . ok ( ) ) ;
EXPECT_EQ ( rbacs - > allow_policy . name , " authz " ) ;
EXPECT_EQ ( rbacs - > allow_policy . audit_condition , Rbac : : AuditCondition : : kOnDeny ) ;
EXPECT_EQ ( rbacs - > allow_policy . logger_configs . size ( ) , 1 ) ;
EXPECT_EQ ( rbacs - > allow_policy . logger_configs . at ( 0 ) - > name ( ) , kLoggerName ) ;
EXPECT_EQ ( rbacs - > allow_policy . logger_configs . at ( 0 ) - > ToString ( ) , " {} " ) ;
}
TEST_F ( GenerateRbacPoliciesTest , UnsupportedAuditLogger ) {
const char * authz_policy =
" { "
" \" name \" : \" authz \" , "
" \" allow_rules \" : [ "
" { "
" \" name \" : \" allow_policy \" "
" } "
" ], "
" \" audit_logging_options \" : { "
" \" audit_loggers \" : [ "
" { "
" \" name \" : \" unknown_logger \" , "
" \" config \" : {} "
" } "
" ] "
" } "
" } " ;
auto rbacs = GenerateRbacPolicies ( authz_policy ) ;
EXPECT_EQ ( rbacs . status ( ) . code ( ) , absl : : StatusCode : : kInvalidArgument ) ;
EXPECT_THAT ( rbacs . status ( ) . message ( ) ,
" \" audit_loggers[0].name \" unknown_logger is not supported "
" natively or registered. " ) ;
}
} // namespace grpc_core
int main ( int argc , char * * argv ) {