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 29 #include "src/core/lib/gprpp/ref_counted.h" 30 #include "src/core/lib/gprpp/ref_counted_ptr.h" 31 #include "src/core/lib/gprpp/validation_errors.h" 32 #include "src/core/lib/json/json.h" 33 #include "src/core/lib/json/json_args.h" 34 35 struct grpc_channel_credentials; 36 37 namespace grpc_core { 38 39 class ChannelCredsConfig : public RefCounted<ChannelCredsConfig> { 40 public: 41 virtual absl::string_view type() const = 0; 42 43 virtual bool Equals(const ChannelCredsConfig& other) const = 0; 44 45 virtual Json ToJson() const = 0; 46 }; 47 48 template <typename T = grpc_channel_credentials> 49 class ChannelCredsFactory final { 50 public: ~ChannelCredsFactory()51 virtual ~ChannelCredsFactory() {} 52 virtual absl::string_view type() const = delete; 53 virtual RefCountedPtr<ChannelCredsConfig> ParseConfig( 54 const Json& config, const JsonArgs& args, 55 ValidationErrors* errors) const = delete; 56 virtual RefCountedPtr<T> CreateChannelCreds( 57 RefCountedPtr<ChannelCredsConfig> config) const = delete; 58 }; 59 60 template <> 61 class ChannelCredsFactory<grpc_channel_credentials> { 62 public: ~ChannelCredsFactory()63 virtual ~ChannelCredsFactory() {} 64 virtual absl::string_view type() const = 0; 65 virtual RefCountedPtr<ChannelCredsConfig> ParseConfig( 66 const Json& config, const JsonArgs& args, 67 ValidationErrors* errors) const = 0; 68 virtual RefCountedPtr<grpc_channel_credentials> CreateChannelCreds( 69 RefCountedPtr<ChannelCredsConfig> config) const = 0; 70 }; 71 72 template <typename T = grpc_channel_credentials> 73 class ChannelCredsRegistry { 74 private: 75 using FactoryMap = 76 std::map<absl::string_view, std::unique_ptr<ChannelCredsFactory<T>>>; 77 78 public: 79 static_assert(std::is_base_of<grpc_channel_credentials, T>::value, 80 "ChannelCredsRegistry must be instantiated with " 81 "grpc_channel_credentials."); 82 83 class Builder { 84 public: RegisterChannelCredsFactory(std::unique_ptr<ChannelCredsFactory<T>> factory)85 void RegisterChannelCredsFactory( 86 std::unique_ptr<ChannelCredsFactory<T>> factory) { 87 absl::string_view type = factory->type(); 88 factories_[type] = std::move(factory); 89 } Build()90 ChannelCredsRegistry Build() { 91 return ChannelCredsRegistry<T>(std::move(factories_)); 92 } 93 94 private: 95 FactoryMap factories_; 96 }; 97 IsSupported(absl::string_view type)98 bool IsSupported(absl::string_view type) const { 99 return factories_.find(type) != factories_.end(); 100 } 101 ParseConfig(absl::string_view type,const Json & config,const JsonArgs & args,ValidationErrors * errors)102 RefCountedPtr<ChannelCredsConfig> ParseConfig( 103 absl::string_view type, const Json& config, const JsonArgs& args, 104 ValidationErrors* errors) const { 105 const auto it = factories_.find(type); 106 if (it == factories_.cend()) return nullptr; 107 return it->second->ParseConfig(config, args, errors); 108 } 109 CreateChannelCreds(RefCountedPtr<ChannelCredsConfig> config)110 RefCountedPtr<T> CreateChannelCreds( 111 RefCountedPtr<ChannelCredsConfig> config) const { 112 if (config == nullptr) return nullptr; 113 const auto it = factories_.find(config->type()); 114 if (it == factories_.cend()) return nullptr; 115 return it->second->CreateChannelCreds(std::move(config)); 116 } 117 118 private: ChannelCredsRegistry(FactoryMap factories)119 explicit ChannelCredsRegistry(FactoryMap factories) 120 : factories_(std::move(factories)) {} 121 122 FactoryMap factories_; 123 }; 124 125 } // namespace grpc_core 126 127 #endif // GRPC_SRC_CORE_LIB_SECURITY_CREDENTIALS_CHANNEL_CREDS_REGISTRY_H 128