Cpp example of how the plugins can be done.

pull/4208/head
Julien Boeuf 9 years ago
parent caf9935e45
commit 114f39475f
  1. 6
      include/grpc++/security/credentials.h
  2. 21
      src/cpp/client/secure_credentials.cc
  3. 2
      src/cpp/client/secure_credentials.h
  4. 5
      test/cpp/end2end/end2end_test.cc

@ -38,6 +38,7 @@
#include <memory> #include <memory>
#include <grpc++/impl/grpc_library.h> #include <grpc++/impl/grpc_library.h>
#include <grpc++/security/auth_context.h>
#include <grpc++/support/config.h> #include <grpc++/support/config.h>
#include <grpc++/support/status.h> #include <grpc++/support/status.h>
#include <grpc++/support/string_ref.h> #include <grpc++/support/string_ref.h>
@ -207,9 +208,14 @@ class MetadataCredentialsPlugin {
// a different thread from the one processing the call. // a different thread from the one processing the call.
virtual bool IsBlocking() const { return true; } 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. // Gets the auth metatada produced by this plugin.
virtual Status GetMetadata( virtual Status GetMetadata(
grpc::string_ref service_url, grpc::string_ref service_url,
grpc::string_ref method_name,
const AuthContext& channel_auth_contexst,
std::multimap<grpc::string, grpc::string>* metadata) = 0; std::multimap<grpc::string, grpc::string>* metadata) = 0;
}; };

@ -37,6 +37,7 @@
#include <grpc++/support/channel_arguments.h> #include <grpc++/support/channel_arguments.h>
#include "src/cpp/client/create_channel_internal.h" #include "src/cpp/client/create_channel_internal.h"
#include "src/cpp/client/secure_credentials.h" #include "src/cpp/client/secure_credentials.h"
#include "src/cpp/common/secure_auth_context.h"
namespace grpc { namespace grpc {
@ -171,18 +172,25 @@ void MetadataCredentialsPluginWrapper::GetMetadata(
} }
if (w->plugin_->IsBlocking()) { if (w->plugin_->IsBlocking()) {
w->thread_pool_->Add( w->thread_pool_->Add(
std::bind(&MetadataCredentialsPluginWrapper::InvokePlugin, w, std::bind(&MetadataCredentialsPluginWrapper::InvokePlugin, w, context,
context.service_url, cb, user_data)); cb, user_data));
} else { } else {
w->InvokePlugin(context.service_url, cb, user_data); w->InvokePlugin(context, cb, user_data);
} }
} }
void MetadataCredentialsPluginWrapper::InvokePlugin( 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) { void* user_data) {
std::multimap<grpc::string, grpc::string> metadata; 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; std::vector<grpc_metadata> md;
for (auto it = metadata.begin(); it != metadata.end(); ++it) { for (auto it = metadata.begin(); it != metadata.end(); ++it) {
grpc_metadata md_entry; grpc_metadata md_entry;
@ -204,11 +212,12 @@ MetadataCredentialsPluginWrapper::MetadataCredentialsPluginWrapper(
std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin( std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
std::unique_ptr<MetadataCredentialsPlugin> plugin) { std::unique_ptr<MetadataCredentialsPlugin> plugin) {
GrpcLibrary init; // To call grpc_init(). GrpcLibrary init; // To call grpc_init().
const char* type = plugin->GetType();
MetadataCredentialsPluginWrapper* wrapper = MetadataCredentialsPluginWrapper* wrapper =
new MetadataCredentialsPluginWrapper(std::move(plugin)); new MetadataCredentialsPluginWrapper(std::move(plugin));
grpc_metadata_credentials_plugin c_plugin = { grpc_metadata_credentials_plugin c_plugin = {
MetadataCredentialsPluginWrapper::GetMetadata, MetadataCredentialsPluginWrapper::GetMetadata,
MetadataCredentialsPluginWrapper::Destroy, wrapper, ""}; MetadataCredentialsPluginWrapper::Destroy, wrapper, type};
return WrapCallCredentials( return WrapCallCredentials(
grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr)); grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr));
} }

@ -88,7 +88,7 @@ class MetadataCredentialsPluginWrapper GRPC_FINAL {
std::unique_ptr<MetadataCredentialsPlugin> plugin); std::unique_ptr<MetadataCredentialsPlugin> plugin);
private: private:
void InvokePlugin(const char* service_url, void InvokePlugin(grpc_auth_metadata_context context,
grpc_credentials_plugin_metadata_cb cb, void* user_data); grpc_credentials_plugin_metadata_cb cb, void* user_data);
std::unique_ptr<ThreadPoolInterface> thread_pool_; std::unique_ptr<ThreadPoolInterface> thread_pool_;
std::unique_ptr<MetadataCredentialsPlugin> plugin_; std::unique_ptr<MetadataCredentialsPlugin> plugin_;

@ -119,10 +119,13 @@ class TestMetadataCredentialsPlugin : public MetadataCredentialsPlugin {
bool IsBlocking() const GRPC_OVERRIDE { return is_blocking_; } 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) std::multimap<grpc::string, grpc::string>* metadata)
GRPC_OVERRIDE { GRPC_OVERRIDE {
EXPECT_GT(service_url.length(), 0UL); EXPECT_GT(service_url.length(), 0UL);
EXPECT_GT(method_name.length(), 0UL);
EXPECT_TRUE(channel_auth_context.IsPeerAuthenticated());
EXPECT_TRUE(metadata != nullptr); EXPECT_TRUE(metadata != nullptr);
if (is_successful_) { if (is_successful_) {
metadata->insert(std::make_pair(kMetadataKey, metadata_value_)); metadata->insert(std::make_pair(kMetadataKey, metadata_value_));

Loading…
Cancel
Save