1 // 2 // Copyright 2022 gRPC authors. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #ifndef GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_CHANNEL_CREDS_REGISTRY_H 18 #define GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_CHANNEL_CREDS_REGISTRY_H 19 20 #include <grpc/support/port_platform.h> 21 22 #include <map> 23 #include <memory> 24 #include <type_traits> 25 #include <utility> 26 27 #include "absl/strings/string_view.h" 28 #include "src/core/util/json/json.h" 29 #include "src/core/util/json/json_args.h" 30 #include "src/core/util/ref_counted.h" 31 #include "src/core/util/ref_counted_ptr.h" 32 #include "src/core/util/validation_errors.h" 33 34 struct grpc_channel_credentials; 35 36 namespace grpc_core { 37 38 class ChannelCredsConfig : public RefCounted<ChannelCredsConfig> { 39 public: 40 virtual absl::string_view type() const = 0; 41 42 virtual bool Equals(const ChannelCredsConfig& other) const = 0; 43 44 virtual Json ToJson() const = 0; 45 }; 46 47 template <typename T = grpc_channel_credentials> 48 class ChannelCredsFactory final { 49 public: ~ChannelCredsFactory()50 virtual ~ChannelCredsFactory() {} 51 virtual absl::string_view type() const = delete; 52 virtual RefCountedPtr<ChannelCredsConfig> ParseConfig( 53 const Json& config, const JsonArgs& args, 54 ValidationErrors* errors) const = delete; 55 virtual RefCountedPtr<T> CreateChannelCreds( 56 RefCountedPtr<ChannelCredsConfig> config) const = delete; 57 }; 58 59 template <> 60 class ChannelCredsFactory<grpc_channel_credentials> { 61 public: ~ChannelCredsFactory()62 virtual ~ChannelCredsFactory() {} 63 virtual absl::string_view type() const = 0; 64 virtual RefCountedPtr<ChannelCredsConfig> ParseConfig( 65 const Json& config, const JsonArgs& args, 66 ValidationErrors* errors) const = 0; 67 virtual RefCountedPtr<grpc_channel_credentials> CreateChannelCreds( 68 RefCountedPtr<ChannelCredsConfig> config) const = 0; 69 }; 70 71 template <typename T = grpc_channel_credentials> 72 class ChannelCredsRegistry { 73 private: 74 using FactoryMap = 75 std::map<absl::string_view, std::unique_ptr<ChannelCredsFactory<T>>>; 76 77 public: 78 static_assert(std::is_base_of<grpc_channel_credentials, T>::value, 79 "ChannelCredsRegistry must be instantiated with " 80 "grpc_channel_credentials."); 81 82 class Builder { 83 public: RegisterChannelCredsFactory(std::unique_ptr<ChannelCredsFactory<T>> factory)84 void RegisterChannelCredsFactory( 85 std::unique_ptr<ChannelCredsFactory<T>> factory) { 86 absl::string_view type = factory->type(); 87 factories_[type] = std::move(factory); 88 } Build()89 ChannelCredsRegistry Build() { 90 return ChannelCredsRegistry<T>(std::move(factories_)); 91 } 92 93 private: 94 FactoryMap factories_; 95 }; 96 IsSupported(absl::string_view type)97 bool IsSupported(absl::string_view type) const { 98 return factories_.find(type) != factories_.end(); 99 } 100 ParseConfig(absl::string_view type,const Json & config,const JsonArgs & args,ValidationErrors * errors)101 RefCountedPtr<ChannelCredsConfig> ParseConfig( 102 absl::string_view type, const Json& config, const JsonArgs& args, 103 ValidationErrors* errors) const { 104 const auto it = factories_.find(type); 105 if (it == factories_.cend()) return nullptr; 106 return it->second->ParseConfig(config, args, errors); 107 } 108 CreateChannelCreds(RefCountedPtr<ChannelCredsConfig> config)109 RefCountedPtr<T> CreateChannelCreds( 110 RefCountedPtr<ChannelCredsConfig> config) const { 111 if (config == nullptr) return nullptr; 112 const auto it = factories_.find(config->type()); 113 if (it == factories_.cend()) return nullptr; 114 return it->second->CreateChannelCreds(std::move(config)); 115 } 116 117 private: ChannelCredsRegistry(FactoryMap factories)118 explicit ChannelCredsRegistry(FactoryMap factories) 119 : factories_(std::move(factories)) {} 120 121 FactoryMap factories_; 122 }; 123 124 } // namespace grpc_core 125 126 #endif // GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_CHANNEL_CREDS_REGISTRY_H 127