Last active
February 8, 2018 08:41
-
-
Save GauthamBanasandra/57981735c11019d07199ad7a08eba7b2 to your computer and use it in GitHub Desktop.
Trying out lcb dynamic auth
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127.0.0.1:12000 @ns_server dfbae1486597c46c796e6c071c6fc144 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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