Skip to content
Permalink
Browse files

feat(async-worker): introduce a `KerberosWorker` using lambdas

This allows us to signifcantly reduce the amount of boilerplate
required for async workers, by replacing the implementation with
a single lambda. This should also make it much easier to split up
implementation from definition in order to support both unix and
windows implementations.
  • Loading branch information
mbroadst committed Jul 8, 2018
1 parent a110868 commit 1239ef750581a00fd089f6c8ae3074ccb33f1e65
Showing with 68 additions and 31 deletions.
  1. +4 −0 src/common.h
  2. +16 −31 src/kerberos.cc
  3. +48 −0 src/kerberos_worker.h
@@ -5,6 +5,10 @@
#include "kerberos_gss.h"

// Provide a default custom delter for the `gss_result` type
inline void ResultDeleter(gss_result* result) {
free(result);
}

struct FreeDeleter {
void operator()(void* result) {
free(result);
@@ -4,6 +4,7 @@
#include "kerberos.h"
#include "kerberos_client.h"
#include "kerberos_server.h"
#include "kerberos_worker.h"

using v8::FunctionTemplate;

@@ -159,44 +160,28 @@ NAN_METHOD(PrincipalDetails) {
AsyncQueueWorker(new PrincipalDetailsWorker(service, hostname, callback));
}

class CheckPasswordWorker : public Nan::AsyncWorker {
public:
CheckPasswordWorker(std::string username,
std::string password,
std::string service,
std::string defaultRealm,
Nan::Callback* callback)
: AsyncWorker(callback, "kerberos:CheckPassword"),
_username(username),
_password(password),
_service(service),
_defaultRealm(defaultRealm) {}

virtual void Execute() {
std::unique_ptr<gss_result, FreeDeleter> result(authenticate_user_krb5pwd(
_username.c_str(), _password.c_str(), _service.c_str(), _defaultRealm.c_str()));

if (result->code == AUTH_GSS_ERROR) {
SetErrorMessage(result->message);
return;
}
}

private:
std::string _username;
std::string _password;
std::string _service;
std::string _defaultRealm;
};

NAN_METHOD(CheckPassword) {
std::string username(*Nan::Utf8String(info[0]));
std::string password(*Nan::Utf8String(info[1]));
std::string service(*Nan::Utf8String(info[2]));
std::string defaultRealm(*Nan::Utf8String(info[3]));
Nan::Callback* callback = new Nan::Callback(Nan::To<v8::Function>(info[4]).ToLocalChecked());

AsyncQueueWorker(new CheckPasswordWorker(username, password, service, defaultRealm, callback));
KerberosWorker::Run(callback, "kerberos:CheckPassword", [=](KerberosWorker::SetOnFinishedHandler onFinished) {
std::shared_ptr<gss_result> result(authenticate_user_krb5pwd(
username.c_str(), password.c_str(), service.c_str(), defaultRealm.c_str()), ResultDeleter);

return onFinished([=](KerberosWorker* worker) {
Nan::HandleScope scope;
if (result->code == AUTH_GSS_ERROR) {
v8::Local<v8::Value> argv[] = {Nan::New(result->message).ToLocalChecked(), Nan::Null()};
worker->Call(2, argv);
} else {
v8::Local<v8::Value> argv[] = {Nan::Null(), Nan::Null()};
worker->Call(2, argv);
}
});
});
}

NAN_MODULE_INIT(Init) {
@@ -0,0 +1,48 @@
#ifndef ASYNC_WORKER_H
#define ASYNC_WORKER_H

#include <functional>
#include <nan.h>

class KerberosWorker : public Nan::AsyncWorker {
public:
typedef std::function<void(KerberosWorker*)> OnFinishedHandler;
typedef std::function<void(OnFinishedHandler)> SetOnFinishedHandler;
typedef std::function<void(SetOnFinishedHandler)> ExecuteHandler;

explicit KerberosWorker(Nan::Callback *callback, const char* resource_name, ExecuteHandler handler)
: Nan::AsyncWorker(callback, resource_name), execute_handler(handler) {}

template <class... T>
void Call(T... t) {
callback->Call(t..., async_resource);
}

virtual void Execute() {
execute_handler([=] (OnFinishedHandler handler) {
on_finished_handler = handler;
});
}

static void Run(Nan::Callback *callback, const char* resource_name, ExecuteHandler handler) {
Nan::TryCatch tryCatch;
if (tryCatch.HasCaught()) {
tryCatch.ReThrow();
return; // don't proceed in case there were any previous errors
}

auto worker = new KerberosWorker(callback, resource_name, handler);
Nan::AsyncQueueWorker(worker);
}

protected:
void HandleOKCallback() {
on_finished_handler(this);
}

private:
ExecuteHandler execute_handler;
OnFinishedHandler on_finished_handler;
};

#endif // ASYNC_WORKER_H

0 comments on commit 1239ef7

Please sign in to comment.
You can’t perform that action at this time.