Merge pull request #1594 from yang-g/creds

support per call credentials in c++
pull/1642/head
jboeuf 10 years ago
commit 6eccb082de
  1. 4
      Makefile
  2. 5
      build.json
  3. 2
      examples/pubsub/main.cc
  4. 14
      include/grpc++/client_context.h
  5. 2
      include/grpc++/create_channel.h
  6. 35
      include/grpc++/credentials.h
  7. 12
      src/cpp/client/client_context.cc
  8. 2
      src/cpp/client/create_channel.cc
  9. 7
      src/cpp/client/insecure_credentials.cc
  10. 32
      src/cpp/client/secure_credentials.cc
  11. 1
      src/cpp/client/secure_credentials.h
  12. 3
      test/cpp/client/credentials_test.cc
  13. 112
      test/cpp/end2end/end2end_test.cc
  14. 6
      test/cpp/interop/client_helper.cc
  15. 6
      test/cpp/util/create_test_channel.cc
  16. 2
      test/cpp/util/create_test_channel.h
  17. 58
      test/cpp/util/fake_credentials.cc
  18. 51
      test/cpp/util/fake_credentials.h
  19. 2
      test/cpp/util/grpc_cli.cc
  20. 1
      test/cpp/util/messages.proto

@ -308,7 +308,7 @@ E = @echo
Q = @ Q = @
endif endif
VERSION = 0.8.0.0 VERSION = 0.9.0.0
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@ -3045,6 +3045,7 @@ LIBGRPC++_TEST_UTIL_SRC = \
$(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc \ $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc \
test/cpp/util/cli_call.cc \ test/cpp/util/cli_call.cc \
test/cpp/util/create_test_channel.cc \ test/cpp/util/create_test_channel.cc \
test/cpp/util/fake_credentials.cc \
LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC)))) LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC))))
@ -3090,6 +3091,7 @@ endif
endif endif
$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/util/fake_credentials.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc
LIBGRPC++_UNSECURE_SRC = \ LIBGRPC++_UNSECURE_SRC = \

