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