From 114f39475fa6f28beb51f1a4265e377aa122fbdb Mon Sep 17 00:00:00 2001 From: Julien Boeuf <jboeuf@google.com> Date: Thu, 19 Nov 2015 21:45:52 -0800 Subject: [PATCH] Cpp example of how the plugins can be done. --- include/grpc++/security/credentials.h | 6 ++++++ src/cpp/client/secure_credentials.cc | 21 +++++++++++++++------ src/cpp/client/secure_credentials.h | 2 +- test/cpp/end2end/end2end_test.cc | 5 ++++- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/include/grpc++/security/credentials.h b/include/grpc++/security/credentials.h index 56827c0f21..acfc3843b3 100644 --- a/include/grpc++/security/credentials.h +++ b/include/grpc++/security/credentials.h @@ -38,6 +38,7 @@ #include <memory> #include <grpc++/impl/grpc_library.h> +#include <grpc++/security/auth_context.h> #include <grpc++/support/config.h> #include <grpc++/support/status.h> #include <grpc++/support/string_ref.h> @@ -207,9 +208,14 @@ class MetadataCredentialsPlugin { // a different thread from the one processing the call. virtual bool IsBlocking() const { return true; } + // Type of credentials this plugin is implementing. + virtual const char* GetType() const { return ""; } + // Gets the auth metatada produced by this plugin. virtual Status GetMetadata( grpc::string_ref service_url, + grpc::string_ref method_name, + const AuthContext& channel_auth_contexst, std::multimap<grpc::string, grpc::string>* metadata) = 0; }; diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index bd68228460..6409323262 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -37,6 +37,7 @@ #include <grpc++/support/channel_arguments.h> #include "src/cpp/client/create_channel_internal.h" #include "src/cpp/client/secure_credentials.h" +#include "src/cpp/common/secure_auth_context.h" namespace grpc { @@ -171,18 +172,25 @@ void MetadataCredentialsPluginWrapper::GetMetadata( } if (w->plugin_->IsBlocking()) { w->thread_pool_->Add( - std::bind(&MetadataCredentialsPluginWrapper::InvokePlugin, w, - context.service_url, cb, user_data)); + std::bind(&MetadataCredentialsPluginWrapper::InvokePlugin, w, context, + cb, user_data)); } else { - w->InvokePlugin(context.service_url, cb, user_data); + w->InvokePlugin(context, cb, user_data); } } void MetadataCredentialsPluginWrapper::InvokePlugin( - const char* service_url, grpc_credentials_plugin_metadata_cb cb, + grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void* user_data) { std::multimap<grpc::string, grpc::string> metadata; - Status status = plugin_->GetMetadata(service_url, &metadata); + + // const_cast is safe since the SecureAuthContext does not take owndership and + // the object is passed as a const ref to plugin_->GetMetadata. + SecureAuthContext cpp_channel_auth_context( + const_cast<grpc_auth_context*>(context.channel_auth_context), false); + + Status status = plugin_->GetMetadata(context.service_url, context.method_name, + cpp_channel_auth_context, &metadata); std::vector<grpc_metadata> md; for (auto it = metadata.begin(); it != metadata.end(); ++it) { grpc_metadata md_entry; @@ -204,11 +212,12 @@ MetadataCredentialsPluginWrapper::MetadataCredentialsPluginWrapper( std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin( std::unique_ptr<MetadataCredentialsPlugin> plugin) { GrpcLibrary init; // To call grpc_init(). + const char* type = plugin->GetType(); MetadataCredentialsPluginWrapper* wrapper = new MetadataCredentialsPluginWrapper(std::move(plugin)); grpc_metadata_credentials_plugin c_plugin = { MetadataCredentialsPluginWrapper::GetMetadata, - MetadataCredentialsPluginWrapper::Destroy, wrapper, ""}; + MetadataCredentialsPluginWrapper::Destroy, wrapper, type}; return WrapCallCredentials( grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr)); } diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index b8fe075dc7..8e3c713a50 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -88,7 +88,7 @@ class MetadataCredentialsPluginWrapper GRPC_FINAL { std::unique_ptr<MetadataCredentialsPlugin> plugin); private: - void InvokePlugin(const char* service_url, + void InvokePlugin(grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void* user_data); std::unique_ptr<ThreadPoolInterface> thread_pool_; std::unique_ptr<MetadataCredentialsPlugin> plugin_; diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 2bd886334e..df37e63499 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -119,10 +119,13 @@ class TestMetadataCredentialsPlugin : public MetadataCredentialsPlugin { bool IsBlocking() const GRPC_OVERRIDE { return is_blocking_; } - Status GetMetadata(grpc::string_ref service_url, + Status GetMetadata(grpc::string_ref service_url, grpc::string_ref method_name, + const grpc::AuthContext& channel_auth_context, std::multimap<grpc::string, grpc::string>* metadata) GRPC_OVERRIDE { EXPECT_GT(service_url.length(), 0UL); + EXPECT_GT(method_name.length(), 0UL); + EXPECT_TRUE(channel_auth_context.IsPeerAuthenticated()); EXPECT_TRUE(metadata != nullptr); if (is_successful_) { metadata->insert(std::make_pair(kMetadataKey, metadata_value_)); -- GitLab