Skip to content

Instantly share code, notes, and snippets.

@GauthamBanasandra
Last active February 8, 2018 08:41
Show Gist options
  • Save GauthamBanasandra/57981735c11019d07199ad7a08eba7b2 to your computer and use it in GitHub Desktop.
Save GauthamBanasandra/57981735c11019d07199ad7a08eba7b2 to your computer and use it in GitHub Desktop.
Trying out lcb dynamic auth
//
// main.cpp
// auth-change
//
// Created by Gautham Banasandra on 07/12/17.
// Copyright © 2017 Couchbase. All rights reserved.
//
#include <chrono>
#include <fstream>
#include <iostream>
#include <libcouchbase/couchbase.h>
#include <libcouchbase/n1ql.h>
#include <sstream>
#include <string>
#include <thread>
#include <unordered_map>
#define CREDS_FILE "/Users/gautham/projects/auth-change/creds.txt"
std::unordered_map<std::string, std::pair<std::string, std::string>>
read_credentials();
void end(lcb_t, const char *, lcb_error_t);
void get_callback(lcb_t, int, const lcb_RESPBASE *);
void store_callback(lcb_t, int, const lcb_RESPBASE *);
extern "C" {
static const char *get_username(void *cookie, const char *host,
const char *port, const char *bucket) {
auto credentials = static_cast<
std::unordered_map<std::string, std::pair<std::string, std::string>> *>(
cookie);
auto kv_host_port = std::string(host) + ":" + std::string(port);
auto username = (*credentials)[kv_host_port].first;
std::cout << "Trying to get username for " << host << ":" << port << " : " << username << std::endl;
return username.c_str();
}
static const char *get_password(void *cookie, const char *host,
const char *port, const char *bucket) {
auto credentials = static_cast<
std::unordered_map<std::string, std::pair<std::string, std::string>> *>(
cookie);
auto kv_host_port = std::string(host) + ":" + std::string(port);
auto password = (*credentials)[kv_host_port].second;
std::cout << "Trying to get password for " << host << ":" << port << " : " << password << std::endl;
return password.c_str();
}
}
std::unordered_map<std::string, std::pair<std::string, std::string>>
read_credentials() {
std::unordered_map<std::string, std::pair<std::string, std::string>>
credentials;
std::string line;
std::ifstream file(CREDS_FILE);
if (file.is_open()) {
while (getline(file, line)) {
std::istringstream tokenizer(line);
std::string kv_host_port, username, password;
tokenizer >> kv_host_port;
tokenizer >> username;
tokenizer >> password;
credentials[kv_host_port] = std::make_pair(username, password);
}
file.close();
} else {
std::cout << "Unable to open file:\t" << CREDS_FILE << std::endl;
}
return credentials;
}
void end(lcb_t instance, const char *msg, lcb_error_t err) {
std::cout << "callback type: " << msg
<< " error: " << lcb_strerror(instance, err);
exit(1);
}
void get_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb) {
std::cout << "--" << lcb_strcbtype(cbtype) << "--" << std::endl;
if (rb->rc == LCB_SUCCESS) {
char *key;
asprintf(&key, "%.*s", (int)rb->nkey, (const char *)rb->key);
const lcb_RESPGET *rget = (const lcb_RESPGET *)rb;
char *value;
asprintf(&value, "%.*s", (int)rget->nvalue, rget->value);
std::cout << "key: " << key << std::endl;
std::cout << "value: " << value << std::endl;
free(value);
free(key);
} else {
end(instance, lcb_strcbtype(rb->rc), rb->rc);
}
}
void store_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb) {
std::cout << "--" << lcb_strcbtype(cbtype) << "--" << std::endl;
if (rb->rc == LCB_SUCCESS) {
char *key;
asprintf(&key, "%.*s", (int)rb->nkey, (const char *)rb->key);
std::cout << "key " << key << " stored" << std::endl;
free(key);
} else {
end(instance, lcb_strcbtype(rb->rc), rb->rc);
}
}
int main() {
lcb_error_t err;
lcb_t instance = NULL;
struct lcb_create_st options = {0};
lcb_CMDSTORE scmd = {0};
lcb_CMDGET gcmd = {0};
options.version = 3;
options.v.v3.connstr = "couchbase://127.0.0.1:12000/"
"default?select_bucket=true&"
"detailed_errcodes=1";
options.v.v3.type = LCB_TYPE_BUCKET;
err = lcb_create(&instance, &options);
if (err != LCB_SUCCESS) {
end(instance, "Unable to create Couchbase handle", err);
}
auto credentials = read_credentials();
// Dynamic authentication
lcb_AUTHENTICATOR *auth = lcbauth_new();
lcbauth_set_callbacks(auth, &credentials, get_username, get_password);
lcbauth_set_mode(auth, LCBAUTH_MODE_DYNAMIC);
lcb_set_auth(instance, auth);
err = lcb_connect(instance);
if (err != LCB_SUCCESS) {
end(instance, "Unable to connect", err);
}
lcb_wait(instance);
err = lcb_get_bootstrap_status(instance);
if (err != LCB_SUCCESS) {
end(instance, "Unable to get bootstrap status", err);
}
lcb_install_callback3(instance, LCB_CALLBACK_STORE, store_callback);
lcb_install_callback3(instance, LCB_CALLBACK_GET, get_callback);
std::string key = "apple";
LCB_CMD_SET_KEY(&scmd, key.c_str(), key.length());
std::string value = "fruit";
LCB_CMD_SET_VALUE(&scmd, value.c_str(), value.length());
scmd.operation = LCB_SET;
err = lcb_store3(instance, NULL, &scmd);
if (err != LCB_SUCCESS) {
end(instance, "Unable to store", err);
}
lcb_wait(instance);
LCB_CMD_SET_KEY(&gcmd, key.c_str(), key.length());
err = lcb_get3(instance, NULL, &gcmd);
if (err != LCB_SUCCESS) {
end(instance, "Unable to get", err);
}
lcb_wait(instance);
lcb_destroy(instance);
return 0;
}
//
// auth-n1ql.cpp
// auth-change
//
// Created by Gautham Banasandra on 08/12/17.
// Copyright © 2017 Couchbase. All rights reserved.
//
#include <chrono>
#include <fstream>
#include <iostream>
#include <libcouchbase/couchbase.h>
#include <libcouchbase/n1ql.h>
#include <sstream>
#include <string>
#include <thread>
#include <unordered_map>
#define CREDS_FILE "/Users/gautham/projects/auth-change/creds.txt"
static void end(lcb_t, const char *, lcb_error_t);
std::unordered_map<std::string, std::pair<std::string, std::string>>
read_credentials();
static void row_callback(lcb_t, int, const lcb_RESPN1QL *);
static void end(lcb_t instance, const char *msg, lcb_error_t err) {
fprintf(stderr, "error\t%s\nerror code\t%X\t%s\n", msg, err,
lcb_strerror(instance, err));
exit(EXIT_FAILURE);
}
static void row_callback(lcb_t instance, int callback_type,
const lcb_RESPN1QL *resp) {
if (!(resp->rflags & LCB_RESP_F_FINAL)) {
printf("%.*s\n", (int)resp->nrow, resp->row);
} else
printf("metadata\t %.*s\n", (int)resp->nrow, resp->row);
}
extern "C" {
static const char *get_username(void *cookie, const char *host,
const char *port, const char *bucket) {
auto credentials = static_cast<
std::unordered_map<std::string, std::pair<std::string, std::string>> *>(
cookie);
auto kv_host_port = std::string(host) + ":" + std::string(port);
auto username = (*credentials)[kv_host_port].first;
std::cout << "Trying to get username for " << host << ":" << port << " : "
<< username << std::endl;
return username.c_str();
}
static const char *get_password(void *cookie, const char *host,
const char *port, const char *bucket) {
auto credentials = static_cast<
std::unordered_map<std::string, std::pair<std::string, std::string>> *>(
cookie);
auto kv_host_port = std::string(host) + ":" + std::string(port);
auto password = (*credentials)[kv_host_port].second;
std::cout << "Trying to get password for " << host << ":" << port << " : "
<< password << std::endl;
return password.c_str();
}
}
std::unordered_map<std::string, std::pair<std::string, std::string>>
read_credentials() {
std::unordered_map<std::string, std::pair<std::string, std::string>>
credentials;
std::string line;
std::ifstream file(CREDS_FILE);
if (file.is_open()) {
while (getline(file, line)) {
std::istringstream tokenizer(line);
std::string kv_host_port, username, password;
tokenizer >> kv_host_port;
tokenizer >> username;
tokenizer >> password;
credentials[kv_host_port] = std::make_pair(username, password);
}
file.close();
} else {
std::cout << "Unable to open file:\t" << CREDS_FILE << std::endl;
}
return credentials;
}
int main(int argc, const char *argv[]) {
// Couchbase handle instance. Connects to a bucket.
lcb_t instance = NULL;
lcb_create_st options;
lcb_error_t err;
// Allocate memory for the handle.
memset(&options, 0, sizeof(options));
options.version = 3;
options.v.v3.connstr = "couchbase://127.0.0.1:12000/"
"default?select_bucket=true&"
"detailed_errcodes=1";
options.v.v3.type = LCB_TYPE_BUCKET;
// Initialize the handle.
err = lcb_create(&instance, &options);
if (err != LCB_SUCCESS) {
end(instance, "unable to create handle", err);
}
auto credentials = read_credentials();
// Dynamic authentication
lcb_AUTHENTICATOR *auth = lcbauth_new();
lcbauth_set_callbacks(auth, &credentials, get_username, get_password);
lcbauth_set_mode(auth, LCBAUTH_MODE_DYNAMIC);
lcb_set_auth(instance, auth);
// Initialize the parameters for connection.
err = lcb_connect(instance);
if (err != LCB_SUCCESS) {
end(instance, "unable to connect to server", err);
}
// Block till the connection is established.
lcb_wait(instance);
// Check if the connection was successful.
err = lcb_get_bootstrap_status(instance);
if (err != LCB_SUCCESS) {
end(instance, "unable to get bootstrap status", err);
}
// Structure for writing the query.
lcb_CMDN1QL cmd = {0};
lcb_N1QLPARAMS *n1ql_params = lcb_n1p_new();
err = lcb_n1p_setstmtz(n1ql_params, "SELECT COUNT(*) FROM `default`;");
if (err != LCB_SUCCESS) {
end(instance, "unable to build query string", err);
}
// Build the query.
lcb_n1p_mkcmd(n1ql_params, &cmd);
// Set the callback to be invoked for fetching each row.
cmd.callback = row_callback;
// Make the query.
err = lcb_n1ql_query(instance, NULL, &cmd);
if (err != LCB_SUCCESS) {
end(instance, "unable to query", err);
}
// Block till the queries finish.
lcb_wait(instance);
// Make the query.
err = lcb_n1ql_query(instance, NULL, &cmd);
if (err != LCB_SUCCESS) {
end(instance, "unable to query", err);
}
// Block till the queries finish.
lcb_wait(instance);
// Make the query.
err = lcb_n1ql_query(instance, NULL, &cmd);
if (err != LCB_SUCCESS) {
end(instance, "unable to query", err);
}
// Block till the queries finish.
lcb_wait(instance);
// Reset the query structure for re-use in subsequent queries.
lcb_n1p_free(n1ql_params);
lcb_destroy(instance);
return 0;
}
package main
import (
"fmt"
"gopkg.in/couchbase/gocb"
"github.com/couchbase/cbauth"
)
func bucketSet() {
cluster, err := gocb.Connect("couchbase://127.0.0.1:12000")
if err != nil {
fmt.Printf("Unable to connect to cluster, err: %v\n", err)
return
}
authenticator := &DynamicAuthenticator{}
err = cluster.Authenticate(authenticator)
if err != nil {
fmt.Printf("Unable to authenticate, err: %v", err)
return
}
bucket, err := cluster.OpenBucket("default", "")
if err != nil {
fmt.Printf("Error connecting to default bucket, err: %v\n", err)
return
}
for i := 0; i < 100; i++ {
_, err = bucket.Upsert(fmt.Sprintf("%v", i), "value", 0)
if err != nil {
fmt.Printf("Unable to upsert key: %v, err: %v\n", i, err)
}
}
bucket.Close()
}
type DynamicAuthenticator struct {
}
func (dynAuth *DynamicAuthenticator) Credentials(req gocb.AuthCredsRequest) ([]gocb.UserPassPair, error) {
fmt.Printf("Need credentials for host: %s\tbucket: %s\t", req.Endpoint, req.Bucket)
username,password, err := cbauth.GetMemcachedServiceAuth(req.Endpoint)
return []gocb.UserPassPair{{
Username: username,
Password: password,
}}, err
}
func main() {
bucketSet()
}
127.0.0.1:12000 @ns_server dfbae1486597c46c796e6c071c6fc144
package main
import (
"fmt"
"time"
"github.com/couchbase/cbauth"
"os"
)
type authenticator func(string) (username, password string)
func getCredentials(kvHostPort string) (username, password string) {
username, password, err := cbauth.GetMemcachedServiceAuth(kvHostPort)
if err != nil {
fmt.Printf("Error in getting credentials : %v\n", err)
}
return
}
func writeContent(content string) {
f, err := os.Create("creds.txt")
if err != nil {
fmt.Println("Unable to open creds.txt file")
return
}
defer f.Close()
f.WriteString(fmt.Sprintf("%s", content))
f.Sync()
}
func startTicker(auth authenticator) {
ticker := time.NewTicker(time.Millisecond * 1000)
for {
select {
case <-ticker.C:
kvHostPort := "127.0.0.1:9499"
username, password := auth(kvHostPort)
content := fmt.Sprintf("%s\t%s\t%s\n", kvHostPort, username, password)
kvHostPort = "127.0.0.1:12000"
username, password = auth(kvHostPort)
content += fmt.Sprintf("%s\t%s\t%s\n", kvHostPort, username, password)
kvHostPort = "127.0.0.1:9498"
username, password = auth(kvHostPort)
content += fmt.Sprintf("%s\t%s\t%s\n", kvHostPort, username, password)
kvHostPort = "127.0.0.1:12002"
username, password = auth(kvHostPort)
content += fmt.Sprintf("%s\t%s\t%s\n", kvHostPort, username, password)
kvHostPort = "192.168.0.114:12000"
username, password = auth(kvHostPort)
content += fmt.Sprintf("%s\t%s\t%s", kvHostPort, username, password)
writeContent(content)
}
}
}
func main() {
startTicker(getCredentials)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment