libcouchbase 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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 */
|