We have Sync Gateway 2.8 running with a Couchbase 7.1 installation and we’re having some difficulty setting things up. Initially we had several buckets, each with a sync function that hardcoded the channel name for that data (e.g. bucket “one” would have a sync function that set the channel for all docs to “one” and enforced it for access).
When we realized that this wouldn’t scale, we moved all the data from several buckets into one large bucket and made a sync function that would set the channel based on a field in every document. We then imported the data from the other buckets using cbimport. When I look at the data via N1QL or the Admin Console “Documents”, they all look correct, including the “channels” in the metadata.
Now, for some reason, our test users who should have access to these channels cannot access some of them. They are seeing failures in Couchbase Lite on iOS, and we can duplicate the problem from the command line via curl.
Here’s some concrete examples to hopefully make it clearer:
# Configuration:
$ curl -kSs -u "admin:password" -H "content-type: application/json" -H "accept: application/json" https://localhost:4985/licensees/_config | jq '.'
{
"server": "couchbase://sdpmwdeusd0",
"pool": "default",
"bucket": "bucket-licensees",
"username": "Administrator",
"password": "****",
"name": "licensees",
"sync": "function(doc, oldDoc) {\n if (doc.doc_type) {\n if (doc.licensee_id === undefined ) {\n channel(\"!\");\n } else if (doc.doc_type === \"Licensee\") {\n requireAccess(doc._id);\n channel(doc._id);\n } else {\n requireAccess(doc.licensee_id);\n channel(doc.licensee_id);\n }\n }\n }",
"users": {
"GUEST": {
"name": "",
"admin_channels": [
"*"
],
"all_channels": null,
"disabled": true,
"password": "****"
},
"admin": {
"name": "admin",
"admin_channels": [
"*"
],
"all_channels": null,
"password": "****"
},
"mike.totman@safedoorpm.com": {
"name": "mike.totman@safedoorpm.com",
"admin_channels": [
"canadoor-dev",
"docks-doors-dev",
"just-docks-dev"
],
"all_channels": null,
"password": "****"
}
},
"revs_limit": 20,
"import_docs": true,
"import_backup_old_rev": false,
"cache": {
"rev_cache": {},
"channel_cache": {}
},
"unsupported": {
"user_views": {},
"oidc_test_provider": {},
"api_endpoints": {},
"warning_thresholds": {
"xattr_size_bytes": 943718,
"channels_per_doc": 50,
"access_and_role_grants_per_doc": 50
},
"oidc_tls_skip_verify": false,
"sgr_tls_skip_verify": false
},
"deprecated": {},
"enable_shared_bucket_access": true,
"session_cookie_name": "",
"session_cookie_http_only": false,
"allow_conflicts": false,
"num_index_replicas": 0,
"use_views": false
}
# Create a document using our admin user
$ curl -kSs -u "admin:password" -H "content-type: application/json" -H "accept: application/json" -X PUT "https://localhost:4984/licensees/test-doc" --data-binary @/tmp/doc.json
{"error":"Forbidden","reason":"sg missing channel access"}
$ jq '.' /tmp/doc.json
{
"_id": "test-doc",
"doc_type": "test",
"licensee_id": "test"
}
doc_type
is a field required in all of our app’s documents. licensee_id
is in most of them, but it is not required.
Sync function as it appears in the config file, for readability:
function(doc, oldDoc) {
if (doc.doc_type) {
if (doc.licensee_id === undefined ) {
channel("!");
} else if (doc.doc_type === "Licensee") {
requireAccess(doc._id);
channel(doc._id);
} else {
requireAccess(doc.licensee_id);
channel(doc.licensee_id);
}
}
}
Previously we could at least add documents with curl PUT
and read them back with the admin user, but it would fail with the error “Forbidden” if we used other users.
Any idea what’s going on? Does that sync function look correct? What else should we be looking at?