libcouchbase 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +3 -3
- data/README.md +4 -9
- data/ext/libcouchbase/include/libcouchbase/auth.h +101 -0
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +13 -0
- data/ext/libcouchbase/src/auth-priv.h +34 -0
- data/ext/libcouchbase/src/auth.cc +53 -28
- data/ext/libcouchbase/src/cntl.cc +3 -3
- data/ext/libcouchbase/src/http/http.cc +6 -1
- data/ext/libcouchbase/src/instance.cc +11 -0
- data/ext/libcouchbase/src/mcserver/negotiate.c +4 -3
- data/ext/libcouchbase/src/n1ql/n1ql.cc +1 -0
- data/ext/libcouchbase/src/settings.c +1 -2
- data/ext/libcouchbase/src/settings.h +0 -1
- data/ext/libcouchbase/tests/basic/t_creds.cc +27 -5
- data/lib/libcouchbase/bucket.rb +5 -3
- data/lib/libcouchbase/design_docs.rb +6 -0
- data/lib/libcouchbase/version.rb +1 -1
- data/spec/design_docs_spec.rb +8 -0
- data/spec/view_spec.rb +2 -2
- metadata +4 -3
- data/ext/libcouchbase/src/auth.h +0 -54
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff0956b1087675795458772e87ba168c045ef2f6
|
4
|
+
data.tar.gz: 715ef9e7bd70e6fe4996fdaf9eaee7ec3a5c9ccd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8d2e5dc66ff778f2353837027e746a38fa56fc2f81163fea892c43d15151625f4e6bfb70d0447b4c9a627af050c0a10f830cb92bde36f4c9778e66cac7a2474
|
7
|
+
data.tar.gz: 028f7bfb147658012fb3556f4fdf86601f7d8b7c64a5f0b4435e5b7f6c74180225e1201166d1bcea462c2da2f4cfb8a02046a55d01bb7813608859d73c168a08
|
data/LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c)
|
1
|
+
Copyright (c) 2016 ACAProjects
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
of this software and associated documentation files (the "Software"), to deal
|
@@ -20,5 +20,5 @@ THE SOFTWARE.
|
|
20
20
|
|
21
21
|
===
|
22
22
|
|
23
|
-
This license applies to all parts of
|
24
|
-
|
23
|
+
This license applies to all parts of the libcouchbase gem (Ruby FFI bindings for libcouchbase only)
|
24
|
+
Libcouchbase itself [is using the Couchbase license](https://github.com/couchbase/libcouchbase/blob/master/LICENSE)
|
data/README.md
CHANGED
@@ -105,16 +105,11 @@ The library supports three different formats for representing values:
|
|
105
105
|
* `:marshal` Use this format if you'd like to transparently serialize your
|
106
106
|
ruby object with standard `Marshal.dump` and `Marshal.load` methods
|
107
107
|
|
108
|
-
The library supports both synchronous and asynchronous mode. In
|
109
|
-
asynchronous mode all operations will return control to caller
|
110
|
-
without blocking current thread. You can collect references to these
|
111
|
-
async operations and then wait for the results on the current thread
|
112
|
-
or the results can be processed in a callback.
|
113
|
-
|
114
108
|
```ruby
|
115
109
|
bucket.put(:some_object, my_object, format: :marshal)
|
116
110
|
```
|
117
111
|
|
112
|
+
|
118
113
|
The library supports both synchronous and asynchronous operations.
|
119
114
|
In asynchronous mode all operations will return control to caller
|
120
115
|
without blocking current thread. By default all operations are
|
@@ -133,10 +128,10 @@ bucket.wait_results(results) #=> ['key1_val', 'key2_val']
|
|
133
128
|
# Is equivalent to:
|
134
129
|
bucket.get(:key1, :key2) #=> ['key1_val', 'key2_val']
|
135
130
|
|
136
|
-
# Process result without waiting
|
131
|
+
# Process result without waiting or blocking the thread at all
|
137
132
|
# This will execute on the couchbase reactor loop so it is
|
138
|
-
# recommended not to block
|
139
|
-
# work to occur next_tick etc
|
133
|
+
# recommended not to block in the callback - spin up a new thread
|
134
|
+
# or schedule the work to occur next_tick etc
|
140
135
|
promise = bucket.get(:key1, async: true)
|
141
136
|
promise.then { |result| puts result }
|
142
137
|
promise.catch { |error| puts error }
|
@@ -0,0 +1,101 @@
|
|
1
|
+
#ifndef LCB_AUTH_H
|
2
|
+
#define LCB_AUTH_H
|
3
|
+
|
4
|
+
#ifdef __cplusplus
|
5
|
+
namespace lcb { class Authenticator; }
|
6
|
+
typedef lcb::Authenticator lcb_AUTHENTICATOR;
|
7
|
+
extern "C" {
|
8
|
+
#else /* C only! */
|
9
|
+
typedef struct lcb_AUTHENTICATOR_Cdummy lcb_AUTHENTICATOR;
|
10
|
+
#endif
|
11
|
+
|
12
|
+
/**
|
13
|
+
* @class lcb_AUTHENTICATOR
|
14
|
+
*
|
15
|
+
* The lcb_AUTHENTICATOR object allows greater flexibility with regard to
|
16
|
+
* adding more than a single bucket/password credential pair. It also restores
|
17
|
+
* the ability to use "true" usernames (though these are not used at present
|
18
|
+
* yet).
|
19
|
+
*/
|
20
|
+
|
21
|
+
/**
|
22
|
+
* @volatile
|
23
|
+
* Creates a new authenticator object. You may destroy it using lcbauth_unref().
|
24
|
+
* The returned object initially has a refcount of 1.
|
25
|
+
*
|
26
|
+
* @return A new authenticator object.
|
27
|
+
*/
|
28
|
+
LIBCOUCHBASE_API
|
29
|
+
lcb_AUTHENTICATOR *
|
30
|
+
lcbauth_new(void);
|
31
|
+
|
32
|
+
/**
|
33
|
+
* Flags to use when adding a new set of credentials to lcbauth_add_pass
|
34
|
+
*/
|
35
|
+
typedef enum {
|
36
|
+
/** User/Password is administrative; for cluster */
|
37
|
+
LCBAUTH_F_CLUSTER = 1<<1,
|
38
|
+
|
39
|
+
/** User is bucket name. Password is bucket password */
|
40
|
+
LCBAUTH_F_BUCKET = 1<<2
|
41
|
+
} lcbauth_ADDPASSFLAGS;
|
42
|
+
|
43
|
+
/**
|
44
|
+
* @volatile
|
45
|
+
*
|
46
|
+
* Add a set of credentials
|
47
|
+
* @param auth
|
48
|
+
* @param user the username (or bucketname, if LCBAUTH_F_BUCKET is passed)
|
49
|
+
* @param pass the password. If the password is NULL, the credential is removed
|
50
|
+
* @param flags one of @ref LCBAUTH_F_CLUSTER or @ref LCBAUTH_F_BUCKET.
|
51
|
+
*/
|
52
|
+
LIBCOUCHBASE_API
|
53
|
+
lcb_error_t
|
54
|
+
lcbauth_add_pass(lcb_AUTHENTICATOR *auth, const char *user, const char *pass, int flags);
|
55
|
+
|
56
|
+
/**
|
57
|
+
* @volatile
|
58
|
+
*
|
59
|
+
* Gets the global username and password. This is either the lone bucket
|
60
|
+
* password, or an explicit cluster password.
|
61
|
+
* @param auth
|
62
|
+
* @param[out] u Global username
|
63
|
+
* @param[out] p Global password
|
64
|
+
*/
|
65
|
+
void
|
66
|
+
lcbauth_get_upass(const lcb_AUTHENTICATOR *auth, const char **u, const char **p);
|
67
|
+
|
68
|
+
|
69
|
+
/**
|
70
|
+
* @private
|
71
|
+
*
|
72
|
+
* Get a user/bucket password
|
73
|
+
* @param auth the authenticator
|
74
|
+
* @param name the name of the bucket
|
75
|
+
* @return the password for the bucket, or NULL if the bucket has no password
|
76
|
+
* (or is unknown to the authenticator)
|
77
|
+
*/
|
78
|
+
const char *
|
79
|
+
lcbauth_get_bpass(const lcb_AUTHENTICATOR *auth, const char *name);
|
80
|
+
|
81
|
+
/**
|
82
|
+
* @uncomitted
|
83
|
+
* Increments the refcount on the authenticator object
|
84
|
+
* @param auth
|
85
|
+
*/
|
86
|
+
LIBCOUCHBASE_API
|
87
|
+
void
|
88
|
+
lcbauth_ref(lcb_AUTHENTICATOR *auth);
|
89
|
+
|
90
|
+
/**
|
91
|
+
* Decrements the refcount on the authenticator object
|
92
|
+
* @param auth
|
93
|
+
*/
|
94
|
+
LIBCOUCHBASE_API
|
95
|
+
void
|
96
|
+
lcbauth_unref(lcb_AUTHENTICATOR *auth);
|
97
|
+
|
98
|
+
#ifdef __cplusplus
|
99
|
+
}
|
100
|
+
#endif
|
101
|
+
#endif /* LCB_AUTH_H */
|
@@ -54,6 +54,7 @@ typedef struct lcb_http_request_st *lcb_http_request_t;
|
|
54
54
|
#include <libcouchbase/http.h>
|
55
55
|
#include <libcouchbase/configuration.h>
|
56
56
|
#include <libcouchbase/kvbuf.h>
|
57
|
+
#include <libcouchbase/auth.h>
|
57
58
|
#include <libcouchbase/_cxxwrap.h>
|
58
59
|
|
59
60
|
#ifdef __cplusplus
|
@@ -387,6 +388,18 @@ lcb_set_bootstrap_callback(lcb_t instance, lcb_bootstrap_callback callback);
|
|
387
388
|
LIBCOUCHBASE_API
|
388
389
|
lcb_error_t
|
389
390
|
lcb_get_bootstrap_status(lcb_t instance);
|
391
|
+
|
392
|
+
/**
|
393
|
+
* Sets the authenticator object for the instance. This may be done anytime, but
|
394
|
+
* should probably be done before calling `lcb_connect()` for best effect.
|
395
|
+
*
|
396
|
+
* @param instance the handle
|
397
|
+
* @param auth the authenticator object used. The library will increase the
|
398
|
+
* refcount on the authenticator object.
|
399
|
+
*/
|
400
|
+
LIBCOUCHBASE_API
|
401
|
+
void
|
402
|
+
lcb_set_auth(lcb_t instance, lcb_AUTHENTICATOR *auth);
|
390
403
|
/**@}*/
|
391
404
|
|
392
405
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#ifndef LCB_AUTH_PRIV_H
|
2
|
+
#define LCB_AUTH_PRIV_H
|
3
|
+
#include <libcouchbase/auth.h>
|
4
|
+
|
5
|
+
#ifdef __cplusplus
|
6
|
+
#include <string>
|
7
|
+
#include <map>
|
8
|
+
|
9
|
+
namespace lcb {
|
10
|
+
class Authenticator {
|
11
|
+
public:
|
12
|
+
typedef std::map<std::string,std::string> Map;
|
13
|
+
const std::string& username() const { return m_username; }
|
14
|
+
const std::string& password() const { return m_password; }
|
15
|
+
const Map& buckets() const { return m_buckets; }
|
16
|
+
Authenticator() : m_refcount(1) {}
|
17
|
+
|
18
|
+
size_t refcount() const { return m_refcount; }
|
19
|
+
void incref() { ++m_refcount; }
|
20
|
+
void decref() { if (!--m_refcount) { delete this; } }
|
21
|
+
lcb_error_t add(const char *user, const char *pass, int flags);
|
22
|
+
lcb_error_t init(const std::string& username_, const std::string& bucket,
|
23
|
+
const std::string& password, lcb_type_t conntype);
|
24
|
+
|
25
|
+
private:
|
26
|
+
// todo: refactor these out
|
27
|
+
Map m_buckets;
|
28
|
+
std::string m_username;
|
29
|
+
std::string m_password;
|
30
|
+
size_t m_refcount;
|
31
|
+
};
|
32
|
+
}
|
33
|
+
#endif
|
34
|
+
#endif /* LCB_AUTH_H */
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#include <libcouchbase/couchbase.h>
|
2
|
-
#include "auth.h"
|
2
|
+
#include "auth-priv.h"
|
3
3
|
|
4
4
|
using namespace lcb;
|
5
5
|
|
@@ -9,53 +9,78 @@ lcbauth_new()
|
|
9
9
|
return new Authenticator();
|
10
10
|
}
|
11
11
|
|
12
|
-
void
|
13
|
-
lcbauth_free(lcb_AUTHENTICATOR *auth)
|
14
|
-
{
|
15
|
-
delete auth;
|
16
|
-
}
|
17
|
-
|
18
12
|
const char *
|
19
13
|
lcbauth_get_bpass(const lcb_AUTHENTICATOR *auth, const char *u)
|
20
14
|
{
|
21
|
-
Authenticator::Map::const_iterator ii = auth->
|
22
|
-
if (ii == auth->
|
15
|
+
Authenticator::Map::const_iterator ii = auth->buckets().find(u);
|
16
|
+
if (ii == auth->buckets().end()) {
|
23
17
|
return NULL;
|
24
18
|
}
|
25
19
|
return ii->second.c_str();
|
26
20
|
}
|
27
21
|
|
22
|
+
lcb_error_t
|
23
|
+
lcbauth_add_pass(lcb_AUTHENTICATOR *auth, const char *u, const char *p, int flags)
|
24
|
+
{
|
25
|
+
return auth->add(u, p, flags);
|
26
|
+
}
|
27
|
+
|
28
|
+
lcb_error_t
|
29
|
+
Authenticator::add(const char *u, const char *p, int flags)
|
30
|
+
{
|
31
|
+
if (!flags) {
|
32
|
+
return LCB_EINVAL;
|
33
|
+
}
|
34
|
+
|
35
|
+
if (flags & LCBAUTH_F_CLUSTER) {
|
36
|
+
if (!p) {
|
37
|
+
m_username.clear();
|
38
|
+
m_password.clear();
|
39
|
+
} else {
|
40
|
+
m_username = u;
|
41
|
+
m_password = p;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
if (flags & LCBAUTH_F_BUCKET) {
|
45
|
+
if (!p) {
|
46
|
+
m_buckets.erase(u);
|
47
|
+
} else {
|
48
|
+
m_buckets[u] = p;
|
49
|
+
}
|
50
|
+
}
|
51
|
+
return LCB_SUCCESS;
|
52
|
+
}
|
53
|
+
|
28
54
|
void
|
29
|
-
|
30
|
-
int is_global)
|
55
|
+
lcbauth_get_upass(const lcb_AUTHENTICATOR *auth, const char **u, const char **p)
|
31
56
|
{
|
32
|
-
if (
|
33
|
-
|
34
|
-
auth->
|
57
|
+
if (!auth->username().empty()) {
|
58
|
+
*u = auth->username().c_str();
|
59
|
+
*p = auth->password().empty() ? NULL : auth->password().c_str();
|
60
|
+
|
61
|
+
} else if (!auth->buckets().empty()) {
|
62
|
+
Authenticator::Map::const_iterator it = auth->buckets().begin();
|
63
|
+
*u = it->first.c_str();
|
64
|
+
if (!it->second.empty()) {
|
65
|
+
*p = it->second.c_str();
|
66
|
+
} else {
|
67
|
+
*p = NULL;
|
68
|
+
}
|
35
69
|
} else {
|
36
|
-
|
70
|
+
*u = *p = NULL;
|
37
71
|
}
|
38
72
|
}
|
39
73
|
|
40
74
|
void
|
41
|
-
|
75
|
+
lcbauth_ref(lcb_AUTHENTICATOR *auth)
|
42
76
|
{
|
43
|
-
auth->
|
77
|
+
auth->incref();
|
44
78
|
}
|
45
79
|
|
46
80
|
void
|
47
|
-
|
81
|
+
lcbauth_unref(lcb_AUTHENTICATOR *auth)
|
48
82
|
{
|
49
|
-
|
50
|
-
*u = auth->m_username.c_str();
|
51
|
-
} else {
|
52
|
-
*u = NULL;
|
53
|
-
}
|
54
|
-
if (!auth->m_password.empty()) {
|
55
|
-
*p = auth->m_password.c_str();
|
56
|
-
} else {
|
57
|
-
*p = NULL;
|
58
|
-
}
|
83
|
+
auth->decref();
|
59
84
|
}
|
60
85
|
|
61
86
|
lcb_error_t
|
@@ -497,7 +497,7 @@ HANDLER(bucket_auth_handler) {
|
|
497
497
|
if (mode == LCB_CNTL_SET) {
|
498
498
|
/* Parse the bucket string... */
|
499
499
|
cred = (const lcb_BUCKETCRED *)arg;
|
500
|
-
|
500
|
+
lcbauth_add_pass(instance->settings->auth, (*cred)[0], (*cred)[1], LCBAUTH_F_BUCKET);
|
501
501
|
(void)cmd; (void)arg;
|
502
502
|
} else if (mode == CNTL__MODE_SETSTRING) {
|
503
503
|
const char *ss = reinterpret_cast<const char *>(arg);
|
@@ -509,9 +509,9 @@ HANDLER(bucket_auth_handler) {
|
|
509
509
|
if (!root.isArray() || root.size() != 2) {
|
510
510
|
return LCB_ECTL_BADARG;
|
511
511
|
}
|
512
|
-
|
512
|
+
lcbauth_add_pass(instance->settings->auth,
|
513
513
|
root[0].asString().c_str(),
|
514
|
-
root[1].asString().c_str(),
|
514
|
+
root[1].asString().c_str(), LCBAUTH_F_BUCKET);
|
515
515
|
} else {
|
516
516
|
return LCB_ECTL_UNSUPPMODE;
|
517
517
|
}
|
@@ -433,7 +433,12 @@ Request::setup_inputs(const lcb_CMDHTTP *cmd)
|
|
433
433
|
if (cmd->cmdflags & LCB_CMDHTTP_F_NOUPASS) {
|
434
434
|
username = password = NULL;
|
435
435
|
} else if (username == NULL && password == NULL) {
|
436
|
-
|
436
|
+
if (reqtype == LCB_HTTP_TYPE_MANAGEMENT) {
|
437
|
+
lcbauth_get_upass(LCBT_SETTING(instance, auth), &username, &password);
|
438
|
+
} else {
|
439
|
+
username = LCBT_SETTING(instance, bucket);
|
440
|
+
password = lcbauth_get_bpass(LCBT_SETTING(instance, auth), username);
|
441
|
+
}
|
437
442
|
}
|
438
443
|
|
439
444
|
base = get_api_node(rc);
|
@@ -15,6 +15,7 @@
|
|
15
15
|
* limitations under the License.
|
16
16
|
*/
|
17
17
|
#include "internal.h"
|
18
|
+
#include "auth-priv.h"
|
18
19
|
#include "connspec.h"
|
19
20
|
#include "logging.h"
|
20
21
|
#include "hostlist.h"
|
@@ -51,6 +52,16 @@ const void *lcb_get_cookie(lcb_t instance)
|
|
51
52
|
return instance->cookie;
|
52
53
|
}
|
53
54
|
|
55
|
+
LIBCOUCHBASE_API
|
56
|
+
void
|
57
|
+
lcb_set_auth(lcb_t instance, lcb_AUTHENTICATOR *auth)
|
58
|
+
{
|
59
|
+
/* First increase refcount in case they are the same object(!) */
|
60
|
+
lcbauth_ref(auth);
|
61
|
+
lcbauth_unref(instance->settings->auth);
|
62
|
+
instance->settings->auth = auth;
|
63
|
+
}
|
64
|
+
|
54
65
|
void
|
55
66
|
lcb_st::add_bs_host(const char *host, int port, unsigned bstype)
|
56
67
|
{
|
@@ -76,8 +76,8 @@ sasl_get_username(void *context, int id, const char **result, unsigned int *len)
|
|
76
76
|
if (!context || !result || (id != CBSASL_CB_USER && id != CBSASL_CB_AUTHNAME)) {
|
77
77
|
return SASL_BADPARAM;
|
78
78
|
}
|
79
|
-
|
80
|
-
|
79
|
+
u = ctx->settings->bucket;
|
80
|
+
p = lcbauth_get_bpass(ctx->settings->auth, ctx->settings->bucket);
|
81
81
|
*result = u;
|
82
82
|
if (len) {
|
83
83
|
*len = (unsigned int)strlen(*result);
|
@@ -124,7 +124,8 @@ setup_sasl_params(struct mc_SESSINFO *ctx)
|
|
124
124
|
}
|
125
125
|
|
126
126
|
memset(&ctx->u_auth, 0, sizeof(ctx->u_auth));
|
127
|
-
|
127
|
+
user = ctx->settings->bucket;
|
128
|
+
pass = lcbauth_get_bpass(ctx->settings->auth, user);
|
128
129
|
|
129
130
|
if (pass) {
|
130
131
|
unsigned long pwlen;
|
@@ -18,7 +18,6 @@
|
|
18
18
|
#include "settings.h"
|
19
19
|
#include <lcbio/ssl.h>
|
20
20
|
#include <rdb/rope.h>
|
21
|
-
#include "auth.h"
|
22
21
|
|
23
22
|
LCB_INTERNAL_API
|
24
23
|
void lcb_default_settings(lcb_settings *settings)
|
@@ -83,7 +82,7 @@ lcb_settings_unref(lcb_settings *settings)
|
|
83
82
|
free(settings->certpath);
|
84
83
|
free(settings->client_string);
|
85
84
|
|
86
|
-
|
85
|
+
lcbauth_unref(settings->auth);
|
87
86
|
|
88
87
|
if (settings->ssl_ctx) {
|
89
88
|
lcbio_ssl_free(settings->ssl_ctx);
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#include "config.h"
|
2
2
|
#include "internal.h"
|
3
|
-
#include "auth.h"
|
3
|
+
#include "auth-priv.h"
|
4
4
|
#include <gtest/gtest.h>
|
5
5
|
#define LIBCOUCHBASE_INTERNAL 1
|
6
6
|
#include <libcouchbase/couchbase.h>
|
@@ -15,8 +15,8 @@ TEST_F(CredsTest, testCreds)
|
|
15
15
|
lcb_BUCKETCRED cred;
|
16
16
|
ASSERT_EQ(LCB_SUCCESS, lcb_create(&instance, NULL));
|
17
17
|
lcb::Authenticator& auth = *instance->settings->auth;
|
18
|
-
ASSERT_FALSE(auth.
|
19
|
-
ASSERT_EQ("default", auth.
|
18
|
+
ASSERT_FALSE(auth.username().empty());
|
19
|
+
ASSERT_EQ("default", auth.username());
|
20
20
|
|
21
21
|
ASSERT_EQ(1, auth.buckets().size());
|
22
22
|
ASSERT_TRUE(auth.buckets().find("default")->second.empty());
|
@@ -26,7 +26,29 @@ TEST_F(CredsTest, testCreds)
|
|
26
26
|
ASSERT_EQ(LCB_SUCCESS, lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_BUCKET_CRED, creds));
|
27
27
|
ASSERT_EQ(2, auth.buckets().size());
|
28
28
|
ASSERT_EQ("pass2", auth.buckets().find("user2")->second);
|
29
|
-
ASSERT_EQ("default", auth.
|
30
|
-
ASSERT_EQ("", auth.
|
29
|
+
ASSERT_EQ("default", auth.username());
|
30
|
+
ASSERT_EQ("", auth.password());
|
31
31
|
lcb_destroy(instance);
|
32
32
|
}
|
33
|
+
|
34
|
+
TEST_F(CredsTest, testSharedAuth)
|
35
|
+
{
|
36
|
+
lcb_t instance1, instance2;
|
37
|
+
ASSERT_EQ(LCB_SUCCESS, lcb_create(&instance1, NULL));
|
38
|
+
ASSERT_EQ(LCB_SUCCESS, lcb_create(&instance2, NULL));
|
39
|
+
|
40
|
+
lcb_AUTHENTICATOR *auth = lcbauth_new();
|
41
|
+
ASSERT_EQ(1, auth->refcount());
|
42
|
+
|
43
|
+
lcb_set_auth(instance1, auth);
|
44
|
+
ASSERT_EQ(2, auth->refcount());
|
45
|
+
|
46
|
+
lcb_set_auth(instance2, auth);
|
47
|
+
ASSERT_EQ(3, auth->refcount());
|
48
|
+
|
49
|
+
ASSERT_EQ(instance1->settings->auth, instance2->settings->auth);
|
50
|
+
lcb_destroy(instance1);
|
51
|
+
lcb_destroy(instance2);
|
52
|
+
ASSERT_EQ(1, auth->refcount());
|
53
|
+
lcbauth_unref(auth);
|
54
|
+
}
|
data/lib/libcouchbase/bucket.rb
CHANGED
@@ -81,10 +81,12 @@ module Libcouchbase
|
|
81
81
|
# @example Get and lock multiple keys using custom timeout
|
82
82
|
# c.get("foo", "bar", lock: 3)
|
83
83
|
def get(*keys, extended: false, async: false, quiet: @quiet, assemble_hash: false, **opts)
|
84
|
+
keys = keys.flatten
|
85
|
+
|
84
86
|
if keys.length == 1
|
85
87
|
promise = @connection.get(keys[0], **opts)
|
86
88
|
|
87
|
-
|
89
|
+
unless extended
|
88
90
|
promise = promise.then(proc { |resp|
|
89
91
|
resp.value
|
90
92
|
})
|
@@ -604,8 +606,8 @@ module Libcouchbase
|
|
604
606
|
attrs[:language] ||= :javascript
|
605
607
|
|
606
608
|
id ||= attrs.delete(:_id)
|
607
|
-
id = id.sub(/^_design\//, '')
|
608
|
-
|
609
|
+
id = id.to_s.sub(/^_design\//, '')
|
610
|
+
|
609
611
|
result @connection.http("/_design/#{id}",
|
610
612
|
method: :put,
|
611
613
|
body: attrs,
|
@@ -46,6 +46,7 @@ module Libcouchbase
|
|
46
46
|
protected
|
47
47
|
|
48
48
|
|
49
|
+
# This is a proxy to the Bucket#result method
|
49
50
|
def result(promise)
|
50
51
|
@result.call(promise)
|
51
52
|
end
|
@@ -75,10 +76,15 @@ module Libcouchbase
|
|
75
76
|
end
|
76
77
|
alias_method :[], :view
|
77
78
|
|
79
|
+
def view_config
|
80
|
+
@row[:json][:views]
|
81
|
+
end
|
82
|
+
|
78
83
|
|
79
84
|
protected
|
80
85
|
|
81
86
|
|
87
|
+
# This is a proxy to the Bucket#result method
|
82
88
|
def result(promise)
|
83
89
|
@result.call(promise)
|
84
90
|
end
|
data/lib/libcouchbase/version.rb
CHANGED
data/spec/design_docs_spec.rb
CHANGED
@@ -20,4 +20,12 @@ describe Libcouchbase::DesignDocs do
|
|
20
20
|
views = @ddoc[:user].views
|
21
21
|
expect(views).to eq([:is_sys_admin])
|
22
22
|
end
|
23
|
+
|
24
|
+
it "should provide access to view configuration" do
|
25
|
+
config = @ddoc.design("user").view_config
|
26
|
+
expect(config.keys).to eq([:is_sys_admin])
|
27
|
+
|
28
|
+
config = @ddoc[:user].view_config
|
29
|
+
expect(config.keys).to eq([:is_sys_admin])
|
30
|
+
end
|
23
31
|
end
|
data/spec/view_spec.rb
CHANGED
@@ -54,8 +54,8 @@ describe Libcouchbase::QueryView do
|
|
54
54
|
it "should create a design document" do
|
55
55
|
doc = {
|
56
56
|
_id: "_design/blog",
|
57
|
-
|
58
|
-
|
57
|
+
language: "javascript",
|
58
|
+
views: {
|
59
59
|
recent_posts: {
|
60
60
|
map: "function(doc){if(doc.date && doc.title){emit(doc.date, doc.title);}}"
|
61
61
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: libcouchbase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen von Takach
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -317,6 +317,7 @@ files:
|
|
317
317
|
- ext/libcouchbase/include/libcouchbase/api-legacy.h
|
318
318
|
- ext/libcouchbase/include/libcouchbase/api3.h
|
319
319
|
- ext/libcouchbase/include/libcouchbase/assert.h
|
320
|
+
- ext/libcouchbase/include/libcouchbase/auth.h
|
320
321
|
- ext/libcouchbase/include/libcouchbase/cbft.h
|
321
322
|
- ext/libcouchbase/include/libcouchbase/cntl-private.h
|
322
323
|
- ext/libcouchbase/include/libcouchbase/cntl.h
|
@@ -384,8 +385,8 @@ files:
|
|
384
385
|
- ext/libcouchbase/plugins/io/select/select_io_opts.h
|
385
386
|
- ext/libcouchbase/src/README.md
|
386
387
|
- ext/libcouchbase/src/aspend.h
|
388
|
+
- ext/libcouchbase/src/auth-priv.h
|
387
389
|
- ext/libcouchbase/src/auth.cc
|
388
|
-
- ext/libcouchbase/src/auth.h
|
389
390
|
- ext/libcouchbase/src/bootstrap.c
|
390
391
|
- ext/libcouchbase/src/bootstrap.h
|
391
392
|
- ext/libcouchbase/src/bucketconfig/bc_cccp.c
|
data/ext/libcouchbase/src/auth.h
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
#ifndef LCB_AUTH_H
|
2
|
-
#define LCB_AUTH_H
|
3
|
-
|
4
|
-
#ifdef __cplusplus
|
5
|
-
#include <map>
|
6
|
-
#include <string>
|
7
|
-
namespace lcb { class Authenticator; }
|
8
|
-
typedef lcb::Authenticator lcb_AUTHENTICATOR;
|
9
|
-
extern "C" {
|
10
|
-
#else /* C only! */
|
11
|
-
typedef struct lcb_AUTHENTICATOR_Cdummy lcb_AUTHENTICATOR;
|
12
|
-
#endif
|
13
|
-
|
14
|
-
lcb_AUTHENTICATOR *
|
15
|
-
lcbauth_new(void);
|
16
|
-
|
17
|
-
void
|
18
|
-
lcbauth_free(lcb_AUTHENTICATOR *);
|
19
|
-
|
20
|
-
const char *
|
21
|
-
lcbauth_get_bpass(const lcb_AUTHENTICATOR *auth, const char *name);
|
22
|
-
|
23
|
-
void
|
24
|
-
lcbauth_set(lcb_AUTHENTICATOR *auth,
|
25
|
-
const char *user, const char *pass, int is_global);
|
26
|
-
|
27
|
-
void
|
28
|
-
lcb_authenticator_clear(lcb_AUTHENTICATOR *auth);
|
29
|
-
|
30
|
-
void
|
31
|
-
lcbauth_get_upass(const lcb_AUTHENTICATOR *auth,
|
32
|
-
const char **u, const char **p);
|
33
|
-
|
34
|
-
#ifdef __cplusplus
|
35
|
-
}
|
36
|
-
namespace lcb {
|
37
|
-
class Authenticator {
|
38
|
-
public:
|
39
|
-
typedef std::map<std::string,std::string> Map;
|
40
|
-
const std::string& username() const { return m_username; }
|
41
|
-
const std::string& password() const { return m_password; }
|
42
|
-
const Map& buckets() const { return m_buckets; }
|
43
|
-
|
44
|
-
// todo: refactor these out
|
45
|
-
Map m_buckets;
|
46
|
-
std::string m_username;
|
47
|
-
std::string m_password;
|
48
|
-
|
49
|
-
lcb_error_t init(const std::string& username_, const std::string& bucket,
|
50
|
-
const std::string& password, lcb_type_t conntype);
|
51
|
-
};
|
52
|
-
}
|
53
|
-
#endif
|
54
|
-
#endif /* LCB_AUTH_H */
|