Split Credentials into two types

This commit is contained in:
murgatroid99 2015-09-30 14:22:54 -07:00
parent 49c1c52bb5
commit 6fcabd1a36
14 changed files with 393 additions and 129 deletions

View File

@ -72,9 +72,10 @@
"sources": [ "sources": [
"ext/byte_buffer.cc", "ext/byte_buffer.cc",
"ext/call.cc", "ext/call.cc",
"ext/call_credentials.cc",
"ext/channel.cc", "ext/channel.cc",
"ext/channel_credentials.cc",
"ext/completion_queue_async_worker.cc", "ext/completion_queue_async_worker.cc",
"ext/credentials.cc",
"ext/node_grpc.cc", "ext/node_grpc.cc",
"ext/server.cc", "ext/server.cc",
"ext/server_credentials.cc", "ext/server_credentials.cc",

View File

@ -46,7 +46,7 @@
#include "call.h" #include "call.h"
#include "channel.h" #include "channel.h"
#include "completion_queue_async_worker.h" #include "completion_queue_async_worker.h"
#include "credentials.h" #include "call_credentials.h"
#include "timeval.h" #include "timeval.h"
using std::unique_ptr; using std::unique_ptr;
@ -733,12 +733,12 @@ NAN_METHOD(Call::SetCredentials) {
return Nan::ThrowTypeError( return Nan::ThrowTypeError(
"setCredentials can only be called on Call objects"); "setCredentials can only be called on Call objects");
} }
if (!Credentials::HasInstance(info[0])) { if (!CallCredentials::HasInstance(info[0])) {
return Nan::ThrowTypeError( return Nan::ThrowTypeError(
"setCredentials' first argument must be a credential"); "setCredentials' first argument must be a CallCredentials");
} }
Call *call = ObjectWrap::Unwrap<Call>(info.This()); Call *call = ObjectWrap::Unwrap<Call>(info.This());
Credentials *creds_object = ObjectWrap::Unwrap<Credentials>( CallCredentials *creds_object = ObjectWrap::Unwrap<CallCredentials>(
Nan::To<Object>(info[0]).ToLocalChecked()); Nan::To<Object>(info[0]).ToLocalChecked());
grpc_credentials *creds = creds_object->GetWrappedCredentials(); grpc_credentials *creds = creds_object->GetWrappedCredentials();
grpc_call_error error = GRPC_CALL_ERROR; grpc_call_error error = GRPC_CALL_ERROR;

View File

@ -36,7 +36,7 @@
#include "grpc/grpc.h" #include "grpc/grpc.h"
#include "grpc/grpc_security.h" #include "grpc/grpc_security.h"
#include "grpc/support/log.h" #include "grpc/support/log.h"
#include "credentials.h" #include "call_credentials.h"
#include "call.h" #include "call.h"
namespace grpc { namespace grpc {
@ -61,47 +61,42 @@ using v8::Object;
using v8::ObjectTemplate; using v8::ObjectTemplate;
using v8::Value; using v8::Value;
Nan::Callback *Credentials::constructor; Nan::Callback *CallCredentials::constructor;
Persistent<FunctionTemplate> Credentials::fun_tpl; Persistent<FunctionTemplate> CallCredentials::fun_tpl;
Credentials::Credentials(grpc_credentials *credentials) CallCredentials::CallCredentials(grpc_credentials *credentials)
: wrapped_credentials(credentials) {} : wrapped_credentials(credentials) {}
Credentials::~Credentials() { CallCredentials::~CallCredentials() {
grpc_credentials_release(wrapped_credentials); grpc_credentials_release(wrapped_credentials);
} }
void Credentials::Init(Local<Object> exports) { void CallCredentials::Init(Local<Object> exports) {
HandleScope scope; HandleScope scope;
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New); Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
tpl->SetClassName(Nan::New("Credentials").ToLocalChecked()); tpl->SetClassName(Nan::New("CallCredentials").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1); tpl->InstanceTemplate()->SetInternalFieldCount(1);
Nan::SetPrototypeMethod(tpl, "compose", Compose);
fun_tpl.Reset(tpl); fun_tpl.Reset(tpl);
Local<Function> ctr = Nan::GetFunction(tpl).ToLocalChecked(); Local<Function> ctr = Nan::GetFunction(tpl).ToLocalChecked();
Nan::Set(ctr, Nan::New("createSsl").ToLocalChecked(),
Nan::GetFunction(
Nan::New<FunctionTemplate>(CreateSsl)).ToLocalChecked());
Nan::Set(ctr, Nan::New("createComposite").ToLocalChecked(),
Nan::GetFunction(
Nan::New<FunctionTemplate>(CreateComposite)).ToLocalChecked());
Nan::Set(ctr, Nan::New("createInsecure").ToLocalChecked(),
Nan::GetFunction(
Nan::New<FunctionTemplate>(CreateInsecure)).ToLocalChecked());
Nan::Set(ctr, Nan::New("createFromPlugin").ToLocalChecked(), Nan::Set(ctr, Nan::New("createFromPlugin").ToLocalChecked(),
Nan::GetFunction( Nan::GetFunction(
Nan::New<FunctionTemplate>(CreateFromPlugin)).ToLocalChecked()); Nan::New<FunctionTemplate>(CreateFromPlugin)).ToLocalChecked());
Nan::Set(exports, Nan::New("Credentials").ToLocalChecked(), ctr); Nan::Set(exports, Nan::New("CallCredentials").ToLocalChecked(), ctr);
constructor = new Nan::Callback(ctr); constructor = new Nan::Callback(ctr);
} }
bool Credentials::HasInstance(Local<Value> val) { bool CallCredentials::HasInstance(Local<Value> val) {
HandleScope scope; HandleScope scope;
return Nan::New(fun_tpl)->HasInstance(val); return Nan::New(fun_tpl)->HasInstance(val);
} }
Local<Value> Credentials::WrapStruct(grpc_credentials *credentials) { Local<Value> CallCredentials::WrapStruct(grpc_credentials *credentials) {
EscapableHandleScope scope; EscapableHandleScope scope;
const int argc = 1; const int argc = 1;
if (credentials == NULL) {
return scope.Escape(Nan::Null());
}
Local<Value> argv[argc] = { Local<Value> argv[argc] = {
Nan::New<External>(reinterpret_cast<void *>(credentials))}; Nan::New<External>(reinterpret_cast<void *>(credentials))};
MaybeLocal<Object> maybe_instance = Nan::NewInstance( MaybeLocal<Object> maybe_instance = Nan::NewInstance(
@ -113,20 +108,20 @@ Local<Value> Credentials::WrapStruct(grpc_credentials *credentials) {
} }
} }
grpc_credentials *Credentials::GetWrappedCredentials() { grpc_credentials *CallCredentials::GetWrappedCredentials() {
return wrapped_credentials; return wrapped_credentials;
} }
NAN_METHOD(Credentials::New) { NAN_METHOD(CallCredentials::New) {
if (info.IsConstructCall()) { if (info.IsConstructCall()) {
if (!info[0]->IsExternal()) { if (!info[0]->IsExternal()) {
return Nan::ThrowTypeError( return Nan::ThrowTypeError(
"Credentials can only be created with the provided functions"); "CallCredentials can only be created with the provided functions");
} }
Local<External> ext = info[0].As<External>(); Local<External> ext = info[0].As<External>();
grpc_credentials *creds_value = grpc_credentials *creds_value =
reinterpret_cast<grpc_credentials *>(ext->Value()); reinterpret_cast<grpc_credentials *>(ext->Value());
Credentials *credentials = new Credentials(creds_value); CallCredentials *credentials = new CallCredentials(creds_value);
credentials->Wrap(info.This()); credentials->Wrap(info.This());
info.GetReturnValue().Set(info.This()); info.GetReturnValue().Set(info.This());
return; return;
@ -144,71 +139,26 @@ NAN_METHOD(Credentials::New) {
} }
} }
NAN_METHOD(Credentials::CreateSsl) { NAN_METHOD(CallCredentials::Compose) {
char *root_certs = NULL; if (!CallCredentials::HasInstance(info.This())) {
grpc_ssl_pem_key_cert_pair key_cert_pair = {NULL, NULL};
if (::node::Buffer::HasInstance(info[0])) {
root_certs = ::node::Buffer::Data(info[0]);
} else if (!(info[0]->IsNull() || info[0]->IsUndefined())) {
return Nan::ThrowTypeError("createSsl's first argument must be a Buffer");
}
if (::node::Buffer::HasInstance(info[1])) {
key_cert_pair.private_key = ::node::Buffer::Data(info[1]);
} else if (!(info[1]->IsNull() || info[1]->IsUndefined())) {
return Nan::ThrowTypeError( return Nan::ThrowTypeError(
"createSSl's second argument must be a Buffer if provided"); "compose can only be called on CallCredentials objects");
} }
if (::node::Buffer::HasInstance(info[2])) { if (!CallCredentials::HasInstance(info[0])) {
key_cert_pair.cert_chain = ::node::Buffer::Data(info[2]);
} else if (!(info[2]->IsNull() || info[2]->IsUndefined())) {
return Nan::ThrowTypeError( return Nan::ThrowTypeError(
"createSSl's third argument must be a Buffer if provided"); "compose's first argument must be a CallCredentials object");
} }
grpc_credentials *creds = grpc_ssl_credentials_create( CallCredentials *self = ObjectWrap::Unwrap<CallCredentials>(info.This());
root_certs, key_cert_pair.private_key == NULL ? NULL : &key_cert_pair, CallCredentials *other = ObjectWrap::Unwrap<CallCredentials>(
NULL);
if (creds == NULL) {
info.GetReturnValue().SetNull();
} else {
info.GetReturnValue().Set(WrapStruct(creds));
}
}
NAN_METHOD(Credentials::CreateComposite) {
if (!HasInstance(info[0])) {
return Nan::ThrowTypeError(
"createComposite's first argument must be a Credentials object");
}
if (!HasInstance(info[1])) {
return Nan::ThrowTypeError(
"createComposite's second argument must be a Credentials object");
}
Credentials *creds0 = ObjectWrap::Unwrap<Credentials>(
Nan::To<Object>(info[0]).ToLocalChecked()); Nan::To<Object>(info[0]).ToLocalChecked());
Credentials *creds1 = ObjectWrap::Unwrap<Credentials>(
Nan::To<Object>(info[1]).ToLocalChecked());
if (creds0->wrapped_credentials == NULL) {
info.GetReturnValue().Set(info[1]);
return;
}
if (creds1->wrapped_credentials == NULL) {
info.GetReturnValue().Set(info[0]);
return;
}
grpc_credentials *creds = grpc_composite_credentials_create( grpc_credentials *creds = grpc_composite_credentials_create(
creds0->wrapped_credentials, creds1->wrapped_credentials, NULL); self->wrapped_credentials, other->wrapped_credentials, NULL);
if (creds == NULL) {
info.GetReturnValue().SetNull();
} else {
info.GetReturnValue().Set(WrapStruct(creds)); info.GetReturnValue().Set(WrapStruct(creds));
} }
}
NAN_METHOD(Credentials::CreateInsecure) {
info.GetReturnValue().Set(WrapStruct(NULL));
}
NAN_METHOD(Credentials::CreateFromPlugin) {
NAN_METHOD(CallCredentials::CreateFromPlugin) {
if (!info[0]->IsFunction()) { if (!info[0]->IsFunction()) {
return Nan::ThrowTypeError( return Nan::ThrowTypeError(
"createFromPlugin's argument must be a function"); "createFromPlugin's argument must be a function");
@ -221,12 +171,8 @@ NAN_METHOD(Credentials::CreateFromPlugin) {
plugin.state = reinterpret_cast<void*>(state); plugin.state = reinterpret_cast<void*>(state);
grpc_credentials *creds = grpc_metadata_credentials_create_from_plugin(plugin, grpc_credentials *creds = grpc_metadata_credentials_create_from_plugin(plugin,
NULL); NULL);
if (creds == NULL) {
info.GetReturnValue().SetNull();
} else {
info.GetReturnValue().Set(WrapStruct(creds)); info.GetReturnValue().Set(WrapStruct(creds));
} }
}
NAN_METHOD(PluginCallback) { NAN_METHOD(PluginCallback) {
// Arguments: status code, error details, metadata // Arguments: status code, error details, metadata
@ -245,9 +191,6 @@ NAN_METHOD(PluginCallback) {
shared_ptr<Resources> resources(new Resources); shared_ptr<Resources> resources(new Resources);
grpc_status_code code = static_cast<grpc_status_code>( grpc_status_code code = static_cast<grpc_status_code>(
Nan::To<uint32_t>(info[0]).FromJust()); Nan::To<uint32_t>(info[0]).FromJust());
//Utf8String details_str(info[1]);
//char *details = static_cast<char*>(calloc(details_str.length(), sizeof(char)));
//memcpy(details, *details_str, details_str.length());
char *details = *Utf8String(info[1]); char *details = *Utf8String(info[1]);
grpc_metadata_array array; grpc_metadata_array array;
if (!CreateMetadataArray(Nan::To<Object>(info[2]).ToLocalChecked(), if (!CreateMetadataArray(Nan::To<Object>(info[2]).ToLocalChecked(),

View File

@ -31,19 +31,17 @@
* *
*/ */
#ifndef NET_GRPC_NODE_CREDENTIALS_H_ #ifndef GRPC_NODE_CALL_CREDENTIALS_H_
#define NET_GRPC_NODE_CREDENTIALS_H_ #define GRPC_NODE_CALL_CREDENTIALS_H_
#include <node.h> #include <node.h>
#include <nan.h> #include <nan.h>
#include "grpc/grpc.h"
#include "grpc/grpc_security.h" #include "grpc/grpc_security.h"
namespace grpc { namespace grpc {
namespace node { namespace node {
/* Wrapper class for grpc_credentials structs */ class CallCredentials : public Nan::ObjectWrap {
class Credentials : public Nan::ObjectWrap {
public: public:
static void Init(v8::Local<v8::Object> exports); static void Init(v8::Local<v8::Object> exports);
static bool HasInstance(v8::Local<v8::Value> val); static bool HasInstance(v8::Local<v8::Value> val);
@ -54,18 +52,18 @@ class Credentials : public Nan::ObjectWrap {
grpc_credentials *GetWrappedCredentials(); grpc_credentials *GetWrappedCredentials();
private: private:
explicit Credentials(grpc_credentials *credentials); explicit CallCredentials(grpc_credentials *credentials);
~Credentials(); ~CallCredentials();
// Prevent copying // Prevent copying
Credentials(const Credentials &); CallCredentials(const CallCredentials &);
Credentials &operator=(const Credentials &); CallCredentials &operator=(const CallCredentials &);
static NAN_METHOD(New); static NAN_METHOD(New);
static NAN_METHOD(CreateSsl); static NAN_METHOD(CreateSsl);
static NAN_METHOD(CreateComposite);
static NAN_METHOD(CreateInsecure);
static NAN_METHOD(CreateFromPlugin); static NAN_METHOD(CreateFromPlugin);
static NAN_METHOD(Compose);
static Nan::Callback *constructor; static Nan::Callback *constructor;
// Used for typechecking instances of this javascript class // Used for typechecking instances of this javascript class
static Nan::Persistent<v8::FunctionTemplate> fun_tpl; static Nan::Persistent<v8::FunctionTemplate> fun_tpl;
@ -97,6 +95,6 @@ NAN_METHOD(PluginCallback);
NAUV_WORK_CB(SendPluginCallback); NAUV_WORK_CB(SendPluginCallback);
} // namespace node } // namespace node
} // namespace grpc } // namepsace grpc
#endif // NET_GRPC_NODE_CREDENTIALS_H_ #endif // GRPC_NODE_CALL_CREDENTIALS_H_

View File

@ -42,7 +42,7 @@
#include "call.h" #include "call.h"
#include "channel.h" #include "channel.h"
#include "completion_queue_async_worker.h" #include "completion_queue_async_worker.h"
#include "credentials.h" #include "channel_credentials.h"
#include "timeval.h" #include "timeval.h"
namespace grpc { namespace grpc {
@ -112,11 +112,11 @@ NAN_METHOD(Channel::New) {
// Owned by the Channel object // Owned by the Channel object
Utf8String host(info[0]); Utf8String host(info[0]);
grpc_credentials *creds; grpc_credentials *creds;
if (!Credentials::HasInstance(info[1])) { if (!ChannelCredentials::HasInstance(info[1])) {
return Nan::ThrowTypeError( return Nan::ThrowTypeError(
"Channel's second argument must be a credential"); "Channel's second argument must be a ChannelCredentials");
} }
Credentials *creds_object = ObjectWrap::Unwrap<Credentials>( ChannelCredentials *creds_object = ObjectWrap::Unwrap<ChannelCredentials>(
Nan::To<Object>(info[1]).ToLocalChecked()); Nan::To<Object>(info[1]).ToLocalChecked());
creds = creds_object->GetWrappedCredentials(); creds = creds_object->GetWrappedCredentials();
grpc_channel_args *channel_args_ptr; grpc_channel_args *channel_args_ptr;

200
ext/channel_credentials.cc Normal file
View File

@ -0,0 +1,200 @@
/*
*
* 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 <node.h>
#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
#include "grpc/support/log.h"
#include "channel_credentials.h"
#include "call_credentials.h"
#include "call.h"
namespace grpc {
namespace node {
using Nan::Callback;
using Nan::EscapableHandleScope;
using Nan::HandleScope;
using Nan::Maybe;
using Nan::MaybeLocal;
using Nan::ObjectWrap;
using Nan::Persistent;
using Nan::Utf8String;
using v8::Exception;
using v8::External;
using v8::Function;
using v8::FunctionTemplate;
using v8::Integer;
using v8::Local;
using v8::Object;
using v8::ObjectTemplate;
using v8::Value;
Nan::Callback *ChannelCredentials::constructor;
Persistent<FunctionTemplate> ChannelCredentials::fun_tpl;
ChannelCredentials::ChannelCredentials(grpc_credentials *credentials)
: wrapped_credentials(credentials) {}
ChannelCredentials::~ChannelCredentials() {
grpc_credentials_release(wrapped_credentials);
}
void ChannelCredentials::Init(Local<Object> exports) {
HandleScope scope;
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
tpl->SetClassName(Nan::New("ChannelCredentials").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Nan::SetPrototypeMethod(tpl, "compose", Compose);
fun_tpl.Reset(tpl);
Local<Function> ctr = Nan::GetFunction(tpl).ToLocalChecked();
Nan::Set(ctr, Nan::New("createSsl").ToLocalChecked(),
Nan::GetFunction(
Nan::New<FunctionTemplate>(CreateSsl)).ToLocalChecked());
Nan::Set(ctr, Nan::New("createInsecure").ToLocalChecked(),
Nan::GetFunction(
Nan::New<FunctionTemplate>(CreateInsecure)).ToLocalChecked());
Nan::Set(exports, Nan::New("ChannelCredentials").ToLocalChecked(), ctr);
constructor = new Nan::Callback(ctr);
}
bool ChannelCredentials::HasInstance(Local<Value> val) {
HandleScope scope;
return Nan::New(fun_tpl)->HasInstance(val);
}
Local<Value> ChannelCredentials::WrapStruct(grpc_credentials *credentials) {
EscapableHandleScope scope;
const int argc = 1;
Local<Value> argv[argc] = {
Nan::New<External>(reinterpret_cast<void *>(credentials))};
MaybeLocal<Object> maybe_instance = Nan::NewInstance(
constructor->GetFunction(), argc, argv);
if (maybe_instance.IsEmpty()) {
return scope.Escape(Nan::Null());
} else {
return scope.Escape(maybe_instance.ToLocalChecked());
}
}
grpc_credentials *ChannelCredentials::GetWrappedCredentials() {
return wrapped_credentials;
}
NAN_METHOD(ChannelCredentials::New) {
if (info.IsConstructCall()) {
if (!info[0]->IsExternal()) {
return Nan::ThrowTypeError(
"ChannelCredentials can only be created with the provided functions");
}
Local<External> ext = info[0].As<External>();
grpc_credentials *creds_value =
reinterpret_cast<grpc_credentials *>(ext->Value());
ChannelCredentials *credentials = new ChannelCredentials(creds_value);
credentials->Wrap(info.This());
info.GetReturnValue().Set(info.This());
return;
} else {
const int argc = 1;
Local<Value> argv[argc] = {info[0]};
MaybeLocal<Object> maybe_instance = constructor->GetFunction()->NewInstance(
argc, argv);
if (maybe_instance.IsEmpty()) {
// There's probably a pending exception
return;
} else {
info.GetReturnValue().Set(maybe_instance.ToLocalChecked());
}
}
}
NAN_METHOD(ChannelCredentials::CreateSsl) {
char *root_certs = NULL;
grpc_ssl_pem_key_cert_pair key_cert_pair = {NULL, NULL};
if (::node::Buffer::HasInstance(info[0])) {
root_certs = ::node::Buffer::Data(info[0]);
} else if (!(info[0]->IsNull() || info[0]->IsUndefined())) {
return Nan::ThrowTypeError("createSsl's first argument must be a Buffer");
}
if (::node::Buffer::HasInstance(info[1])) {
key_cert_pair.private_key = ::node::Buffer::Data(info[1]);
} else if (!(info[1]->IsNull() || info[1]->IsUndefined())) {
return Nan::ThrowTypeError(
"createSSl's second argument must be a Buffer if provided");
}
if (::node::Buffer::HasInstance(info[2])) {
key_cert_pair.cert_chain = ::node::Buffer::Data(info[2]);
} else if (!(info[2]->IsNull() || info[2]->IsUndefined())) {
return Nan::ThrowTypeError(
"createSSl's third argument must be a Buffer if provided");
}
grpc_credentials *creds = grpc_ssl_credentials_create(
root_certs, key_cert_pair.private_key == NULL ? NULL : &key_cert_pair,
NULL);
if (creds == NULL) {
info.GetReturnValue().SetNull();
} else {
info.GetReturnValue().Set(WrapStruct(creds));
}
}
NAN_METHOD(ChannelCredentials::Compose) {
if (!ChannelCredentials::HasInstance(info.This())) {
return Nan::ThrowTypeError(
"compose can only be called on ChannelCredentials objects");
}
if (!CallCredentials::HasInstance(info[0])) {
return Nan::ThrowTypeError(
"compose's first argument must be a CallCredentials object");
}
ChannelCredentials *self = ObjectWrap::Unwrap<ChannelCredentials>(
info.This());
CallCredentials *other = ObjectWrap::Unwrap<CallCredentials>(
Nan::To<Object>(info[0]).ToLocalChecked());
grpc_credentials *creds = grpc_composite_credentials_create(
self->wrapped_credentials, other->GetWrappedCredentials(), NULL);
if (creds == NULL) {
info.GetReturnValue().SetNull();
} else {
info.GetReturnValue().Set(WrapStruct(creds));
}
}
NAN_METHOD(ChannelCredentials::CreateInsecure) {
info.GetReturnValue().Set(WrapStruct(NULL));
}
} // namespace node
} // namespace grpc

79
ext/channel_credentials.h Normal file
View File

@ -0,0 +1,79 @@
/*
*
* 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 NET_GRPC_NODE_CHANNEL_CREDENTIALS_H_
#define NET_GRPC_NODE_CHANNEL_CREDENTIALS_H_
#include <node.h>
#include <nan.h>
#include "grpc/grpc.h"
#include "grpc/grpc_security.h"
namespace grpc {
namespace node {
/* Wrapper class for grpc_credentials structs */
class ChannelCredentials : public Nan::ObjectWrap {
public:
static void Init(v8::Local<v8::Object> exports);
static bool HasInstance(v8::Local<v8::Value> val);
/* Wrap a grpc_credentials struct in a javascript object */
static v8::Local<v8::Value> WrapStruct(grpc_credentials *credentials);
/* Returns the grpc_credentials struct that this object wraps */
grpc_credentials *GetWrappedCredentials();
private:
explicit ChannelCredentials(grpc_credentials *credentials);
~ChannelCredentials();
// Prevent copying
ChannelCredentials(const ChannelCredentials &);
ChannelCredentials &operator=(const ChannelCredentials &);
static NAN_METHOD(New);
static NAN_METHOD(CreateSsl);
static NAN_METHOD(CreateInsecure);
static NAN_METHOD(Compose);
static Nan::Callback *constructor;
// Used for typechecking instances of this javascript class
static Nan::Persistent<v8::FunctionTemplate> fun_tpl;
grpc_credentials *wrapped_credentials;
};
} // namespace node
} // namespace grpc
#endif // NET_GRPC_NODE_CHANNEL_CREDENTIALS_H_

View File

@ -37,10 +37,11 @@
#include "grpc/grpc.h" #include "grpc/grpc.h"
#include "call.h" #include "call.h"
#include "call_credentials.h"
#include "channel.h" #include "channel.h"
#include "channel_credentials.h"
#include "server.h" #include "server.h"
#include "completion_queue_async_worker.h" #include "completion_queue_async_worker.h"
#include "credentials.h"
#include "server_credentials.h" #include "server_credentials.h"
using v8::Local; using v8::Local;
@ -240,10 +241,11 @@ void init(Local<Object> exports) {
InitWriteFlags(exports); InitWriteFlags(exports);
grpc::node::Call::Init(exports); grpc::node::Call::Init(exports);
grpc::node::CallCredentials::Init(exports);
grpc::node::Channel::Init(exports); grpc::node::Channel::Init(exports);
grpc::node::ChannelCredentials::Init(exports);
grpc::node::Server::Init(exports); grpc::node::Server::Init(exports);
grpc::node::CompletionQueueAsyncWorker::Init(exports); grpc::node::CompletionQueueAsyncWorker::Init(exports);
grpc::node::Credentials::Init(exports);
grpc::node::ServerCredentials::Init(exports); grpc::node::ServerCredentials::Init(exports);
} }

View File

@ -460,7 +460,8 @@ function runTest(address, host_override, test_case, tls, test_ca, done) {
if (test.getCreds) { if (test.getCreds) {
test.getCreds(function(err, new_creds) { test.getCreds(function(err, new_creds) {
execute(err, grpc.credentials.combineCredentials(creds, new_creds)); execute(err, grpc.credentials.combineChannelCredentials(
creds, new_creds));
}); });
} else { } else {
execute(null, creds); execute(null, creds);

View File

@ -40,7 +40,9 @@
var grpc = require('bindings')('grpc.node'); var grpc = require('bindings')('grpc.node');
var Credentials = grpc.Credentials; var CallCredentials = grpc.CallCredentials;
var ChannelCredentials = grpc.ChannelCredentials;
var Metadata = require('./metadata.js'); var Metadata = require('./metadata.js');
@ -51,8 +53,9 @@ var Metadata = require('./metadata.js');
* @param {Buffer=} private_key The client certificate private key, if * @param {Buffer=} private_key The client certificate private key, if
* applicable * applicable
* @param {Buffer=} cert_chain The client certificate cert chain, if applicable * @param {Buffer=} cert_chain The client certificate cert chain, if applicable
* @return {ChannelCredentials} The SSL Credentials object
*/ */
exports.createSsl = Credentials.createSsl; exports.createSsl = ChannelCredentials.createSsl;
/** /**
* Create a gRPC credentials object from a metadata generation function. This * Create a gRPC credentials object from a metadata generation function. This
@ -61,10 +64,10 @@ exports.createSsl = Credentials.createSsl;
* which corresponds to a status code that this library uses. * which corresponds to a status code that this library uses.
* @param {function(String, function(Error, Metadata))} metadata_generator The * @param {function(String, function(Error, Metadata))} metadata_generator The
* function that generates metadata * function that generates metadata
* @return {Credentials} The credentials object * @return {CallCredentials} The credentials object
*/ */
exports.createFromMetadataGenerator = function(metadata_generator) { exports.createFromMetadataGenerator = function(metadata_generator) {
return Credentials.createFromPlugin(function(service_url, callback) { return CallCredentials.createFromPlugin(function(service_url, callback) {
metadata_generator(service_url, function(error, metadata) { metadata_generator(service_url, function(error, metadata) {
var code = grpc.status.OK; var code = grpc.status.OK;
var message = ''; var message = '';
@ -82,7 +85,7 @@ exports.createFromMetadataGenerator = function(metadata_generator) {
/** /**
* Create a gRPC credential from a Google credential object. * Create a gRPC credential from a Google credential object.
* @param {Object} google_credential The Google credential object to use * @param {Object} google_credential The Google credential object to use
* @return {Credentials} The resulting credentials object * @return {CallCredentials} The resulting credentials object
*/ */
exports.createFromGoogleCredential = function(google_credential) { exports.createFromGoogleCredential = function(google_credential) {
return exports.createFromMetadataGenerator(function(service_url, callback) { return exports.createFromMetadataGenerator(function(service_url, callback) {
@ -99,22 +102,39 @@ exports.createFromGoogleCredential = function(google_credential) {
}; };
/** /**
* Combine any number of Credentials into a single credentials object * Combine a ChannelCredentials with any number of CallCredentials into a single
* @param(...Credentials) credentials The Credentials to combine * ChannelCredentials object.
* @return Credentials A credentials object that combines all of the input * @param {ChannelCredentials} channel_credential The ChannelCredentials to
* credentials * start with
* @param {...CallCredentials} credentials The CallCredentials to compose
* @return ChannelCredentials A credentials object that combines all of the
* input credentials
*/ */
exports.combineCredentials = function() { exports.combineChannelCredentials = function(channel_credential) {
var current = arguments[0]; var current = channel_credential;
for (var i = 1; i < arguments.length; i++) { for (var i = 1; i < arguments.length; i++) {
current = Credentials.createComposite(current, arguments[i]); current = current.compose(arguments[i]);
} }
return current; return current;
}; };
/**
* Combine any number of CallCredentials into a single CallCredentials object
* @param {...CallCredentials} credentials the CallCredentials to compose
* @return CallCredentials A credentials object that combines all of the input
* credentials
*/
exports.combineCallCredentials = function() {
var current = arguments[0];
for (var i = 1; i < arguments.length; i++) {
current = current.compose(arguments[i]);
}
return current;
}
/** /**
* Create an insecure credentials object. This is used to create a channel that * Create an insecure credentials object. This is used to create a channel that
* does not use SSL. * does not use SSL.
* @return Credentials The insecure credentials object * @return {ChannelCredentials} The insecure credentials object
*/ */
exports.createInsecure = Credentials.createInsecure; exports.createInsecure = ChannelCredentials.createInsecure;

View File

@ -48,7 +48,7 @@ function getDeadline(timeout_secs) {
return deadline; return deadline;
} }
var insecureCreds = grpc.Credentials.createInsecure(); var insecureCreds = grpc.ChannelCredentials.createInsecure();
describe('call', function() { describe('call', function() {
var channel; var channel;

View File

@ -56,7 +56,7 @@ function multiDone(done, count) {
} }
}; };
} }
var insecureCreds = grpc.Credentials.createInsecure(); var insecureCreds = grpc.ChannelCredentials.createInsecure();
describe('channel', function() { describe('channel', function() {
describe('constructor', function() { describe('constructor', function() {

View File

@ -219,5 +219,25 @@ describe('client credentials', function() {
}); });
call.end(); call.end();
}); });
it('should be able to use multiple plugin credentials', function(done) {
var altMetadataUpdater = function(service_url, callback) {
var metadata = new grpc.Metadata();
metadata.set('other_plugin_key', 'other_plugin_value');
callback(null, metadata);
};
var alt_updater_creds = grpc.credentials.createFromMetadataGenerator(
altMetadataUpdater);
var combined_updater = grpc.credentials.combineCallCredentials(
updater_creds, alt_updater_creds);
var call = client.unary({}, function(err, data) {
assert.ifError(err);
}, null, {credentials: updater_creds});
call.on('metadata', function(metadata) {
assert.deepEqual(metadata.get('plugin_key'), ['plugin_value']);
assert.deepEqual(metadata.get('other_plugin_key'),
['other_plugin_value']);
done();
});
});
}); });
}); });

View File

@ -57,7 +57,7 @@ function multiDone(done, count) {
}; };
} }
var insecureCreds = grpc.Credentials.createInsecure(); var insecureCreds = grpc.ChannelCredentials.createInsecure();
describe('end-to-end', function() { describe('end-to-end', function() {
var server; var server;