User access control


#1

I’m creating an application where every user has their own data. I’ve been reading if couchbase has something to define which data belongs to some user, and restrict access to others. It looks like the only way is creating a chanel for every user. If that’s the only way, do I need to include some property (like user) on every document? I believe that this is a little messy because every time I create any document I need to query the user identificator. Also, what if the user changes their username?


#2

You need something on a document to identify which user it belongs to, yes. If you don’t want to add a property, you can embed the user ID in the document ID. Either way, you’ll need to set up your sync function to prevent users from pushing spoofed documents.

Also, what if the user changes their username?

Don’t use the username then. You’ll need some immutable identifier for each user.


#3

I made an example application, it works, but sometimes it doesn’t synchronize correctly, and that’s strange. For example, I have a user called adam, I login with him using sync-gateway admin api, I create some documents, and they synchronize correctly and I can see them on couchbase, if I delete application data and start again, login with adam the documents are downloaded and they are showed as expected. Now, I delete application data again, and login with another user called jorge, I create some documents and they are synchronized with couchbase because I can see them on database. After that I delete application data and login again with jorge and the documents aren’t synchronized. I don’t understand why, if adam does, why jorge not? they both are created on the same way and logcat doesn’t show any error related.
This is the sync function I put on sync-gateway json configuration file:

"sync": `
           function(doc){
               requireUser(doc.owner);
               access(doc.owner, "user_" + doc.owner);
               channel("user_" + doc.owner);
            }
    `

This is how I create the document:

MutableDocument mutableDoc = new MutableDocument()
                .setString("type", "animal")
                .setString("name", name.getText().toString())
                .setString("owner", name);
                .setString("color", color.getText().toString());
        try {
            database.save(mutableDoc);
            updateRecyclerView();
        } catch (CouchbaseLiteException e) {
            e.printStackTrace();
        }

And this the synchronization:

private void startReplication() {
    try {
        URI uri = new URI("ws://192.168.1.190:4984/db");
        Endpoint targetEndpoint = new URLEndpoint(uri);
        ReplicatorConfiguration replConfig = new ReplicatorConfiguration(database, targetEndpoint);
        replConfig.setContinuous(true);
        replConfig.setReplicatorType(ReplicatorConfiguration.ReplicatorType.PUSH_AND_PULL);
        replConfig.setAuthenticator(new BasicAuthenticator(user, password));
        Replicator replicator = new Replicator(replConfig);
        replicator.start();
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
}

#4

Hmm, that’s strange.

Have you verified that the docs on the server have the expected owner property values, and that those match the actual user names in SG?

Make sure to disable the GUEST account in the SG config, otherwise the client might end up connected as a guest (unauthenticated) instead of their user account (this is a bug in 2.0.)


#5

I already verified that the docs on the server have the expected owner property values.
The GUEST account was enabled, I already disabled the account, and still having the same problem.
I’ve noted that this only happens with the last one user created. If I have users A, B and C, only C is having this problem. If I create user D, only D has this problem and C works as expected.
I can provide anything you need.


#6

Another detail I discovered: if I restart sync gateway then synchronization works as expected for all accounts, even the last one.
This is my full sync gateway cofiguration file, maybe there’s any detail I didn’t noted:

{
"interface":":4984",
"log": ["sync"],
"databases":
    {
    "db_bucket":
            {
        "import_docs": "continuous",
        "unsupported":
                    {
            "enable_extended_attributes": true,
            "replicator_2":true
        },
        "bucket":"kewelta_bucket",
        "server": "http://ipaddress:8091",
        "enable_shared_bucket_access":true,
        "username": "admin",
        "password": "qwerty123",
        "users":
            {
            "admin":
                    {
                        "password": "qwerty123",
                        "admin_channels": ["*"]
                    },
            "GUEST":
                {
                    "disabled": true
                }
        },
       "sync": `
           function(doc){
               requireUser(doc.owner);
               channel("user_" + doc.owner);
               access(doc.owner, "user_" + doc.owner);
            }
    `
    }
}

}