@ -6,7 +6,7 @@
"#": "The public version number of the library.", "#": "The public version number of the library.",
"version": { "version": {
"major": 0, "major": 0,
"minor": 8, "minor": 9,
"micro": 0, "micro": 0,
"build": 0 "build": 0
} }
@ -543,7 +543,8 @@
"test/cpp/util/echo.proto", "test/cpp/util/echo.proto",
"test/cpp/util/echo_duplicate.proto", "test/cpp/util/echo_duplicate.proto",
"test/cpp/util/cli_call.cc", "test/cpp/util/cli_call.cc",
"test/cpp/util/create_test_channel.cc" "test/cpp/util/create_test_channel.cc",
"test/cpp/util/fake_credentials.cc"
] ]
}, },
{ {

@ -71,7 +71,7 @@ int main(int argc, char** argv) {
ss << FLAGS_server_host << ":" << FLAGS_server_port; ss << FLAGS_server_host << ":" << FLAGS_server_port;
std::unique_ptr<grpc::Credentials> creds = grpc::GoogleDefaultCredentials(); std::shared_ptr<grpc::Credentials> creds = grpc::GoogleDefaultCredentials();
std::shared_ptr<grpc::ChannelInterface> channel = std::shared_ptr<grpc::ChannelInterface> channel =
grpc::CreateChannel(ss.str(), creds, grpc::ChannelArguments()); grpc::CreateChannel(ss.str(), creds, grpc::ChannelArguments());

@ -51,6 +51,7 @@ namespace grpc {
class CallOpBuffer; class CallOpBuffer;
class ChannelInterface; class ChannelInterface;
class CompletionQueue; class CompletionQueue;
class Credentials;
class RpcMethod; class RpcMethod;
class Status; class Status;
template <class R> template <class R>
@ -102,6 +103,11 @@ class ClientContext {
void set_authority(const grpc::string& authority) { authority_ = authority; } void set_authority(const grpc::string& authority) { authority_ = authority; }
// Set credentials for the rpc.
void set_credentials(const std::shared_ptr<Credentials>& creds) {
creds_ = creds;
}
void TryCancel(); void TryCancel();
private: private:
@ -127,11 +133,8 @@ class ClientContext {
friend class ::grpc::ClientAsyncResponseReader; friend class ::grpc::ClientAsyncResponseReader;
grpc_call* call() { return call_; } grpc_call* call() { return call_; }
void set_call(grpc_call* call, const std::shared_ptr<ChannelInterface>& channel) { void set_call(grpc_call* call,
GPR_ASSERT(call_ == nullptr); const std::shared_ptr<ChannelInterface>& channel);
call_ = call;
channel_ = channel;
}
grpc_completion_queue* cq() { return cq_; } grpc_completion_queue* cq() { return cq_; }
void set_cq(grpc_completion_queue* cq) { cq_ = cq; } void set_cq(grpc_completion_queue* cq) { cq_ = cq; }
@ -144,6 +147,7 @@ class ClientContext {
grpc_completion_queue* cq_; grpc_completion_queue* cq_;
gpr_timespec deadline_; gpr_timespec deadline_;
grpc::string authority_; grpc::string authority_;
std::shared_ptr<Credentials> creds_;
std::multimap<grpc::string, grpc::string> send_initial_metadata_; std::multimap<grpc::string, grpc::string> send_initial_metadata_;
std::multimap<grpc::string, grpc::string> recv_initial_metadata_; std::multimap<grpc::string, grpc::string> recv_initial_metadata_;
std::multimap<grpc::string, grpc::string> trailing_metadata_; std::multimap<grpc::string, grpc::string> trailing_metadata_;

@ -45,7 +45,7 @@ class ChannelInterface;
// If creds does not hold an object or is invalid, a lame channel is returned. // If creds does not hold an object or is invalid, a lame channel is returned.
std::shared_ptr<ChannelInterface> CreateChannel( std::shared_ptr<ChannelInterface> CreateChannel(
const grpc::string& target, const std::unique_ptr<Credentials>& creds, const grpc::string& target, const std::shared_ptr<Credentials>& creds,
const ChannelArguments& args); const ChannelArguments& args);
} // namespace grpc } // namespace grpc

@ -47,17 +47,18 @@ class SecureCredentials;
class Credentials : public GrpcLibrary { class Credentials : public GrpcLibrary {
public: public:
~Credentials() GRPC_OVERRIDE; ~Credentials() GRPC_OVERRIDE;
virtual bool ApplyToCall(grpc_call* call) = 0;
protected: protected:
friend std::unique_ptr<Credentials> CompositeCredentials( friend std::shared_ptr<Credentials> CompositeCredentials(
const std::unique_ptr<Credentials>& creds1, const std::shared_ptr<Credentials>& creds1,
const std::unique_ptr<Credentials>& creds2); const std::shared_ptr<Credentials>& creds2);
virtual SecureCredentials* AsSecureCredentials() = 0; virtual SecureCredentials* AsSecureCredentials() = 0;
private: private:
friend std::shared_ptr<ChannelInterface> CreateChannel( friend std::shared_ptr<ChannelInterface> CreateChannel(
const grpc::string& target, const std::unique_ptr<Credentials>& creds, const grpc::string& target, const std::shared_ptr<Credentials>& creds,
const ChannelArguments& args); const ChannelArguments& args);
virtual std::shared_ptr<ChannelInterface> CreateChannel( virtual std::shared_ptr<ChannelInterface> CreateChannel(
@ -80,20 +81,20 @@ struct SslCredentialsOptions {
}; };
// Factories for building different types of Credentials // Factories for building different types of Credentials
// The functions may return empty unique_ptr when credentials cannot be created. // The functions may return empty shared_ptr when credentials cannot be created.
// If a Credentials pointer is returned, it can still be invalid when used to // If a Credentials pointer is returned, it can still be invalid when used to
// create a channel. A lame channel will be created then and all rpcs will // create a channel. A lame channel will be created then and all rpcs will
// fail on it. // fail on it.
// Builds credentials with reasonable defaults. // Builds credentials with reasonable defaults.
std::unique_ptr<Credentials> GoogleDefaultCredentials(); std::shared_ptr<Credentials> GoogleDefaultCredentials();
// Builds SSL Credentials given SSL specific options // Builds SSL Credentials given SSL specific options
std::unique_ptr<Credentials> SslCredentials( std::shared_ptr<Credentials> SslCredentials(
const SslCredentialsOptions& options); const SslCredentialsOptions& options);
// Builds credentials for use when running in GCE // Builds credentials for use when running in GCE
std::unique_ptr<Credentials> ComputeEngineCredentials(); std::shared_ptr<Credentials> ComputeEngineCredentials();
// Builds service account credentials. // Builds service account credentials.
// json_key is the JSON key string containing the client's private key. // json_key is the JSON key string containing the client's private key.
@ -101,7 +102,7 @@ std::unique_ptr<Credentials> ComputeEngineCredentials();
// token_lifetime_seconds is the lifetime in seconds of each token acquired // token_lifetime_seconds is the lifetime in seconds of each token acquired
// through this service account credentials. It should be positive and should // through this service account credentials. It should be positive and should
// not exceed grpc_max_auth_token_lifetime or will be cropped to this value. // not exceed grpc_max_auth_token_lifetime or will be cropped to this value.
std::unique_ptr<Credentials> ServiceAccountCredentials( std::shared_ptr<Credentials> ServiceAccountCredentials(
const grpc::string& json_key, const grpc::string& scope, const grpc::string& json_key, const grpc::string& scope,
long token_lifetime_seconds); long token_lifetime_seconds);
@ -110,27 +111,27 @@ std::unique_ptr<Credentials> ServiceAccountCredentials(
// token_lifetime_seconds is the lifetime in seconds of each Json Web Token // token_lifetime_seconds is the lifetime in seconds of each Json Web Token
// (JWT) created with this credentials. It should not exceed // (JWT) created with this credentials. It should not exceed
// grpc_max_auth_token_lifetime or will be cropped to this value. // grpc_max_auth_token_lifetime or will be cropped to this value.
std::unique_ptr<Credentials> JWTCredentials( std::shared_ptr<Credentials> JWTCredentials(const grpc::string& json_key,
const grpc::string& json_key, long token_lifetime_seconds); long token_lifetime_seconds);
// Builds refresh token credentials. // Builds refresh token credentials.
// json_refresh_token is the JSON string containing the refresh token along // json_refresh_token is the JSON string containing the refresh token along
// with a client_id and client_secret. // with a client_id and client_secret.
std::unique_ptr<Credentials> RefreshTokenCredentials( std::shared_ptr<Credentials> RefreshTokenCredentials(
const grpc::string& json_refresh_token); const grpc::string& json_refresh_token);
// Builds IAM credentials. // Builds IAM credentials.
std::unique_ptr<Credentials> IAMCredentials( std::shared_ptr<Credentials> IAMCredentials(
const grpc::string& authorization_token, const grpc::string& authorization_token,
const grpc::string& authority_selector); const grpc::string& authority_selector);
// Combines two credentials objects into a composite credentials // Combines two credentials objects into a composite credentials
std::unique_ptr<Credentials> CompositeCredentials( std::shared_ptr<Credentials> CompositeCredentials(
const std::unique_ptr<Credentials>& creds1, const std::shared_ptr<Credentials>& creds1,
const std::unique_ptr<Credentials>& creds2); const std::shared_ptr<Credentials>& creds2);
// Credentials for an unencrypted, unauthenticated channel // Credentials for an unencrypted, unauthenticated channel
std::unique_ptr<Credentials> InsecureCredentials(); std::shared_ptr<Credentials> InsecureCredentials();
} // namespace grpc } // namespace grpc

@ -34,6 +34,7 @@
#include <grpc++/client_context.h> #include <grpc++/client_context.h>
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include <grpc++/credentials.h>
#include <grpc++/time.h> #include <grpc++/time.h>
namespace grpc { namespace grpc {
@ -63,6 +64,17 @@ void ClientContext::AddMetadata(const grpc::string& meta_key,
send_initial_metadata_.insert(std::make_pair(meta_key, meta_value)); send_initial_metadata_.insert(std::make_pair(meta_key, meta_value));
} }
void ClientContext::set_call(grpc_call* call,
const std::shared_ptr<ChannelInterface>& channel) {
GPR_ASSERT(call_ == nullptr);
call_ = call;
channel_ = channel;
if (creds_ && !creds_->ApplyToCall(call_)) {
grpc_call_cancel_with_status(call, GRPC_STATUS_CANCELLED,
"Failed to set credentials to rpc.");
}
}
void ClientContext::TryCancel() { void ClientContext::TryCancel() {
if (call_) { if (call_) {
grpc_call_cancel(call_); grpc_call_cancel(call_);

@ -41,7 +41,7 @@ namespace grpc {
class ChannelArguments; class ChannelArguments;
std::shared_ptr<ChannelInterface> CreateChannel( std::shared_ptr<ChannelInterface> CreateChannel(
const grpc::string& target, const std::unique_ptr<Credentials>& creds, const grpc::string& target, const std::shared_ptr<Credentials>& creds,
const ChannelArguments& args) { const ChannelArguments& args) {
return creds ? creds->CreateChannel(target, args) return creds ? creds->CreateChannel(target, args)
: std::shared_ptr<ChannelInterface>( : std::shared_ptr<ChannelInterface>(

@ -52,12 +52,15 @@ class InsecureCredentialsImpl GRPC_FINAL : public Credentials {
target, grpc_channel_create(target.c_str(), &channel_args))); target, grpc_channel_create(target.c_str(), &channel_args)));
} }
// InsecureCredentials should not be applied to a call.
bool ApplyToCall(grpc_call* call) GRPC_OVERRIDE { return false; }
SecureCredentials* AsSecureCredentials() GRPC_OVERRIDE { return nullptr; } SecureCredentials* AsSecureCredentials() GRPC_OVERRIDE { return nullptr; }
}; };
} // namespace } // namespace
std::unique_ptr<Credentials> InsecureCredentials() { std::shared_ptr<Credentials> InsecureCredentials() {
return std::unique_ptr<Credentials>(new InsecureCredentialsImpl()); return std::shared_ptr<Credentials>(new InsecureCredentialsImpl());
} }
} // namespace grpc } // namespace grpc

@ -49,20 +49,24 @@ std::shared_ptr<grpc::ChannelInterface> SecureCredentials::CreateChannel(
grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args))); grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args)));
} }
bool SecureCredentials::ApplyToCall(grpc_call* call) {
return grpc_call_set_credentials(call, c_creds_) == GRPC_CALL_OK;
}
namespace { namespace {
std::unique_ptr<Credentials> WrapCredentials(grpc_credentials* creds) { std::shared_ptr<Credentials> WrapCredentials(grpc_credentials* creds) {
return creds == nullptr return creds == nullptr
? nullptr ? nullptr
: std::unique_ptr<Credentials>(new SecureCredentials(creds)); : std::shared_ptr<Credentials>(new SecureCredentials(creds));
} }
} // namespace } // namespace
std::unique_ptr<Credentials> GoogleDefaultCredentials() { std::shared_ptr<Credentials> GoogleDefaultCredentials() {
return WrapCredentials(grpc_google_default_credentials_create()); return WrapCredentials(grpc_google_default_credentials_create());
} }
// Builds SSL Credentials given SSL specific options // Builds SSL Credentials given SSL specific options
std::unique_ptr<Credentials> SslCredentials( std::shared_ptr<Credentials> SslCredentials(
const SslCredentialsOptions& options) { const SslCredentialsOptions& options) {
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = { grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {
options.pem_private_key.c_str(), options.pem_cert_chain.c_str()}; options.pem_private_key.c_str(), options.pem_cert_chain.c_str()};
@ -74,12 +78,12 @@ std::unique_ptr<Credentials> SslCredentials(
} }
// Builds credentials for use when running in GCE // Builds credentials for use when running in GCE
std::unique_ptr<Credentials> ComputeEngineCredentials() { std::shared_ptr<Credentials> ComputeEngineCredentials() {
return WrapCredentials(grpc_compute_engine_credentials_create()); return WrapCredentials(grpc_compute_engine_credentials_create());
} }
// Builds service account credentials. // Builds service account credentials.
std::unique_ptr<Credentials> ServiceAccountCredentials( std::shared_ptr<Credentials> ServiceAccountCredentials(
const grpc::string& json_key, const grpc::string& scope, const grpc::string& json_key, const grpc::string& scope,
long token_lifetime_seconds) { long token_lifetime_seconds) {
if (token_lifetime_seconds <= 0) { if (token_lifetime_seconds <= 0) {
@ -94,8 +98,8 @@ std::unique_ptr<Credentials> ServiceAccountCredentials(
} }
// Builds JWT credentials. // Builds JWT credentials.
std::unique_ptr<Credentials> JWTCredentials( std::shared_ptr<Credentials> JWTCredentials(const grpc::string& json_key,
const grpc::string& json_key, long token_lifetime_seconds) { long token_lifetime_seconds) {
if (token_lifetime_seconds <= 0) { if (token_lifetime_seconds <= 0) {
gpr_log(GPR_ERROR, gpr_log(GPR_ERROR,
"Trying to create JWTCredentials with non-positive lifetime"); "Trying to create JWTCredentials with non-positive lifetime");
@ -107,14 +111,14 @@ std::unique_ptr<Credentials> JWTCredentials(
} }
// Builds refresh token credentials. // Builds refresh token credentials.
std::unique_ptr<Credentials> RefreshTokenCredentials( std::shared_ptr<Credentials> RefreshTokenCredentials(
const grpc::string& json_refresh_token) { const grpc::string& json_refresh_token) {
return WrapCredentials( return WrapCredentials(
grpc_refresh_token_credentials_create(json_refresh_token.c_str())); grpc_refresh_token_credentials_create(json_refresh_token.c_str()));
} }
// Builds IAM credentials. // Builds IAM credentials.
std::unique_ptr<Credentials> IAMCredentials( std::shared_ptr<Credentials> IAMCredentials(
const grpc::string& authorization_token, const grpc::string& authorization_token,
const grpc::string& authority_selector) { const grpc::string& authority_selector) {
return WrapCredentials(grpc_iam_credentials_create( return WrapCredentials(grpc_iam_credentials_create(
@ -122,10 +126,10 @@ std::unique_ptr<Credentials> IAMCredentials(
} }
// Combines two credentials objects into a composite credentials. // Combines two credentials objects into a composite credentials.
std::unique_ptr<Credentials> CompositeCredentials( std::shared_ptr<Credentials> CompositeCredentials(
const std::unique_ptr<Credentials>& creds1, const std::shared_ptr<Credentials>& creds1,
const std::unique_ptr<Credentials>& creds2) { const std::shared_ptr<Credentials>& creds2) {
// Note that we are not saving unique_ptrs to the two credentials // Note that we are not saving shared_ptrs to the two credentials
// passed in here. This is OK because the underlying C objects (i.e., // passed in here. This is OK because the underlying C objects (i.e.,
// creds1 and creds2) into grpc_composite_credentials_create will see their // creds1 and creds2) into grpc_composite_credentials_create will see their
// refcounts incremented. // refcounts incremented.

@ -46,6 +46,7 @@ class SecureCredentials GRPC_FINAL : public Credentials {
explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {} explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {}
~SecureCredentials() GRPC_OVERRIDE { grpc_credentials_release(c_creds_); } ~SecureCredentials() GRPC_OVERRIDE { grpc_credentials_release(c_creds_); }
grpc_credentials* GetRawCreds() { return c_creds_; } grpc_credentials* GetRawCreds() { return c_creds_; }
bool ApplyToCall(grpc_call* call) GRPC_OVERRIDE;
std::shared_ptr<grpc::ChannelInterface> CreateChannel( std::shared_ptr<grpc::ChannelInterface> CreateChannel(
const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE; const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE;

@ -46,8 +46,7 @@ class CredentialsTest : public ::testing::Test {
}; };
TEST_F(CredentialsTest, InvalidServiceAccountCreds) { TEST_F(CredentialsTest, InvalidServiceAccountCreds) {
std::unique_ptr<Credentials> bad1 = std::shared_ptr<Credentials> bad1 = ServiceAccountCredentials("", "", 1);
ServiceAccountCredentials("", "", 1);
EXPECT_EQ(nullptr, bad1.get()); EXPECT_EQ(nullptr, bad1.get());
} }

@ -33,11 +33,13 @@
#include <thread> #include <thread>
#include "src/core/security/credentials.h"
#include "src/cpp/server/thread_pool.h"
#include "test/core/util/port.h" #include "test/core/util/port.h"
#include "test/core/util/test_config.h" #include "test/core/util/test_config.h"
#include "test/cpp/util/echo_duplicate.grpc.pb.h" #include "test/cpp/util/echo_duplicate.grpc.pb.h"
#include "test/cpp/util/echo.grpc.pb.h" #include "test/cpp/util/echo.grpc.pb.h"
#include "src/cpp/server/thread_pool.h" #include "test/cpp/util/fake_credentials.h"
#include <grpc++/channel_arguments.h> #include <grpc++/channel_arguments.h>
#include <grpc++/channel_interface.h> #include <grpc++/channel_interface.h>
#include <grpc++/client_context.h> #include <grpc++/client_context.h>
@ -106,6 +108,16 @@ class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
} else { } else {
EXPECT_FALSE(context->IsCancelled()); EXPECT_FALSE(context->IsCancelled());
} }
if (request->has_param() && request->param().echo_metadata()) {
const std::multimap<grpc::string, grpc::string>& client_metadata =
context->client_metadata();
for (std::multimap<grpc::string, grpc::string>::const_iterator iter =
client_metadata.begin();
iter != client_metadata.end(); ++iter) {
context->AddTrailingMetadata((*iter).first, (*iter).second);
}
}
return Status::OK; return Status::OK;
} }
@ -180,7 +192,7 @@ class End2endTest : public ::testing::Test {
// Setup server // Setup server
ServerBuilder builder; ServerBuilder builder;
builder.AddListeningPort(server_address_.str(), builder.AddListeningPort(server_address_.str(),
InsecureServerCredentials()); FakeTransportSecurityServerCredentials());
builder.RegisterService(&service_); builder.RegisterService(&service_);
builder.SetMaxMessageSize( builder.SetMaxMessageSize(
kMaxMessageSize_); // For testing max message size. kMaxMessageSize_); // For testing max message size.
@ -192,8 +204,9 @@ class End2endTest : public ::testing::Test {
void TearDown() GRPC_OVERRIDE { server_->Shutdown(); } void TearDown() GRPC_OVERRIDE { server_->Shutdown(); }
void ResetStub() { void ResetStub() {
std::shared_ptr<ChannelInterface> channel = CreateChannel( std::shared_ptr<ChannelInterface> channel =
server_address_.str(), InsecureCredentials(), ChannelArguments()); CreateChannel(server_address_.str(), FakeTransportSecurityCredentials(),
ChannelArguments());
stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel)); stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel));
} }
@ -404,8 +417,9 @@ TEST_F(End2endTest, BidiStream) {
// Talk to the two services with the same name but different package names. // Talk to the two services with the same name but different package names.
// The two stubs are created on the same channel. // The two stubs are created on the same channel.
TEST_F(End2endTest, DiffPackageServices) { TEST_F(End2endTest, DiffPackageServices) {
std::shared_ptr<ChannelInterface> channel = CreateChannel( std::shared_ptr<ChannelInterface> channel =
server_address_.str(), InsecureCredentials(), ChannelArguments()); CreateChannel(server_address_.str(), FakeTransportSecurityCredentials(),
ChannelArguments());
EchoRequest request; EchoRequest request;
EchoResponse response; EchoResponse response;
@ -429,7 +443,7 @@ TEST_F(End2endTest, DiffPackageServices) {
// rpc and stream should fail on bad credentials. // rpc and stream should fail on bad credentials.
TEST_F(End2endTest, BadCredentials) { TEST_F(End2endTest, BadCredentials) {
std::unique_ptr<Credentials> bad_creds = ServiceAccountCredentials("", "", 1); std::shared_ptr<Credentials> bad_creds = ServiceAccountCredentials("", "", 1);
EXPECT_EQ(nullptr, bad_creds.get()); EXPECT_EQ(nullptr, bad_creds.get());
std::shared_ptr<ChannelInterface> channel = std::shared_ptr<ChannelInterface> channel =
CreateChannel(server_address_.str(), bad_creds, ChannelArguments()); CreateChannel(server_address_.str(), bad_creds, ChannelArguments());
@ -438,7 +452,7 @@ TEST_F(End2endTest, BadCredentials) {
EchoRequest request; EchoRequest request;
EchoResponse response; EchoResponse response;
ClientContext context; ClientContext context;
grpc::string msg("hello"); request.set_message("Hello");
Status s = stub->Echo(&context, request, &response); Status s = stub->Echo(&context, request, &response);
EXPECT_EQ("", response.message()); EXPECT_EQ("", response.message());
@ -588,6 +602,88 @@ TEST_F(End2endTest, RpcMaxMessageSize) {
EXPECT_FALSE(s.IsOk()); EXPECT_FALSE(s.IsOk());
} }
bool MetadataContains(const std::multimap<grpc::string, grpc::string>& metadata,
const grpc::string& key, const grpc::string& value) {
int count = 0;
for (std::multimap<grpc::string, grpc::string>::const_iterator iter =
metadata.begin();
iter != metadata.end(); ++iter) {
if ((*iter).first == key && (*iter).second == value) {
count++;
}
}
return count == 1;
}
TEST_F(End2endTest, SetPerCallCredentials) {
ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
std::shared_ptr<Credentials> creds =
IAMCredentials("fake_token", "fake_selector");
context.set_credentials(creds);
request.set_message("Hello");
request.mutable_param()->set_echo_metadata(true);
Status s = stub_->Echo(&context, request, &response);
EXPECT_EQ(request.message(), response.message());
EXPECT_TRUE(s.IsOk());
EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
"fake_token"));
EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
"fake_selector"));
}
TEST_F(End2endTest, InsecurePerCallCredentials) {
ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
std::shared_ptr<Credentials> creds = InsecureCredentials();
context.set_credentials(creds);
request.set_message("Hello");
request.mutable_param()->set_echo_metadata(true);
Status s = stub_->Echo(&context, request, &response);
EXPECT_EQ(StatusCode::CANCELLED, s.code());
EXPECT_EQ("Failed to set credentials to rpc.", s.details());
}
TEST_F(End2endTest, OverridePerCallCredentials) {
ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
std::shared_ptr<Credentials> creds1 =
IAMCredentials("fake_token1", "fake_selector1");
context.set_credentials(creds1);
std::shared_ptr<Credentials> creds2 =
IAMCredentials("fake_token2", "fake_selector2");
context.set_credentials(creds2);
request.set_message("Hello");
request.mutable_param()->set_echo_metadata(true);
Status s = stub_->Echo(&context, request, &response);
EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
"fake_token2"));
EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
"fake_selector2"));
EXPECT_FALSE(MetadataContains(context.GetServerTrailingMetadata(),
GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
"fake_token1"));
EXPECT_FALSE(MetadataContains(context.GetServerTrailingMetadata(),
GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
"fake_selector1"));
EXPECT_EQ(request.message(), response.message());
EXPECT_TRUE(s.IsOk());
}
} // namespace testing } // namespace testing
} // namespace grpc } // namespace grpc

@ -82,7 +82,7 @@ std::shared_ptr<ChannelInterface> CreateChannelForTestCase(
FLAGS_server_port); FLAGS_server_port);
if (test_case == "service_account_creds") { if (test_case == "service_account_creds") {
std::unique_ptr<Credentials> creds; std::shared_ptr<Credentials> creds;
GPR_ASSERT(FLAGS_enable_ssl); GPR_ASSERT(FLAGS_enable_ssl);
grpc::string json_key = GetServiceAccountJsonKey(); grpc::string json_key = GetServiceAccountJsonKey();
std::chrono::seconds token_lifetime = std::chrono::hours(1); std::chrono::seconds token_lifetime = std::chrono::hours(1);
@ -91,13 +91,13 @@ std::shared_ptr<ChannelInterface> CreateChannelForTestCase(
return CreateTestChannel(host_port, FLAGS_server_host_override, return CreateTestChannel(host_port, FLAGS_server_host_override,
FLAGS_enable_ssl, FLAGS_use_prod_roots, creds); FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
} else if (test_case == "compute_engine_creds") { } else if (test_case == "compute_engine_creds") {
std::unique_ptr<Credentials> creds; std::shared_ptr<Credentials> creds;
GPR_ASSERT(FLAGS_enable_ssl); GPR_ASSERT(FLAGS_enable_ssl);
creds = ComputeEngineCredentials(); creds = ComputeEngineCredentials();
return CreateTestChannel(host_port, FLAGS_server_host_override, return CreateTestChannel(host_port, FLAGS_server_host_override,
FLAGS_enable_ssl, FLAGS_use_prod_roots, creds); FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
} else if (test_case == "jwt_token_creds") { } else if (test_case == "jwt_token_creds") {
std::unique_ptr<Credentials> creds; std::shared_ptr<Credentials> creds;
GPR_ASSERT(FLAGS_enable_ssl); GPR_ASSERT(FLAGS_enable_ssl);
grpc::string json_key = GetServiceAccountJsonKey(); grpc::string json_key = GetServiceAccountJsonKey();
std::chrono::seconds token_lifetime = std::chrono::hours(1); std::chrono::seconds token_lifetime = std::chrono::hours(1);

@ -58,13 +58,13 @@ namespace grpc {
std::shared_ptr<ChannelInterface> CreateTestChannel( std::shared_ptr<ChannelInterface> CreateTestChannel(
const grpc::string& server, const grpc::string& override_hostname, const grpc::string& server, const grpc::string& override_hostname,
bool enable_ssl, bool use_prod_roots, bool enable_ssl, bool use_prod_roots,
const std::unique_ptr<Credentials>& creds) { const std::shared_ptr<Credentials>& creds) {
ChannelArguments channel_args; ChannelArguments channel_args;
if (enable_ssl) { if (enable_ssl) {
const char* roots_certs = use_prod_roots ? "" : test_root_cert; const char* roots_certs = use_prod_roots ? "" : test_root_cert;
SslCredentialsOptions ssl_opts = {roots_certs, "", ""}; SslCredentialsOptions ssl_opts = {roots_certs, "", ""};
std::unique_ptr<Credentials> channel_creds = SslCredentials(ssl_opts); std::shared_ptr<Credentials> channel_creds = SslCredentials(ssl_opts);
if (!server.empty() && !override_hostname.empty()) { if (!server.empty() && !override_hostname.empty()) {
channel_args.SetSslTargetNameOverride(override_hostname); channel_args.SetSslTargetNameOverride(override_hostname);
@ -84,7 +84,7 @@ std::shared_ptr<ChannelInterface> CreateTestChannel(
const grpc::string& server, const grpc::string& override_hostname, const grpc::string& server, const grpc::string& override_hostname,
bool enable_ssl, bool use_prod_roots) { bool enable_ssl, bool use_prod_roots) {
return CreateTestChannel(server, override_hostname, enable_ssl, return CreateTestChannel(server, override_hostname, enable_ssl,
use_prod_roots, std::unique_ptr<Credentials>()); use_prod_roots, std::shared_ptr<Credentials>());
} }
// Shortcut for end2end and interop tests. // Shortcut for end2end and interop tests.

@ -52,7 +52,7 @@ std::shared_ptr<ChannelInterface> CreateTestChannel(
std::shared_ptr<ChannelInterface> CreateTestChannel( std::shared_ptr<ChannelInterface> CreateTestChannel(
const grpc::string& server, const grpc::string& override_hostname, const grpc::string& server, const grpc::string& override_hostname,
bool enable_ssl, bool use_prod_roots, bool enable_ssl, bool use_prod_roots,
const std::unique_ptr<Credentials>& creds); const std::shared_ptr<Credentials>& creds);
} // namespace grpc } // namespace grpc

@ -0,0 +1,58 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <grpc/grpc_security.h>
#include <grpc++/channel_arguments.h>
#include <grpc++/credentials.h>
#include <grpc++/server_credentials.h>
#include "src/cpp/client/channel.h"
#include "src/cpp/client/secure_credentials.h"
#include "src/cpp/server/secure_server_credentials.h"
namespace grpc {
namespace testing {
std::shared_ptr<Credentials> FakeTransportSecurityCredentials() {
grpc_credentials* c_creds = grpc_fake_transport_security_credentials_create();
return std::shared_ptr<Credentials>(new SecureCredentials(c_creds));
}
std::shared_ptr<ServerCredentials> FakeTransportSecurityServerCredentials() {
grpc_server_credentials* c_creds =
grpc_fake_transport_security_server_credentials_create();
return std::shared_ptr<ServerCredentials>(
new SecureServerCredentials(c_creds));
}
} // namespace testing
} // namespace grpc

@ -0,0 +1,51 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_TEST_CPP_UTIL_FAKE_CREDENTIALS_H
#define GRPC_TEST_CPP_UTIL_FAKE_CREDENTIALS_H
#include <memory>
namespace grpc {
class Credentials;
class ServerCredentials;
namespace testing {
std::shared_ptr<Credentials> FakeTransportSecurityCredentials();
std::shared_ptr<ServerCredentials> FakeTransportSecurityServerCredentials();
} // namespace testing
} // namespace grpc
#endif // GRPC_TEST_CPP_UTIL_FAKE_CREDENTIALS_H

@ -104,7 +104,7 @@ int main(int argc, char** argv) {
std::stringstream input_stream; std::stringstream input_stream;
input_stream << input_file.rdbuf(); input_stream << input_file.rdbuf();
std::unique_ptr<grpc::Credentials> creds; std::shared_ptr<grpc::Credentials> creds;
if (!FLAGS_enable_ssl) { if (!FLAGS_enable_ssl) {
creds = grpc::InsecureCredentials(); creds = grpc::InsecureCredentials();
} else { } else {

@ -36,6 +36,7 @@ message RequestParams {
optional bool echo_deadline = 1; optional bool echo_deadline = 1;
optional int32 client_cancel_after_us = 2; optional int32 client_cancel_after_us = 2;
optional int32 server_cancel_after_us = 3; optional int32 server_cancel_after_us = 3;
optional bool echo_metadata = 4;
} }
message EchoRequest { message EchoRequest {

Loading…
Cancel
Save