mirror of https://github.com/grpc/grpc.git
Rbac Matcher implementation. (#25653)
parent
c0a78774f8
commit
1fb4f715db
22 changed files with 1253 additions and 292 deletions
@ -0,0 +1,202 @@ |
|||||||
|
// Copyright 2021 gRPC authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <grpc/support/port_platform.h> |
||||||
|
|
||||||
|
#include "src/core/lib/security/authorization/matchers.h" |
||||||
|
|
||||||
|
namespace grpc_core { |
||||||
|
|
||||||
|
namespace { |
||||||
|
|
||||||
|
bool AuthenticatedMatchesHelper(const EvaluateArgs& args, |
||||||
|
const StringMatcher& matcher) { |
||||||
|
if (args.GetTransportSecurityType() != GRPC_SSL_TRANSPORT_SECURITY_TYPE) { |
||||||
|
// Connection is not authenticated.
|
||||||
|
return false; |
||||||
|
} |
||||||
|
if (matcher.string_matcher().empty()) { |
||||||
|
// Allows any authenticated user.
|
||||||
|
return true; |
||||||
|
} |
||||||
|
absl::string_view spiffe_id = args.GetSpiffeId(); |
||||||
|
if (!spiffe_id.empty()) { |
||||||
|
return matcher.Match(spiffe_id); |
||||||
|
} |
||||||
|
// TODO(ashithasantosh): Check principal matches DNS SAN, followed by Subject
|
||||||
|
// field from certificate. This requires updating tsi_peer to expose these
|
||||||
|
// fields.
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
std::unique_ptr<AuthorizationMatcher> AuthorizationMatcher::Create( |
||||||
|
Rbac::Permission permission) { |
||||||
|
switch (permission.type) { |
||||||
|
case Rbac::Permission::RuleType::AND: |
||||||
|
return absl::make_unique<AndAuthorizationMatcher>( |
||||||
|
std::move(permission.permissions), permission.not_rule); |
||||||
|
case Rbac::Permission::RuleType::OR: |
||||||
|
return absl::make_unique<OrAuthorizationMatcher>( |
||||||
|
std::move(permission.permissions), permission.not_rule); |
||||||
|
case Rbac::Permission::RuleType::ANY: |
||||||
|
return absl::make_unique<AlwaysAuthorizationMatcher>(permission.not_rule); |
||||||
|
case Rbac::Permission::RuleType::HEADER: |
||||||
|
return absl::make_unique<HeaderAuthorizationMatcher>( |
||||||
|
std::move(permission.header_matcher), permission.not_rule); |
||||||
|
case Rbac::Permission::RuleType::PATH: |
||||||
|
return absl::make_unique<PathAuthorizationMatcher>( |
||||||
|
std::move(permission.string_matcher), permission.not_rule); |
||||||
|
case Rbac::Permission::RuleType::DEST_IP: |
||||||
|
return absl::make_unique<IpAuthorizationMatcher>(std::move(permission.ip), |
||||||
|
permission.not_rule); |
||||||
|
case Rbac::Permission::RuleType::DEST_PORT: |
||||||
|
return absl::make_unique<PortAuthorizationMatcher>(permission.port, |
||||||
|
permission.not_rule); |
||||||
|
case Rbac::Permission::RuleType::REQ_SERVER_NAME: |
||||||
|
return absl::make_unique<ReqServerNameAuthorizationMatcher>( |
||||||
|
std::move(permission.string_matcher), permission.not_rule); |
||||||
|
} |
||||||
|
return nullptr; |
||||||
|
} |
||||||
|
|
||||||
|
std::unique_ptr<AuthorizationMatcher> AuthorizationMatcher::Create( |
||||||
|
Rbac::Principal principal) { |
||||||
|
switch (principal.type) { |
||||||
|
case Rbac::Principal::RuleType::AND: |
||||||
|
return absl::make_unique<AndAuthorizationMatcher>( |
||||||
|
std::move(principal.principals), principal.not_rule); |
||||||
|
case Rbac::Principal::RuleType::OR: |
||||||
|
return absl::make_unique<OrAuthorizationMatcher>( |
||||||
|
std::move(principal.principals), principal.not_rule); |
||||||
|
case Rbac::Principal::RuleType::ANY: |
||||||
|
return absl::make_unique<AlwaysAuthorizationMatcher>(principal.not_rule); |
||||||
|
case Rbac::Principal::RuleType::PRINCIPAL_NAME: |
||||||
|
return absl::make_unique<AuthenticatedAuthorizationMatcher>( |
||||||
|
std::move(principal.string_matcher), principal.not_rule); |
||||||
|
case Rbac::Principal::RuleType::SOURCE_IP: |
||||||
|
case Rbac::Principal::RuleType::DIRECT_REMOTE_IP: |
||||||
|
case Rbac::Principal::RuleType::REMOTE_IP: |
||||||
|
return absl::make_unique<IpAuthorizationMatcher>(std::move(principal.ip), |
||||||
|
principal.not_rule); |
||||||
|
case Rbac::Principal::RuleType::HEADER: |
||||||
|
return absl::make_unique<HeaderAuthorizationMatcher>( |
||||||
|
std::move(principal.header_matcher), principal.not_rule); |
||||||
|
case Rbac::Principal::RuleType::PATH: |
||||||
|
return absl::make_unique<PathAuthorizationMatcher>( |
||||||
|
std::move(principal.string_matcher), principal.not_rule); |
||||||
|
} |
||||||
|
return nullptr; |
||||||
|
} |
||||||
|
|
||||||
|
AndAuthorizationMatcher::AndAuthorizationMatcher( |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> rules, bool not_rule) |
||||||
|
: not_rule_(not_rule) { |
||||||
|
for (auto& rule : rules) { |
||||||
|
matchers_.push_back(AuthorizationMatcher::Create(std::move(*rule))); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
AndAuthorizationMatcher::AndAuthorizationMatcher( |
||||||
|
std::vector<std::unique_ptr<Rbac::Principal>> ids, bool not_rule) |
||||||
|
: not_rule_(not_rule) { |
||||||
|
for (const auto& id : ids) { |
||||||
|
matchers_.push_back(AuthorizationMatcher::Create(std::move(*id))); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
bool AndAuthorizationMatcher::Matches(const EvaluateArgs& args) const { |
||||||
|
bool matches = true; |
||||||
|
for (const auto& matcher : matchers_) { |
||||||
|
if (!matcher->Matches(args)) { |
||||||
|
matches = false; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
return matches != not_rule_; |
||||||
|
} |
||||||
|
|
||||||
|
OrAuthorizationMatcher::OrAuthorizationMatcher( |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> rules, bool not_rule) |
||||||
|
: not_rule_(not_rule) { |
||||||
|
for (const auto& rule : rules) { |
||||||
|
matchers_.push_back(AuthorizationMatcher::Create(std::move(*rule))); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
OrAuthorizationMatcher::OrAuthorizationMatcher( |
||||||
|
std::vector<std::unique_ptr<Rbac::Principal>> ids, bool not_rule) |
||||||
|
: not_rule_(not_rule) { |
||||||
|
for (const auto& id : ids) { |
||||||
|
matchers_.push_back(AuthorizationMatcher::Create(std::move(*id))); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
bool OrAuthorizationMatcher::Matches(const EvaluateArgs& args) const { |
||||||
|
bool matches = false; |
||||||
|
for (const auto& matcher : matchers_) { |
||||||
|
if (matcher->Matches(args)) { |
||||||
|
matches = true; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
return matches != not_rule_; |
||||||
|
} |
||||||
|
|
||||||
|
bool HeaderAuthorizationMatcher::Matches(const EvaluateArgs& args) const { |
||||||
|
std::string concatenated_value; |
||||||
|
bool matches = |
||||||
|
matcher_.Match(args.GetHeaderValue(matcher_.name(), &concatenated_value)); |
||||||
|
return matches != not_rule_; |
||||||
|
} |
||||||
|
|
||||||
|
// TODO(ashithasantosh): Implement IpAuthorizationMatcher::Matches.
|
||||||
|
bool IpAuthorizationMatcher::Matches(const EvaluateArgs&) const { |
||||||
|
bool matches = false; |
||||||
|
return matches != not_rule_; |
||||||
|
} |
||||||
|
|
||||||
|
bool PortAuthorizationMatcher::Matches(const EvaluateArgs& args) const { |
||||||
|
bool matches = (port_ == args.GetLocalPort()); |
||||||
|
return matches != not_rule_; |
||||||
|
} |
||||||
|
|
||||||
|
bool AuthenticatedAuthorizationMatcher::Matches( |
||||||
|
const EvaluateArgs& args) const { |
||||||
|
bool matches = AuthenticatedMatchesHelper(args, matcher_); |
||||||
|
return matches != not_rule_; |
||||||
|
} |
||||||
|
|
||||||
|
bool ReqServerNameAuthorizationMatcher::Matches(const EvaluateArgs&) const { |
||||||
|
// Currently we do not support matching rules containing
|
||||||
|
// "requested_server_name".
|
||||||
|
bool matches = false; |
||||||
|
return matches != not_rule_; |
||||||
|
} |
||||||
|
|
||||||
|
bool PathAuthorizationMatcher::Matches(const EvaluateArgs& args) const { |
||||||
|
bool matches = false; |
||||||
|
absl::string_view path = args.GetPath(); |
||||||
|
if (!path.empty()) { |
||||||
|
matches = matcher_.Match(path); |
||||||
|
} |
||||||
|
return matches != not_rule_; |
||||||
|
} |
||||||
|
|
||||||
|
bool PolicyAuthorizationMatcher::Matches(const EvaluateArgs& args) const { |
||||||
|
return permissions_->Matches(args) && principals_->Matches(args); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace grpc_core
|
@ -0,0 +1,206 @@ |
|||||||
|
// Copyright 2021 gRPC authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef GRPC_CORE_LIB_SECURITY_AUTHORIZATION_MATCHERS_H |
||||||
|
#define GRPC_CORE_LIB_SECURITY_AUTHORIZATION_MATCHERS_H |
||||||
|
|
||||||
|
#include <grpc/support/port_platform.h> |
||||||
|
|
||||||
|
#include <memory> |
||||||
|
|
||||||
|
#include "src/core/lib/matchers/matchers.h" |
||||||
|
#include "src/core/lib/security/authorization/evaluate_args.h" |
||||||
|
#include "src/core/lib/security/authorization/rbac_policy.h" |
||||||
|
|
||||||
|
namespace grpc_core { |
||||||
|
|
||||||
|
// Describes the rules for matching permission or principal.
|
||||||
|
class AuthorizationMatcher { |
||||||
|
public: |
||||||
|
virtual ~AuthorizationMatcher() = default; |
||||||
|
|
||||||
|
// Returns whether or not the permission/principal matches the rules of the
|
||||||
|
// matcher.
|
||||||
|
virtual bool Matches(const EvaluateArgs& args) const = 0; |
||||||
|
|
||||||
|
// Creates an instance of a matcher based off the rules defined in Permission
|
||||||
|
// config.
|
||||||
|
static std::unique_ptr<AuthorizationMatcher> Create( |
||||||
|
Rbac::Permission permission); |
||||||
|
|
||||||
|
// Creates an instance of a matcher based off the rules defined in Principal
|
||||||
|
// config.
|
||||||
|
static std::unique_ptr<AuthorizationMatcher> Create( |
||||||
|
Rbac::Principal principal); |
||||||
|
}; |
||||||
|
|
||||||
|
class AlwaysAuthorizationMatcher : public AuthorizationMatcher { |
||||||
|
public: |
||||||
|
explicit AlwaysAuthorizationMatcher(bool not_rule = false) |
||||||
|
: not_rule_(not_rule) {} |
||||||
|
|
||||||
|
bool Matches(const EvaluateArgs&) const override { return !not_rule_; } |
||||||
|
|
||||||
|
private: |
||||||
|
// Negates matching the provided permission/principal.
|
||||||
|
const bool not_rule_; |
||||||
|
}; |
||||||
|
|
||||||
|
class AndAuthorizationMatcher : public AuthorizationMatcher { |
||||||
|
public: |
||||||
|
explicit AndAuthorizationMatcher( |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> rules, |
||||||
|
bool not_rule = false); |
||||||
|
explicit AndAuthorizationMatcher( |
||||||
|
std::vector<std::unique_ptr<Rbac::Principal>> ids, bool not_rule = false); |
||||||
|
|
||||||
|
bool Matches(const EvaluateArgs& args) const override; |
||||||
|
|
||||||
|
private: |
||||||
|
std::vector<std::unique_ptr<AuthorizationMatcher>> matchers_; |
||||||
|
// Negates matching the provided permission/principal.
|
||||||
|
const bool not_rule_; |
||||||
|
}; |
||||||
|
|
||||||
|
class OrAuthorizationMatcher : public AuthorizationMatcher { |
||||||
|
public: |
||||||
|
explicit OrAuthorizationMatcher( |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> rules, |
||||||
|
bool not_rule = false); |
||||||
|
explicit OrAuthorizationMatcher( |
||||||
|
std::vector<std::unique_ptr<Rbac::Principal>> ids, bool not_rule = false); |
||||||
|
|
||||||
|
bool Matches(const EvaluateArgs& args) const override; |
||||||
|
|
||||||
|
private: |
||||||
|
std::vector<std::unique_ptr<AuthorizationMatcher>> matchers_; |
||||||
|
// Negates matching the provided permission/principal.
|
||||||
|
const bool not_rule_; |
||||||
|
}; |
||||||
|
|
||||||
|
// TODO(ashithasantosh): Add matcher implementation for metadata field.
|
||||||
|
|
||||||
|
// Perform a match against HTTP headers.
|
||||||
|
class HeaderAuthorizationMatcher : public AuthorizationMatcher { |
||||||
|
public: |
||||||
|
explicit HeaderAuthorizationMatcher(HeaderMatcher matcher, |
||||||
|
bool not_rule = false) |
||||||
|
: matcher_(std::move(matcher)), not_rule_(not_rule) {} |
||||||
|
|
||||||
|
bool Matches(const EvaluateArgs& args) const override; |
||||||
|
|
||||||
|
private: |
||||||
|
const HeaderMatcher matcher_; |
||||||
|
// Negates matching the provided permission/principal.
|
||||||
|
const bool not_rule_; |
||||||
|
}; |
||||||
|
|
||||||
|
// Perform a match against IP Cidr Range.
|
||||||
|
// TODO(ashithasantosh): Handle type of Ip or use seperate matchers for each
|
||||||
|
// type. Implement Match functionality, this would require updating EvaluateArgs
|
||||||
|
// getters, to return format of IP as well.
|
||||||
|
class IpAuthorizationMatcher : public AuthorizationMatcher { |
||||||
|
public: |
||||||
|
explicit IpAuthorizationMatcher(Rbac::CidrRange range, bool not_rule = false) |
||||||
|
: range_(std::move(range)), not_rule_(not_rule) {} |
||||||
|
|
||||||
|
bool Matches(const EvaluateArgs&) const override; |
||||||
|
|
||||||
|
private: |
||||||
|
const Rbac::CidrRange range_; |
||||||
|
// Negates matching the provided permission/principal.
|
||||||
|
const bool not_rule_; |
||||||
|
}; |
||||||
|
|
||||||
|
// Perform a match against port number of the destination (local) address.
|
||||||
|
class PortAuthorizationMatcher : public AuthorizationMatcher { |
||||||
|
public: |
||||||
|
explicit PortAuthorizationMatcher(int port, bool not_rule = false) |
||||||
|
: port_(port), not_rule_(not_rule) {} |
||||||
|
|
||||||
|
bool Matches(const EvaluateArgs& args) const override; |
||||||
|
|
||||||
|
private: |
||||||
|
const int port_; |
||||||
|
// Negates matching the provided permission/principal.
|
||||||
|
const bool not_rule_; |
||||||
|
}; |
||||||
|
|
||||||
|
// Matches the principal name as described in the peer certificate. Uses URI SAN
|
||||||
|
// or DNS SAN in that order, otherwise uses subject field.
|
||||||
|
class AuthenticatedAuthorizationMatcher : public AuthorizationMatcher { |
||||||
|
public: |
||||||
|
explicit AuthenticatedAuthorizationMatcher(StringMatcher auth, |
||||||
|
bool not_rule = false) |
||||||
|
: matcher_(std::move(auth)), not_rule_(not_rule) {} |
||||||
|
|
||||||
|
bool Matches(const EvaluateArgs& args) const override; |
||||||
|
|
||||||
|
private: |
||||||
|
const StringMatcher matcher_; |
||||||
|
// Negates matching the provided permission/principal.
|
||||||
|
const bool not_rule_; |
||||||
|
}; |
||||||
|
|
||||||
|
// Perform a match against the request server from the client's connection
|
||||||
|
// request. This is typically TLS SNI. Currently unsupported.
|
||||||
|
class ReqServerNameAuthorizationMatcher : public AuthorizationMatcher { |
||||||
|
public: |
||||||
|
explicit ReqServerNameAuthorizationMatcher( |
||||||
|
StringMatcher requested_server_name, bool not_rule = false) |
||||||
|
: matcher_(std::move(requested_server_name)), not_rule_(not_rule) {} |
||||||
|
|
||||||
|
bool Matches(const EvaluateArgs&) const override; |
||||||
|
|
||||||
|
private: |
||||||
|
const StringMatcher matcher_; |
||||||
|
// Negates matching the provided permission/principal.
|
||||||
|
const bool not_rule_; |
||||||
|
}; |
||||||
|
|
||||||
|
// Perform a match against the path header of HTTP request.
|
||||||
|
class PathAuthorizationMatcher : public AuthorizationMatcher { |
||||||
|
public: |
||||||
|
explicit PathAuthorizationMatcher(StringMatcher path, bool not_rule = false) |
||||||
|
: matcher_(std::move(path)), not_rule_(not_rule) {} |
||||||
|
|
||||||
|
bool Matches(const EvaluateArgs& args) const override; |
||||||
|
|
||||||
|
private: |
||||||
|
const StringMatcher matcher_; |
||||||
|
// Negates matching the provided permission/principal.
|
||||||
|
const bool not_rule_; |
||||||
|
}; |
||||||
|
|
||||||
|
// Performs a match for policy field in RBAC, which is a collection of
|
||||||
|
// permission and principal matchers. Policy matches iff, we find a match in one
|
||||||
|
// of its permissions and a match in one of its principals.
|
||||||
|
class PolicyAuthorizationMatcher : public AuthorizationMatcher { |
||||||
|
public: |
||||||
|
explicit PolicyAuthorizationMatcher(Rbac::Policy policy) |
||||||
|
: permissions_( |
||||||
|
AuthorizationMatcher::Create(std::move(policy.permissions))), |
||||||
|
principals_( |
||||||
|
AuthorizationMatcher::Create(std::move(policy.principals))) {} |
||||||
|
|
||||||
|
bool Matches(const EvaluateArgs& args) const override; |
||||||
|
|
||||||
|
private: |
||||||
|
std::unique_ptr<AuthorizationMatcher> permissions_; |
||||||
|
std::unique_ptr<AuthorizationMatcher> principals_; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace grpc_core
|
||||||
|
|
||||||
|
#endif // GRPC_CORE_LIB_SECURITY_AUTHORIZATION_MATCHERS_H
|
@ -0,0 +1,454 @@ |
|||||||
|
// Copyright 2021 gRPC authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <grpc/support/port_platform.h> |
||||||
|
|
||||||
|
#include <list> |
||||||
|
|
||||||
|
#include <gmock/gmock.h> |
||||||
|
#include <gtest/gtest.h> |
||||||
|
|
||||||
|
#include "src/core/lib/security/authorization/evaluate_args.h" |
||||||
|
#include "src/core/lib/security/authorization/matchers.h" |
||||||
|
#include "test/core/util/mock_eval_args_endpoint.h" |
||||||
|
|
||||||
|
namespace grpc_core { |
||||||
|
|
||||||
|
class AuthorizationMatchersTest : public ::testing::Test { |
||||||
|
protected: |
||||||
|
void SetUp() override { grpc_metadata_batch_init(&metadata_); } |
||||||
|
|
||||||
|
void TearDown() override { grpc_metadata_batch_destroy(&metadata_); } |
||||||
|
|
||||||
|
void AddPairToMetadata(const char* key, const char* value) { |
||||||
|
metadata_storage_.emplace_back(); |
||||||
|
auto& storage = metadata_storage_.back(); |
||||||
|
ASSERT_EQ(grpc_metadata_batch_add_tail( |
||||||
|
&metadata_, &storage, |
||||||
|
grpc_mdelem_from_slices( |
||||||
|
grpc_slice_intern(grpc_slice_from_static_string(key)), |
||||||
|
grpc_slice_intern(grpc_slice_from_static_string(value)))), |
||||||
|
GRPC_ERROR_NONE); |
||||||
|
} |
||||||
|
|
||||||
|
void SetLocalEndpoint(absl::string_view local_uri) { |
||||||
|
endpoint_.SetLocalAddress(local_uri); |
||||||
|
} |
||||||
|
|
||||||
|
void SetPeerEndpoint(absl::string_view peer_uri) { |
||||||
|
endpoint_.SetPeer(peer_uri); |
||||||
|
} |
||||||
|
|
||||||
|
void AddPropertyToAuthContext(const char* name, const char* value) { |
||||||
|
auth_context_.add_cstring_property(name, value); |
||||||
|
} |
||||||
|
|
||||||
|
EvaluateArgs MakeEvaluateArgs() { |
||||||
|
return EvaluateArgs(&metadata_, &auth_context_, &endpoint_); |
||||||
|
} |
||||||
|
|
||||||
|
std::list<grpc_linked_mdelem> metadata_storage_; |
||||||
|
grpc_metadata_batch metadata_; |
||||||
|
MockEvalArgsEndpoint endpoint_{/*local_uri=*/"", /*peer_uri=*/""}; |
||||||
|
grpc_auth_context auth_context_{nullptr}; |
||||||
|
}; |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, AlwaysAuthorizationMatcher) { |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
AlwaysAuthorizationMatcher matcher; |
||||||
|
EXPECT_TRUE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, NotAlwaysAuthorizationMatcher) { |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
AlwaysAuthorizationMatcher matcher(/*not_rule=*/true); |
||||||
|
EXPECT_FALSE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, AndAuthorizationMatcherSuccessfulMatch) { |
||||||
|
AddPairToMetadata("foo", "bar"); |
||||||
|
SetLocalEndpoint("ipv4:255.255.255.255:123"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> rules; |
||||||
|
rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::HEADER, |
||||||
|
HeaderMatcher::Create(/*name=*/"foo", HeaderMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"bar") |
||||||
|
.value())); |
||||||
|
rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::DEST_PORT, /*port=*/123)); |
||||||
|
AndAuthorizationMatcher matcher(std::move(rules)); |
||||||
|
EXPECT_TRUE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, AndAuthorizationMatcherFailedMatch) { |
||||||
|
AddPairToMetadata("foo", "not_bar"); |
||||||
|
SetLocalEndpoint("ipv4:255.255.255.255:123"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> rules; |
||||||
|
rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::HEADER, |
||||||
|
HeaderMatcher::Create(/*name=*/"foo", HeaderMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"bar") |
||||||
|
.value())); |
||||||
|
rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::DEST_PORT, /*port=*/123)); |
||||||
|
AndAuthorizationMatcher matcher(std::move(rules)); |
||||||
|
// Header rule fails. Expected value "bar", got "not_bar" for key "foo".
|
||||||
|
EXPECT_FALSE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, NotAndAuthorizationMatcher) { |
||||||
|
AddPairToMetadata(":path", "/expected/foo"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
StringMatcher string_matcher = |
||||||
|
StringMatcher::Create(StringMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"/expected/foo", |
||||||
|
/*case_sensitive=*/false) |
||||||
|
.value(); |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> ids; |
||||||
|
ids.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::PATH, std::move(string_matcher))); |
||||||
|
AndAuthorizationMatcher matcher(std::move(ids), /*not_rule=*/true); |
||||||
|
EXPECT_FALSE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, OrAuthorizationMatcherSuccessfulMatch) { |
||||||
|
AddPairToMetadata("foo", "bar"); |
||||||
|
SetLocalEndpoint("ipv4:255.255.255.255:123"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
HeaderMatcher header_matcher = |
||||||
|
HeaderMatcher::Create(/*name=*/"foo", HeaderMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"bar") |
||||||
|
.value(); |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> rules; |
||||||
|
rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::HEADER, header_matcher)); |
||||||
|
rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::DEST_PORT, /*port=*/456)); |
||||||
|
OrAuthorizationMatcher matcher(std::move(rules)); |
||||||
|
// Matches as header rule matches even though port rule fails.
|
||||||
|
EXPECT_TRUE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, OrAuthorizationMatcherFailedMatch) { |
||||||
|
AddPairToMetadata("foo", "not_bar"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> rules; |
||||||
|
rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::HEADER, |
||||||
|
HeaderMatcher::Create(/*name=*/"foo", HeaderMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"bar") |
||||||
|
.value())); |
||||||
|
OrAuthorizationMatcher matcher(std::move(rules)); |
||||||
|
// Header rule fails. Expected value "bar", got "not_bar" for key "foo".
|
||||||
|
EXPECT_FALSE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, NotOrAuthorizationMatcher) { |
||||||
|
AddPairToMetadata("foo", "not_bar"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> rules; |
||||||
|
rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::HEADER, |
||||||
|
HeaderMatcher::Create(/*name=*/"foo", HeaderMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"bar") |
||||||
|
.value())); |
||||||
|
OrAuthorizationMatcher matcher(std::move(rules), /*not_rule=*/true); |
||||||
|
EXPECT_TRUE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, HybridAuthorizationMatcherSuccessfulMatch) { |
||||||
|
AddPairToMetadata("foo", "bar"); |
||||||
|
SetLocalEndpoint("ipv4:255.255.255.255:123"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> sub_and_rules; |
||||||
|
sub_and_rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::HEADER, |
||||||
|
HeaderMatcher::Create(/*name=*/"foo", HeaderMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"bar") |
||||||
|
.value())); |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> sub_or_rules; |
||||||
|
sub_or_rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::DEST_PORT, /*port=*/123)); |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> and_rules; |
||||||
|
and_rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::AND, std::move(sub_and_rules))); |
||||||
|
and_rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::OR, std::move(std::move(sub_or_rules)))); |
||||||
|
AndAuthorizationMatcher matcher(std::move(and_rules)); |
||||||
|
EXPECT_TRUE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, HybridAuthorizationMatcherFailedMatch) { |
||||||
|
AddPairToMetadata("foo", "bar"); |
||||||
|
SetLocalEndpoint("ipv4:255.255.255.255:123"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> sub_and_rules; |
||||||
|
sub_and_rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::HEADER, |
||||||
|
HeaderMatcher::Create(/*name=*/"foo", HeaderMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"bar") |
||||||
|
.value())); |
||||||
|
sub_and_rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::HEADER, |
||||||
|
HeaderMatcher::Create(/*name=*/"absent_key", HeaderMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"some_value") |
||||||
|
.value())); |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> sub_or_rules; |
||||||
|
sub_or_rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::DEST_PORT, /*port=*/123)); |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> and_rules; |
||||||
|
and_rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::AND, std::move(sub_and_rules))); |
||||||
|
and_rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::OR, std::move(std::move(sub_or_rules)))); |
||||||
|
AndAuthorizationMatcher matcher(std::move(and_rules)); |
||||||
|
// Fails as "absent_key" header was not present.
|
||||||
|
EXPECT_FALSE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, PathAuthorizationMatcherSuccessfulMatch) { |
||||||
|
AddPairToMetadata(":path", "expected/path"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
PathAuthorizationMatcher matcher( |
||||||
|
StringMatcher::Create(StringMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"expected/path", |
||||||
|
/*case_sensitive=*/false) |
||||||
|
.value()); |
||||||
|
EXPECT_TRUE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, PathAuthorizationMatcherFailedMatch) { |
||||||
|
AddPairToMetadata(":path", "different/path"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
PathAuthorizationMatcher matcher( |
||||||
|
StringMatcher::Create(StringMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"expected/path", |
||||||
|
/*case_sensitive=*/false) |
||||||
|
.value()); |
||||||
|
EXPECT_FALSE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, NotPathAuthorizationMatcher) { |
||||||
|
AddPairToMetadata(":path", "expected/path"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
PathAuthorizationMatcher matcher( |
||||||
|
StringMatcher::Create(StringMatcher::Type::EXACT, "expected/path", false) |
||||||
|
.value(), |
||||||
|
/*not_rule=*/true); |
||||||
|
EXPECT_FALSE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, |
||||||
|
PathAuthorizationMatcherFailedMatchMissingPath) { |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
PathAuthorizationMatcher matcher( |
||||||
|
StringMatcher::Create(StringMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"expected/path", |
||||||
|
/*case_sensitive=*/false) |
||||||
|
.value()); |
||||||
|
EXPECT_FALSE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, HeaderAuthorizationMatcherSuccessfulMatch) { |
||||||
|
AddPairToMetadata("key123", "foo_xxx"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
HeaderAuthorizationMatcher matcher( |
||||||
|
HeaderMatcher::Create(/*name=*/"key123", HeaderMatcher::Type::PREFIX, |
||||||
|
/*matcher=*/"foo") |
||||||
|
.value()); |
||||||
|
EXPECT_TRUE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, HeaderAuthorizationMatcherFailedMatch) { |
||||||
|
AddPairToMetadata("key123", "foo"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
HeaderAuthorizationMatcher matcher( |
||||||
|
HeaderMatcher::Create(/*name=*/"key123", HeaderMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"bar") |
||||||
|
.value()); |
||||||
|
EXPECT_FALSE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, |
||||||
|
HeaderAuthorizationMatcherFailedMatchMultivaluedHeader) { |
||||||
|
AddPairToMetadata("key123", "foo"); |
||||||
|
AddPairToMetadata("key123", "bar"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
HeaderAuthorizationMatcher matcher( |
||||||
|
HeaderMatcher::Create(/*name=*/"key123", HeaderMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"foo") |
||||||
|
.value()); |
||||||
|
EXPECT_FALSE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, |
||||||
|
HeaderAuthorizationMatcherFailedMatchMissingHeader) { |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
HeaderAuthorizationMatcher matcher( |
||||||
|
HeaderMatcher::Create(/*name=*/"key123", HeaderMatcher::Type::SUFFIX, |
||||||
|
/*matcher=*/"foo") |
||||||
|
.value()); |
||||||
|
EXPECT_FALSE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, NotHeaderAuthorizationMatcher) { |
||||||
|
AddPairToMetadata("key123", "foo"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
HeaderAuthorizationMatcher matcher( |
||||||
|
HeaderMatcher::Create(/*name=*/"key123", HeaderMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"bar") |
||||||
|
.value(), |
||||||
|
/*not_rule=*/true); |
||||||
|
EXPECT_TRUE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, PortAuthorizationMatcherSuccessfulMatch) { |
||||||
|
SetLocalEndpoint("ipv4:255.255.255.255:123"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
PortAuthorizationMatcher matcher(/*port=*/123); |
||||||
|
EXPECT_TRUE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, PortAuthorizationMatcherFailedMatch) { |
||||||
|
SetLocalEndpoint("ipv4:255.255.255.255:123"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
PortAuthorizationMatcher matcher(/*port=*/456); |
||||||
|
EXPECT_FALSE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, NotPortAuthorizationMatcher) { |
||||||
|
SetLocalEndpoint("ipv4:255.255.255.255:123"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
PortAuthorizationMatcher matcher(/*port=*/123, /*not_rule=*/true); |
||||||
|
EXPECT_FALSE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, |
||||||
|
AuthenticatedMatcherUnAuthenticatedConnection) { |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
AuthenticatedAuthorizationMatcher matcher( |
||||||
|
StringMatcher::Create(StringMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"foo.com", |
||||||
|
/*case_sensitive=*/false) |
||||||
|
.value()); |
||||||
|
EXPECT_FALSE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, |
||||||
|
AuthenticatedMatcherAuthenticatedConnectionMatcherUnset) { |
||||||
|
AddPropertyToAuthContext(GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, |
||||||
|
GRPC_SSL_TRANSPORT_SECURITY_TYPE); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
AuthenticatedAuthorizationMatcher matcher( |
||||||
|
StringMatcher::Create(StringMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"", |
||||||
|
/*case_sensitive=*/false) |
||||||
|
.value()); |
||||||
|
EXPECT_TRUE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, |
||||||
|
AuthenticatedMatcherSuccessfulSpiffeIdMatches) { |
||||||
|
AddPropertyToAuthContext(GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, |
||||||
|
GRPC_SSL_TRANSPORT_SECURITY_TYPE); |
||||||
|
AddPropertyToAuthContext(GRPC_PEER_SPIFFE_ID_PROPERTY_NAME, |
||||||
|
"spiffe://foo.abc"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
AuthenticatedAuthorizationMatcher matcher( |
||||||
|
StringMatcher::Create(StringMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"spiffe://foo.abc", |
||||||
|
/*case_sensitive=*/false) |
||||||
|
.value()); |
||||||
|
EXPECT_TRUE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, AuthenticatedMatcherFailedSpiffeIdMatches) { |
||||||
|
AddPropertyToAuthContext(GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, |
||||||
|
GRPC_SSL_TRANSPORT_SECURITY_TYPE); |
||||||
|
AddPropertyToAuthContext(GRPC_PEER_SPIFFE_ID_PROPERTY_NAME, |
||||||
|
"spiffe://bar.abc"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
AuthenticatedAuthorizationMatcher matcher( |
||||||
|
StringMatcher::Create(StringMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"spiffe://foo.abc", |
||||||
|
/*case_sensitive=*/false) |
||||||
|
.value()); |
||||||
|
EXPECT_FALSE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, AuthenticatedMatcherFailedNothingMatches) { |
||||||
|
AddPropertyToAuthContext(GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, |
||||||
|
GRPC_SSL_TRANSPORT_SECURITY_TYPE); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
AuthenticatedAuthorizationMatcher matcher( |
||||||
|
StringMatcher::Create(StringMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"foo", |
||||||
|
/*case_sensitive=*/false) |
||||||
|
.value()); |
||||||
|
EXPECT_FALSE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, NotAuthenticatedMatcher) { |
||||||
|
AddPropertyToAuthContext(GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, |
||||||
|
GRPC_SSL_TRANSPORT_SECURITY_TYPE); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
AuthenticatedAuthorizationMatcher matcher( |
||||||
|
StringMatcher::Create(StringMatcher::Type::EXACT, /*matcher=*/"foo", |
||||||
|
/*case_sensitive=*/false) |
||||||
|
.value(), |
||||||
|
/*not_rule=*/true); |
||||||
|
EXPECT_TRUE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, PolicyAuthorizationMatcherSuccessfulMatch) { |
||||||
|
AddPairToMetadata("key123", "foo"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> rules; |
||||||
|
rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::HEADER, |
||||||
|
HeaderMatcher::Create(/*name=*/"key123", HeaderMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"foo") |
||||||
|
.value())); |
||||||
|
PolicyAuthorizationMatcher matcher(Rbac::Policy( |
||||||
|
Rbac::Permission(Rbac::Permission::RuleType::OR, std::move(rules)), |
||||||
|
Rbac::Principal(Rbac::Principal::RuleType::ANY))); |
||||||
|
EXPECT_TRUE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
TEST_F(AuthorizationMatchersTest, PolicyAuthorizationMatcherFailedMatch) { |
||||||
|
AddPairToMetadata("key123", "foo"); |
||||||
|
EvaluateArgs args = MakeEvaluateArgs(); |
||||||
|
std::vector<std::unique_ptr<Rbac::Permission>> rules; |
||||||
|
rules.push_back(absl::make_unique<Rbac::Permission>( |
||||||
|
Rbac::Permission::RuleType::HEADER, |
||||||
|
HeaderMatcher::Create(/*name=*/"key123", HeaderMatcher::Type::EXACT, |
||||||
|
/*matcher=*/"bar") |
||||||
|
.value())); |
||||||
|
PolicyAuthorizationMatcher matcher(Rbac::Policy( |
||||||
|
Rbac::Permission(Rbac::Permission::RuleType::OR, std::move(rules)), |
||||||
|
Rbac::Principal(Rbac::Principal::RuleType::ANY))); |
||||||
|
EXPECT_FALSE(matcher.Matches(args)); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace grpc_core
|
||||||
|
|
||||||
|
int main(int argc, char** argv) { |
||||||
|
::testing::InitGoogleTest(&argc, argv); |
||||||
|
grpc_init(); |
||||||
|
int ret = RUN_ALL_TESTS(); |
||||||
|
grpc_shutdown(); |
||||||
|
return ret; |
||||||
|
} |
@ -1,119 +0,0 @@ |
|||||||
// Copyright 2020 gRPC authors.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include <grpc/support/port_platform.h> |
|
||||||
|
|
||||||
#include "test/core/util/eval_args_mock_endpoint.h" |
|
||||||
|
|
||||||
#include <inttypes.h> |
|
||||||
|
|
||||||
#include <string> |
|
||||||
|
|
||||||
#include "absl/strings/str_format.h" |
|
||||||
|
|
||||||
#include <grpc/support/alloc.h> |
|
||||||
#include <grpc/support/string_util.h> |
|
||||||
#include "src/core/lib/iomgr/sockaddr.h" |
|
||||||
#include "src/core/lib/iomgr/sockaddr_utils.h" |
|
||||||
|
|
||||||
namespace grpc_core { |
|
||||||
|
|
||||||
class EvalArgsMockEndpoint { |
|
||||||
public: |
|
||||||
EvalArgsMockEndpoint(absl::string_view local_uri, absl::string_view peer_uri) |
|
||||||
: local_address_(local_uri), peer_(peer_uri) { |
|
||||||
base_.vtable = &vtable_; |
|
||||||
} |
|
||||||
grpc_endpoint* base() const { return const_cast<grpc_endpoint*>(&base_); } |
|
||||||
static void Read(grpc_endpoint* /*ep*/, grpc_slice_buffer* /*slices*/, |
|
||||||
grpc_closure* /*cb*/, bool /*unused*/) {} |
|
||||||
static void Write(grpc_endpoint* /*ep*/, grpc_slice_buffer* /*slices*/, |
|
||||||
grpc_closure* /*cb*/, void* /*unused*/) {} |
|
||||||
static void AddToPollset(grpc_endpoint* /*ep*/, grpc_pollset* /*unused*/) {} |
|
||||||
static void AddToPollsetSet(grpc_endpoint* /*ep*/, |
|
||||||
grpc_pollset_set* /*unused*/) {} |
|
||||||
static void DeleteFromPollsetSet(grpc_endpoint* /*ep*/, |
|
||||||
grpc_pollset_set* /*unused*/) {} |
|
||||||
static void Shutdown(grpc_endpoint* /*ep*/, grpc_error* /*why*/) {} |
|
||||||
static void Destroy(grpc_endpoint* ep) { |
|
||||||
EvalArgsMockEndpoint* m = reinterpret_cast<EvalArgsMockEndpoint*>(ep); |
|
||||||
delete m; |
|
||||||
} |
|
||||||
|
|
||||||
static absl::string_view GetPeer(grpc_endpoint* ep) { |
|
||||||
EvalArgsMockEndpoint* m = reinterpret_cast<EvalArgsMockEndpoint*>(ep); |
|
||||||
return m->peer_; |
|
||||||
} |
|
||||||
|
|
||||||
static absl::string_view GetLocalAddress(grpc_endpoint* ep) { |
|
||||||
EvalArgsMockEndpoint* m = reinterpret_cast<EvalArgsMockEndpoint*>(ep); |
|
||||||
return m->local_address_; |
|
||||||
} |
|
||||||
|
|
||||||
static grpc_resource_user* GetResourceUser(grpc_endpoint* /*ep*/) { |
|
||||||
return nullptr; |
|
||||||
} |
|
||||||
|
|
||||||
static int GetFd(grpc_endpoint* /*unused*/) { return -1; } |
|
||||||
static bool CanTrackErr(grpc_endpoint* /*unused*/) { return false; } |
|
||||||
|
|
||||||
private: |
|
||||||
static constexpr grpc_endpoint_vtable vtable_ = { |
|
||||||
EvalArgsMockEndpoint::Read, |
|
||||||
EvalArgsMockEndpoint::Write, |
|
||||||
EvalArgsMockEndpoint::AddToPollset, |
|
||||||
EvalArgsMockEndpoint::AddToPollsetSet, |
|
||||||
EvalArgsMockEndpoint::DeleteFromPollsetSet, |
|
||||||
EvalArgsMockEndpoint::Shutdown, |
|
||||||
EvalArgsMockEndpoint::Destroy, |
|
||||||
EvalArgsMockEndpoint::GetResourceUser, |
|
||||||
EvalArgsMockEndpoint::GetPeer, |
|
||||||
EvalArgsMockEndpoint::GetLocalAddress, |
|
||||||
EvalArgsMockEndpoint::GetFd, |
|
||||||
EvalArgsMockEndpoint::CanTrackErr}; |
|
||||||
grpc_endpoint base_; |
|
||||||
std::string local_address_; |
|
||||||
std::string peer_; |
|
||||||
}; |
|
||||||
|
|
||||||
constexpr grpc_endpoint_vtable EvalArgsMockEndpoint::vtable_; |
|
||||||
|
|
||||||
namespace { |
|
||||||
|
|
||||||
std::string NameAndPortToURI(const char* addr, const int port) { |
|
||||||
grpc_sockaddr_in address; |
|
||||||
memset(&address, 0, sizeof(address)); |
|
||||||
address.sin_family = AF_INET; |
|
||||||
address.sin_port = htons(port); |
|
||||||
inet_pton(AF_INET, addr, &address.sin_addr); |
|
||||||
grpc_resolved_address resolved; |
|
||||||
memset(&resolved, 0, sizeof(resolved)); |
|
||||||
memcpy(resolved.addr, &address, sizeof(address)); |
|
||||||
resolved.len = sizeof(address); |
|
||||||
return grpc_sockaddr_to_uri(&resolved); |
|
||||||
} |
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
grpc_endpoint* CreateEvalArgsMockEndpoint(const char* local_address, |
|
||||||
const int local_port, |
|
||||||
const char* peer_address, |
|
||||||
const int peer_port) { |
|
||||||
EvalArgsMockEndpoint* m = |
|
||||||
new EvalArgsMockEndpoint(NameAndPortToURI(local_address, local_port), |
|
||||||
NameAndPortToURI(peer_address, peer_port)); |
|
||||||
return m->base(); |
|
||||||
} |
|
||||||
|
|
||||||
} // namespace grpc_core
|
|
@ -1,31 +0,0 @@ |
|||||||
// Copyright 2020 gRPC authors.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#ifndef GRPC_TEST_CORE_UTIL_EVAL_ARGS_MOCK_ENDPOINT_H |
|
||||||
#define GRPC_TEST_CORE_UTIL_EVAL_ARGS_MOCK_ENDPOINT_H |
|
||||||
|
|
||||||
#include <grpc/support/port_platform.h> |
|
||||||
|
|
||||||
#include "src/core/lib/iomgr/endpoint.h" |
|
||||||
|
|
||||||
namespace grpc_core { |
|
||||||
|
|
||||||
grpc_endpoint* CreateEvalArgsMockEndpoint(const char* local_address, |
|
||||||
const int local_port, |
|
||||||
const char* peer_address, |
|
||||||
const int peer_port); |
|
||||||
|
|
||||||
} // namespace grpc_core
|
|
||||||
|
|
||||||
#endif // GRPC_TEST_CORE_UTIL_EVAL_ARGS_MOCK_ENDPOINT_H
|
|
@ -0,0 +1,59 @@ |
|||||||
|
// Copyright 2021 gRPC authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef GRPC_TEST_CORE_UTIL_MOCK_EVAL_ARGS_ENDPOINT_H |
||||||
|
#define GRPC_TEST_CORE_UTIL_MOCK_EVAL_ARGS_ENDPOINT_H |
||||||
|
|
||||||
|
#include <grpc/support/port_platform.h> |
||||||
|
|
||||||
|
#include "src/core/lib/iomgr/endpoint.h" |
||||||
|
|
||||||
|
namespace grpc_core { |
||||||
|
|
||||||
|
class MockEvalArgsEndpoint : public grpc_endpoint { |
||||||
|
public: |
||||||
|
MockEvalArgsEndpoint(absl::string_view local_uri, absl::string_view peer_uri) |
||||||
|
: local_address_(local_uri), peer_address_(peer_uri) { |
||||||
|
static constexpr grpc_endpoint_vtable vtable = { |
||||||
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, |
||||||
|
nullptr, nullptr, GetPeer, GetLocalAddress, nullptr, nullptr}; |
||||||
|
grpc_endpoint::vtable = &vtable; |
||||||
|
} |
||||||
|
|
||||||
|
static absl::string_view GetPeer(grpc_endpoint* ep) { |
||||||
|
MockEvalArgsEndpoint* m = reinterpret_cast<MockEvalArgsEndpoint*>(ep); |
||||||
|
return m->peer_address_; |
||||||
|
} |
||||||
|
|
||||||
|
static absl::string_view GetLocalAddress(grpc_endpoint* ep) { |
||||||
|
MockEvalArgsEndpoint* m = reinterpret_cast<MockEvalArgsEndpoint*>(ep); |
||||||
|
return m->local_address_; |
||||||
|
} |
||||||
|
|
||||||
|
void SetPeer(absl::string_view peer_address) { |
||||||
|
peer_address_ = std::string(peer_address); |
||||||
|
} |
||||||
|
|
||||||
|
void SetLocalAddress(absl::string_view local_address) { |
||||||
|
local_address_ = std::string(local_address); |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
std::string local_address_; |
||||||
|
std::string peer_address_; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace grpc_core
|
||||||
|
|
||||||
|
#endif // GRPC_TEST_CORE_UTIL_MOCK_EVAL_ARGS_ENDPOINT_H
|
Loading…
Reference in new issue