Skip to content

Commit

Permalink
Add macaroons support to node.js bindings
Browse files Browse the repository at this point in the history
Patch-By:  William Whitacre <[email protected]>

Patch against HyperDex 1.8.1 Source Distribution
Source : http://hyperdex.org/src/hyperdex-1.8.1.tar.gz
Patch  : ./hyperdex-1.8.1-authjs.patch

Patch for enabling node.js bindings for authorization support and test program.

Successfully tested against node.js versions

[email protected] ([email protected])
[email protected] ([email protected])

Test program depends on
[email protected] /home/ww/s/node-hyperdex-test
├─┬ [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│   └── [email protected]
└── [email protected]

No support for `secret` argument. Directly pass attribute `__secret` instead to
create a secret record:

    c.put('space', 'key', { __secret: 'super secret', ... }, put_callback);

Supports `auth` argument in the following form:

    c.get('space', 'key', [ M.serialize() ], get_callback);

Note that the tail of the argument list after method specific arguments was
before taken to just always be the callback. With this patch, existing code will
not break, but instead if there are two extra arguments, then the first is taken
to be an array of tokens, and the second is taken to be a callback.
  • Loading branch information
rescrv committed Sep 28, 2015
1 parent 0d43a61 commit 0b4e3af
Show file tree
Hide file tree
Showing 4 changed files with 292 additions and 16 deletions.
107 changes: 107 additions & 0 deletions bindings/node.js/client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,17 @@ class Operation
bool convert_maxmin(v8::Handle<v8::Value>& _maxmin,
int* maximize);

// 20 Sept 2015 - William Whitacre
// Patch against 1.8.1: Enable macaroon authorization.

// Convert a v8 array of strings to a character pointer array.
bool convert_auth_context(v8::Handle<v8::Value> &_value,
const char ***p_auth, size_t *p_auth_sz);

// Set and clear the auth context using the hyperdex_client API.
bool set_auth_context(v8::Handle<v8::Value> &_value);
bool clear_auth_context();

bool build_string(const char* value, size_t value_sz,
v8::Local<v8::Value>& retval,
v8::Local<v8::Value>& error);
Expand Down Expand Up @@ -275,6 +286,7 @@ class Operation
uint64_t count;
bool finished;
void (Operation::*encode_return)();
const char **m_auth;

private:
void inc() { ++m_ref; }
Expand Down Expand Up @@ -845,6 +857,7 @@ Operation :: Operation(v8::Handle<v8::Object>& c1, HyperDexClient* c2)
, count(0)
, finished(false)
, encode_return()
, m_auth(NULL)
, m_ref(0)
, m_arena(hyperdex_ds_arena_create())
, m_client()
Expand All @@ -871,6 +884,11 @@ Operation :: ~Operation() throw ()
hyperdex_client_destroy_attrs(attrs, attrs_sz);
}

if (m_auth)
{
free((void *)m_auth);
}

if (description)
{
free((void*)description);
Expand Down Expand Up @@ -1662,6 +1680,95 @@ Operation :: convert_maxmin(v8::Handle<v8::Value>& _maxmin,
return true;
}

// 20 Sept 2015 - William Whitacre
// Patch against 1.8.1: Enable macaroon authorization.
bool
Operation :: convert_auth_context(v8::Handle<v8::Value> &_value,
const char ***p_auth, size_t *p_auth_sz)
{
// Make sure this is an array we've been passed.
if (!_value->IsArray())
{
this->callback_error_message("auth must be specified as an array");
return false;
}

// Reference it as an array.
v8::Local<v8::Array> arr =
v8::Local<v8::Array>::New(_value.As<v8::Array>());

// Allocate the pointer array for storing the authorization chain.
const size_t auth_sz = arr->Length();
const char **auth = reinterpret_cast<const char **>(malloc(auth_sz * sizeof(const char *)));

// Loop through the array elements.
for (size_t i = 0; i < auth_sz; ++i)
{
// Retrieve array element at index i.
v8::Local<v8::Value> _M = arr->Get(i);

// Make sure it's actually a string and use the convert_cstring member
// function to copy the string.
if (_M.IsEmpty() ||
!(_M->IsString() && this->convert_cstring(_M, &auth[i])))
{
this->callback_error_message("auth must be an array of strings");
return false;
}
}

// Copy the resulting pointers to the return arguments.
*p_auth_sz = auth_sz;
*p_auth = auth;

// Everything worked ok.
return true;
}

bool
Operation :: set_auth_context(v8::Handle<v8::Value> &_value)
{
// Clear the authorization context if it's already been set (wierd).
this->clear_auth_context();
size_t auth_sz;

// Convert the authorization context object to an array of character
// pointers.
if (this->convert_auth_context(_value, &this->m_auth, &auth_sz))
{
// Call hyperdex client to set the authorization context.
hyperdex_client_set_auth_context(
this->client->client(),
this->m_auth, auth_sz
);
return true;
}
else
{
// Something went wrong during conversion!
return false;
}
}

bool
Operation :: clear_auth_context()
{
// Make sure the authorization context has been set.
if (this->m_auth != NULL)
{
// Call hyperdex client to clear the authorization context.
hyperdex_client_clear_auth_context(this->client->client());

// Free the array.
free((void *)this->m_auth);
this->m_auth = NULL;
}

// this->m_auth is always null at this point, and if an array was there
// it was freed.
return true;
}

bool
Operation :: build_string(const char* value, size_t value_sz,
v8::Local<v8::Value>& retval,
Expand Down
Loading

0 comments on commit 0b4e3af

Please sign in to comment.