This reverts commit 1fb4f715db
.
reviewable/pr25964/r1
parent
4f81c3b706
commit
8489a6050b
22 changed files with 292 additions and 1253 deletions
@ -1,202 +0,0 @@ |
|||||||
// 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
|
|
@ -1,206 +0,0 @@ |
|||||||
// 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
|
|
@ -1,454 +0,0 @@ |
|||||||
// 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; |
|
||||||
} |
|
@ -0,0 +1,119 @@ |
|||||||
|
// 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
|
@ -0,0 +1,31 @@ |
|||||||
|
// 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
|
@ -1,59 +0,0 @@ |
|||||||
// 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