1 #include "config.h"
2 #include "internal.h"
3 #include "auth-priv.h"
4 #include <gtest/gtest.h>
5 #define LIBCOUCHBASE_INTERNAL 1
6 #include <libcouchbase/couchbase.h>
7 
8 class CredsTest : public ::testing::Test
9 {
10 };
11 
create(const char * connstr=NULL)12 static lcb_t create(const char *connstr = NULL) {
13     lcb_create_st crst;
14     memset(&crst, 0, sizeof crst);
15     crst.version = 3;
16     crst.v.v3.connstr = connstr;
17     lcb_t ret;
18     lcb_error_t rc = lcb_create(&ret, &crst);
19     EXPECT_EQ(LCB_SUCCESS, rc);
20     return ret;
21 }
22 
TEST_F(CredsTest,testLegacyCreds)23 TEST_F(CredsTest, testLegacyCreds)
24 {
25     lcb_t instance;
26     ASSERT_EQ(LCB_SUCCESS, lcb_create(&instance, NULL));
27     lcb::Authenticator& auth = *instance->settings->auth;
28     ASSERT_TRUE(auth.username().empty());
29     ASSERT_EQ(LCBAUTH_MODE_CLASSIC, auth.mode());
30 
31     ASSERT_EQ(1, auth.buckets().size());
32     ASSERT_TRUE(auth.buckets().find("default")->second.empty());
33     ASSERT_EQ("", auth.password_for(NULL, NULL, "default"));
34     ASSERT_EQ("default", auth.username_for(NULL, NULL, "default"));
35 
36     // Try to add another user/password:
37     lcb_BUCKETCRED creds = { "user2", "pass2" };
38     ASSERT_EQ(LCB_SUCCESS, lcb_cntl(instance, LCB_CNTL_SET, LCB_CNTL_BUCKET_CRED, creds));
39     ASSERT_EQ(2, auth.buckets().size());
40     ASSERT_EQ("pass2", auth.buckets().find("user2")->second);
41     ASSERT_EQ("user2", auth.username_for(NULL, NULL, "user2"));
42     ASSERT_EQ("pass2", auth.password_for(NULL, NULL, "user2"));
43 
44     ASSERT_TRUE(auth.username().empty());
45     ASSERT_TRUE(auth.password().empty());
46     lcb_destroy(instance);
47 }
48 
TEST_F(CredsTest,testRbacCreds)49 TEST_F(CredsTest, testRbacCreds) {
50     lcb_t instance = create("couchbase://localhost/default?username=mark");
51     lcb::Authenticator& auth = *instance->settings->auth;
52     ASSERT_EQ("mark", auth.username());
53     ASSERT_EQ(LCBAUTH_MODE_RBAC, auth.mode());
54     ASSERT_TRUE(auth.buckets().empty());
55     ASSERT_EQ("mark", auth.username_for(NULL, NULL, "default"));
56     ASSERT_EQ("", auth.password_for(NULL, NULL, "default"));
57     ASSERT_EQ("mark", auth.username_for(NULL, NULL, "jane"));
58     ASSERT_EQ("", auth.password_for(NULL, NULL, "jane"));
59 
60     // Try adding a new bucket, it should fail
61     ASSERT_EQ(LCB_OPTIONS_CONFLICT, auth.add("users", "secret", LCBAUTH_F_BUCKET));
62 
63     // Try using "old-style" auth. It should fail:
64     ASSERT_EQ(LCB_OPTIONS_CONFLICT, auth.add("users", "secret", LCBAUTH_F_BUCKET|LCBAUTH_F_CLUSTER));
65     // Username/password should remain unchanged:
66     ASSERT_EQ("mark", auth.username());
67     ASSERT_EQ("", auth.password());
68 
69     // Try *changing* the credentials
70     ASSERT_EQ(LCB_SUCCESS, auth.add("jane", "seekrit", LCBAUTH_F_CLUSTER));
71     ASSERT_EQ("jane", auth.username_for(NULL, NULL, "default"));
72     ASSERT_EQ("seekrit", auth.password_for(NULL, NULL, "default"));
73     lcb_destroy(instance);
74 }
75 
TEST_F(CredsTest,testSharedAuth)76 TEST_F(CredsTest, testSharedAuth)
77 {
78     lcb_t instance1, instance2;
79     ASSERT_EQ(LCB_SUCCESS, lcb_create(&instance1, NULL));
80     ASSERT_EQ(LCB_SUCCESS, lcb_create(&instance2, NULL));
81 
82     lcb_AUTHENTICATOR *auth = lcbauth_new();
83     ASSERT_EQ(1, auth->refcount());
84 
85     lcb_set_auth(instance1, auth);
86     ASSERT_EQ(2, auth->refcount());
87 
88     lcb_set_auth(instance2, auth);
89     ASSERT_EQ(3, auth->refcount());
90 
91     ASSERT_EQ(instance1->settings->auth, instance2->settings->auth);
92     lcb_destroy(instance1);
93     lcb_destroy(instance2);
94     ASSERT_EQ(1, auth->refcount());
95     lcbauth_unref(auth);
96 }
97