Sample Code

The C SDK now lets you create users, assign them roles and associated privileges, and remove them from the system.

User-Management APIs

Users who have been assigned the Admin role for the cluster are able to create, edit, and remove users. The C SDK provides APIs to support these activities. A high-level summary of the APIs can be found in User-Management.

C User-Management Example

The following code-example demonstrates how the user-management APIs can be used. It assumes that Couchbase Server is established on localhost; that the Full Administrator username and password are Administrator and password respectively; and that the travel-sample bucket is installed. For information on installing the travel-sample bucket, see Sample Buckets.

Use of the Full Administrator username and password gives an application complete access to all resources within the Couchbase Server-environment: use of the Full Administrator username and password may therefore be useful during code-development. However, for production purposes, the Full Administrator username and password should only be used when absolutely essential: in all other circumstances, the specified username and password should correspond to some lesser role, which appropriately delimits access to server-resources. Creation of such a role, and the establishment of its associated username and password, is demonstrated in the following code-example.
**
* @file
*
* This is an example file showing how to create and list user accounts
* on Couchbase Cluster 5.
*
* https://developer.couchbase.com/documentation/server/current/rest-api/rbac.html
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libcouchbase/couchbase.h>

static void die(lcb_t instance, const char *msg, lcb_error_t err)
{
    fprintf(stderr, "%s. Received code 0x%X (%s)\n", msg, err, lcb_strerror(instance, err));
    exit(EXIT_FAILURE);
}

void http_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *r)
{
    const lcb_RESPHTTP *resp = (const lcb_RESPHTTP *)r;

    printf("HTTP status: %d\n", resp->htstatus);
    if (resp->headers) {
        for (const char *const *cur = resp->headers; *cur; cur += 2) {
        printf("%s: %s\n", cur[0], cur[1]);
        }
    }
    if (resp->nbody) {
        printf("%*s\n", (int)resp->nbody, (char *)resp->body);
    }
    if (resp->rc != LCB_SUCCESS) {
        die(instance, "Failed to execute HTTP request", resp->rc);
        }
    }

int main(int argc, char *argv[])
{
    lcb_error_t err;
    lcb_t instance;
    struct lcb_create_st create_options = {0};

    create_options.version = 3;

    if (argc < 3) {
        fprintf(stderr, "Usage: %s couchbase://host/bucket ADMIN_NAME ADMIN_PASSWORD\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    create_options.v.v3.connstr = argv[1];
    create_options.v.v3.username = argv[2];
    create_options.v.v3.passwd = argv[3];

    err = lcb_create(&instance, &create_options);
    if (err != LCB_SUCCESS) {
        die(NULL, "Failed create couchbase handle", err);
    }

    err = lcb_connect(instance);
    if (err != LCB_SUCCESS) {
        die(instance, "Failed schedule connection", err);
    }

    lcb_wait(instance);

    err = lcb_get_bootstrap_status(instance);
    if (err != LCB_SUCCESS) {
        die(instance, "Failed bootstrap from cluster", err);
    }

    lcb_install_callback3(instance, LCB_CALLBACK_HTTP, http_callback);

    printf("1. Create account 'cbtestuser' with predefined set of roles\n");
    {
        lcb_CMDHTTP cmd = {0};
        char *path = "/settings/rbac/users/local/cbtestuser";
        char *body = "name=TestUser&password=cbtestuserpwd&roles=cluster_admin,bucket_admin[default]";

        cmd.type = LCB_HTTP_TYPE_MANAGEMENT;
        cmd.method = LCB_HTTP_METHOD_PUT;
        cmd.content_type = "application/x-www-form-urlencoded";
        LCB_CMD_SET_KEY(&cmd, path, strlen(path));
        cmd.body = body;
        cmd.nbody = strlen(body);

        err = lcb_http3(instance, NULL, &cmd);
        if (err != LCB_SUCCESS) {
            die(instance, "Failed schedule command to upsert user", err);
        }
        lcb_wait(instance);
    }

    printf("2. Retrieve list of all accounts in the cluster\n");
    {
        lcb_CMDHTTP cmd = {0};
        char *path = "/settings/rbac/users/local";

        cmd.type = LCB_HTTP_TYPE_MANAGEMENT;
        cmd.method = LCB_HTTP_METHOD_GET;
        LCB_CMD_SET_KEY(&cmd, path, strlen(path));

        err = lcb_http3(instance, NULL, &cmd);
        if (err != LCB_SUCCESS) {
            die(instance, "Failed schedule command to upsert user", err);
        }
        lcb_wait(instance);
    }

    printf("3. Remove account 'cbtestuser'\n");
    {
        lcb_CMDHTTP cmd = {0};
        char *path = "/settings/rbac/users/local/cbtestuser";

        cmd.type = LCB_HTTP_TYPE_MANAGEMENT;
        cmd.method = LCB_HTTP_METHOD_DELETE;
        LCB_CMD_SET_KEY(&cmd, path, strlen(path));

        err = lcb_http3(instance, NULL, &cmd);
        if (err != LCB_SUCCESS) {
            die(instance, "Failed schedule command to upsert user", err);
        }
        lcb_wait(instance);
    }
    /* Now that we're all done, close down the connection handle */
    lcb_destroy(instance);
    return 0;
}