diff options
Diffstat (limited to 'grpc/src/core/lib/security/authorization/rbac_policy.cc')
-rw-r--r-- | grpc/src/core/lib/security/authorization/rbac_policy.cc | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/grpc/src/core/lib/security/authorization/rbac_policy.cc b/grpc/src/core/lib/security/authorization/rbac_policy.cc new file mode 100644 index 00000000..a081c514 --- /dev/null +++ b/grpc/src/core/lib/security/authorization/rbac_policy.cc @@ -0,0 +1,328 @@ +// 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/rbac_policy.h" + +#include "absl/strings/str_format.h" +#include "absl/strings/str_join.h" + +namespace grpc_core { + +// +// Rbac +// + +Rbac::Rbac(Rbac::Action action, std::map<std::string, Policy> policies) + : action(action), policies(std::move(policies)) {} + +Rbac::Rbac(Rbac&& other) noexcept + : action(other.action), policies(std::move(other.policies)) {} + +Rbac& Rbac::operator=(Rbac&& other) noexcept { + action = other.action; + policies = std::move(other.policies); + return *this; +} + +std::string Rbac::ToString() const { + std::vector<std::string> contents; + contents.push_back(absl::StrFormat( + "Rbac action=%s{", action == Rbac::Action::kAllow ? "Allow" : "Deny")); + for (const auto& p : policies) { + contents.push_back(absl::StrFormat("{\n policy_name=%s\n%s\n}", p.first, + p.second.ToString())); + } + contents.push_back("}"); + return absl::StrJoin(contents, "\n"); +} + +// +// CidrRange +// + +Rbac::CidrRange::CidrRange(std::string address_prefix, uint32_t prefix_len) + : address_prefix(std::move(address_prefix)), prefix_len(prefix_len) {} + +Rbac::CidrRange::CidrRange(Rbac::CidrRange&& other) noexcept + : address_prefix(std::move(other.address_prefix)), + prefix_len(other.prefix_len) {} + +Rbac::CidrRange& Rbac::CidrRange::operator=(Rbac::CidrRange&& other) noexcept { + address_prefix = std::move(other.address_prefix); + prefix_len = other.prefix_len; + return *this; +} + +std::string Rbac::CidrRange::ToString() const { + return absl::StrFormat("CidrRange{address_prefix=%s,prefix_len=%d}", + address_prefix, prefix_len); +} + +// +// Permission +// + +Rbac::Permission::Permission( + Permission::RuleType type, + std::vector<std::unique_ptr<Permission>> permissions, bool not_rule) + : type(type), permissions(std::move(permissions)), not_rule(not_rule) {} +Rbac::Permission::Permission(Permission::RuleType type, bool not_rule) + : type(type), not_rule(not_rule) {} +Rbac::Permission::Permission(Permission::RuleType type, + HeaderMatcher header_matcher, bool not_rule) + : type(type), + header_matcher(std::move(header_matcher)), + not_rule(not_rule) {} +Rbac::Permission::Permission(Permission::RuleType type, + StringMatcher string_matcher, bool not_rule) + : type(type), + string_matcher(std::move(string_matcher)), + not_rule(not_rule) {} +Rbac::Permission::Permission(Permission::RuleType type, CidrRange ip, + bool not_rule) + : type(type), ip(std::move(ip)), not_rule(not_rule) {} +Rbac::Permission::Permission(Permission::RuleType type, int port, bool not_rule) + : type(type), port(port), not_rule(not_rule) {} + +Rbac::Permission::Permission(Rbac::Permission&& other) noexcept + : type(other.type), not_rule(other.not_rule) { + switch (type) { + case RuleType::kAnd: + case RuleType::kOr: + permissions = std::move(other.permissions); + break; + case RuleType::kAny: + break; + case RuleType::kHeader: + header_matcher = std::move(other.header_matcher); + break; + case RuleType::kPath: + case RuleType::kReqServerName: + string_matcher = std::move(other.string_matcher); + break; + case RuleType::kDestIp: + ip = std::move(other.ip); + break; + default: + port = other.port; + } +} + +Rbac::Permission& Rbac::Permission::operator=( + Rbac::Permission&& other) noexcept { + type = other.type; + not_rule = other.not_rule; + switch (type) { + case RuleType::kAnd: + case RuleType::kOr: + permissions = std::move(other.permissions); + break; + case RuleType::kAny: + break; + case RuleType::kHeader: + header_matcher = std::move(other.header_matcher); + break; + case RuleType::kPath: + case RuleType::kReqServerName: + string_matcher = std::move(other.string_matcher); + break; + case RuleType::kDestIp: + ip = std::move(other.ip); + break; + default: + port = other.port; + } + return *this; +} + +std::string Rbac::Permission::ToString() const { + switch (type) { + case RuleType::kAnd: { + std::vector<std::string> contents; + contents.reserve(permissions.size()); + for (const auto& permission : permissions) { + contents.push_back(permission->ToString()); + } + return absl::StrFormat("%sand=[%s]", not_rule ? "not " : "", + absl::StrJoin(contents, ",")); + } + case RuleType::kOr: { + std::vector<std::string> contents; + contents.reserve(permissions.size()); + for (const auto& permission : permissions) { + contents.push_back(permission->ToString()); + } + return absl::StrFormat("%sor=[%s]", not_rule ? "not " : "", + absl::StrJoin(contents, ",")); + } + case RuleType::kAny: + return absl::StrFormat("%sany", not_rule ? "not " : ""); + case RuleType::kHeader: + return absl::StrFormat("%sheader=%s", not_rule ? "not " : "", + header_matcher.ToString()); + case RuleType::kPath: + return absl::StrFormat("%spath=%s", not_rule ? "not " : "", + string_matcher.ToString()); + case RuleType::kDestIp: + return absl::StrFormat("%sdest_ip=%s", not_rule ? "not " : "", + ip.ToString()); + case RuleType::kDestPort: + return absl::StrFormat("%sdest_port=%d", not_rule ? "not " : "", port); + case RuleType::kReqServerName: + return absl::StrFormat("%srequested_server_name=%s", + not_rule ? "not " : "", string_matcher.ToString()); + default: + return ""; + } +} + +// +// Principal +// + +Rbac::Principal::Principal(Principal::RuleType type, + std::vector<std::unique_ptr<Principal>> principals, + bool not_rule) + : type(type), principals(std::move(principals)), not_rule(not_rule) {} +Rbac::Principal::Principal(Principal::RuleType type, bool not_rule) + : type(type), not_rule(not_rule) {} +Rbac::Principal::Principal(Principal::RuleType type, + StringMatcher string_matcher, bool not_rule) + : type(type), + string_matcher(std::move(string_matcher)), + not_rule(not_rule) {} +Rbac::Principal::Principal(Principal::RuleType type, CidrRange ip, + bool not_rule) + : type(type), ip(std::move(ip)), not_rule(not_rule) {} +Rbac::Principal::Principal(Principal::RuleType type, + HeaderMatcher header_matcher, bool not_rule) + : type(type), + header_matcher(std::move(header_matcher)), + not_rule(not_rule) {} + +Rbac::Principal::Principal(Rbac::Principal&& other) noexcept + : type(other.type), not_rule(other.not_rule) { + switch (type) { + case RuleType::kAnd: + case RuleType::kOr: + principals = std::move(other.principals); + break; + case RuleType::kAny: + break; + case RuleType::kHeader: + header_matcher = std::move(other.header_matcher); + break; + case RuleType::kPrincipalName: + case RuleType::kPath: + string_matcher = std::move(other.string_matcher); + break; + default: + ip = std::move(other.ip); + } +} + +Rbac::Principal& Rbac::Principal::operator=(Rbac::Principal&& other) noexcept { + type = other.type; + not_rule = other.not_rule; + switch (type) { + case RuleType::kAnd: + case RuleType::kOr: + principals = std::move(other.principals); + break; + case RuleType::kAny: + break; + case RuleType::kHeader: + header_matcher = std::move(other.header_matcher); + break; + case RuleType::kPrincipalName: + case RuleType::kPath: + string_matcher = std::move(other.string_matcher); + break; + default: + ip = std::move(other.ip); + } + return *this; +} + +std::string Rbac::Principal::ToString() const { + switch (type) { + case RuleType::kAnd: { + std::vector<std::string> contents; + contents.reserve(principals.size()); + for (const auto& principal : principals) { + contents.push_back(principal->ToString()); + } + return absl::StrFormat("%sand=[%s]", not_rule ? "not " : "", + absl::StrJoin(contents, ",")); + } + case RuleType::kOr: { + std::vector<std::string> contents; + contents.reserve(principals.size()); + for (const auto& principal : principals) { + contents.push_back(principal->ToString()); + } + return absl::StrFormat("%sor=[%s]", not_rule ? "not " : "", + absl::StrJoin(contents, ",")); + } + case RuleType::kAny: + return absl::StrFormat("%sany", not_rule ? "not " : ""); + case RuleType::kPrincipalName: + return absl::StrFormat("%sprincipal_name=%s", not_rule ? "not " : "", + string_matcher.ToString()); + case RuleType::kSourceIp: + return absl::StrFormat("%ssource_ip=%s", not_rule ? "not " : "", + ip.ToString()); + case RuleType::kDirectRemoteIp: + return absl::StrFormat("%sdirect_remote_ip=%s", not_rule ? "not " : "", + ip.ToString()); + case RuleType::kRemoteIp: + return absl::StrFormat("%sremote_ip=%s", not_rule ? "not " : "", + ip.ToString()); + case RuleType::kHeader: + return absl::StrFormat("%sheader=%s", not_rule ? "not " : "", + header_matcher.ToString()); + case RuleType::kPath: + return absl::StrFormat("%spath=%s", not_rule ? "not " : "", + string_matcher.ToString()); + default: + return ""; + } +} + +// +// Policy +// + +Rbac::Policy::Policy(Permission permissions, Principal principals) + : permissions(std::move(permissions)), principals(std::move(principals)) {} + +Rbac::Policy::Policy(Rbac::Policy&& other) noexcept + : permissions(std::move(other.permissions)), + principals(std::move(other.principals)) {} + +Rbac::Policy& Rbac::Policy::operator=(Rbac::Policy&& other) noexcept { + permissions = std::move(other.permissions); + principals = std::move(other.principals); + return *this; +} + +std::string Rbac::Policy::ToString() const { + return absl::StrFormat( + " Policy {\n Permissions{%s}\n Principals{%s}\n }", + permissions.ToString(), principals.ToString()); +} + +} // namespace grpc_core |