Trouble with authorization in sync function

I'm having some trouble adding some authorization into our couchbase mobile app. Can you offer any help or insight?

I'm running this on an amazon ec2 instance so the couchbase version may be a little older than current.

I'm using persona to authenticate. I successfully authenticate and then log in using a POST to the sync gateway with the url ending with _persona. I see in the logs Persona: Logged in brian@consultant.com

In my Android mobile code I get a hold of a document and try to update its properties. No exception is thrown in the client code. I see this in the couchbase logging window.

21:14:04.905611 CRUD+: Invoking sync on doc "brian@consultant.com" rev 8-013f9884-f373-4934-8969-5a4c14a902ef
21:14:04.905966 WARNING: Sync fn exception: TypeError; doc = map[_rev:8-013f9884-f373-4934-8969-5a4c14a902ef mySchedule:[] type:user _id:brian@consultant.com _revisions:map[start:%!s(float64=8) ids:[013f9884-f373-4934-8969-5a4c14a902ef 11e09725-0e98-46f2-a3b7-d2285ba7425a 42ec0784-604d-4719-9d69-ab2591d77263 c3fc859e-996a-4141-84ac-68e760a414d4 5becbf8d-cdc1-4523-9ef9-3bee9aa796ea 2513787e-0c5e-48f6-9e35-19109056a9c2 009d30a7-322f-4317-93b8-e4e376be879e 903d36b5-ae6f-4b7a-b6f4-3ed5f4e0bc9e]]] -- db.(*Database).getChannelsAndAccess() at crud.go:553
21:14:04.906041 BulkDocs: Doc "brian@consultant.com" --> 500 Exception in JS sync function (Exception in JS sync function)
21:14:04.906093 HTTP+: #032: --> 201 (1.6 ms)
21:14:04.906611 CRUD+: Invoking sync on doc "brian@consultant.com" rev 8-013f9884-f373-4934-8969-5a4c14a902ef
21:14:04.906815 WARNING: Sync fn exception: TypeError; doc = map[_rev:8-013f9884-f373-4934-8969-5a4c14a902ef mySchedule:[] type:user _id:brian@consultant.com _revisions:map[start:%!s(float64=8) ids:[013f9884-f373-4934-8969-5a4c14a902ef 11e09725-0e98-46f2-a3b7-d2285ba7425a 42ec0784-604d-4719-9d69-ab2591d77263 c3fc859e-996a-4141-84ac-68e760a414d4 5becbf8d-cdc1-4523-9ef9-3bee9aa796ea 2513787e-0c5e-48f6-9e35-19109056a9c2 009d30a7-322f-4317-93b8-e4e376be879e 903d36b5-ae6f-4b7a-b6f4-3ed5f4e0bc9e]]] -- db.(*Database).getChannelsAndAccess() at crud.go:553
21:14:04.906839 BulkDocs: Doc "brian@consultant.com" --> 500 Exception in JS sync function (Exception in JS sync function)
21:14:04.906880 HTTP+: #033: --> 201 (2.0 ms)
21:14:07.500479 HTTP: #034: PUT /bsg_sync/_local/9c9619549c733242f7bd4a53c28c7786818a04a4
21:14:07.501121 HTTP+: #034: --> 201 (1.0 ms)
21:14:07.507888 HTTP: #035: PUT /bsg_sync/_local/9c9619549c733242f7bd4a53c28c7786818a04a4
21:14:07.508118 HTTP: #035: --> 409 Document update conflict
21:14:28.632673 HTTP: #036: POST /bsg_sync/_revs_diff
21:14:28.633323 HTTP+: #036: --> 200 (1.0 ms)
21:14:28.639796 HTTP: #037: POST /bsg_sync/_revs_diff
21:14:28.640491 HTTP+: #037: --> 200 (1.0 ms)
21:14:29.022395 HTTP: #038: POST /bsg_sync/_bulk_docs
21:14:29.023219 CRUD+: Invoking sync on doc "brian@consultant.com" rev 9-714eec9f-90bd-4147-88d6-7e93a2b79f7b
21:14:29.023451 CRUD+: No old revision "brian@consultant.com" / "8-013f9884-f373-4934-8969-5a4c14a902ef"
21:14:29.023633 CRUD+: Saving old revision "brian@consultant.com" / "7-11e09725-0e98-46f2-a3b7-d2285ba7425a" (31 bytes)
21:14:29.038096 CRUD+: Backed up obsolete rev "brian@consultant.com"/"7-11e09725-0e98-46f2-a3b7-d2285ba7425a"
21:14:29.038594 CRUD: Stored doc "brian@consultant.com" / "9-714eec9f-90bd-4147-88d6-7e93a2b79f7b"
21:14:29.038624 Changes: Updating #1246 "brian@consultant.com"/"9-714eec9f-90bd-4147-88d6-7e93a2b79f7b" in channels {}
21:14:29.038685 HTTP+: #038: --> 201 (16.6 ms)
21:14:29.081423 HTTP: #039: POST /bsg_sync/_bulk_docs
21:14:29.082972 CRUD+: PutExistingRev("brian@consultant.com"): No new revisions to add
21:14:29.083039 HTTP+: #039: --> 201 (1.9 ms)

This is what I put in my config.json:
{
"interface": ":4984",
"adminInterface": ":4985",
"log": ["CRUD", "CRUD+", "HTTP", "HTTP+", "Access", "Cache", "Shadow", "Shadow+", "Changes", "Changes+"],
"persona": { "origin": "http://myserver.com:4984/", "register": true },
"databases": {
"our_sync": {
"server": "http://localhost:8091",
"bucket": "our_sync",
"users": {
"GUEST": {"disabled": false, "admin_channels":["*"], "all_channels":["*"]}
},
"sync": `function(doc, oldDoc, userCtx) {
if (oldDoc) {
userCtx.requireUser("brian@consultant.com");
}
channel(doc.channels);
}`
}
}
}

1 Answer

« Back to question.

Your sync function is throwing a JavaScript exception.

function(doc, oldDoc, userCtx) {
if (oldDoc) {
userCtx.requireUser("brian@consultant.com");

The sync function only takes two parameters; there is no userCtx. So you're calling a method on an undefined value, causing an exception.

So take out the userCtx parameter, and call requireUser() as a plain function not a method.

(If you read some docs that told you to do what you were doing, please let us know where you found them so we can fix them! IIRC, a long time ago the sync function did work this way, but it hasn't for at least six months.)

--Jens

Thanks Jens. That worked. Mostly what I read on the internet says to use userCtx.name == "something".

In my client code I do something like this:

Document document = getDocumentById(identity.getUser().getId());
properties = document.getProperties();
Map newProperties = new HashMap(properties);
newProperties.put("mySchedule", updatedSchedule);
try {
document.putProperties(newProperties);
} catch (CouchbaseLiteException e) {
status = AddStatus.FAILURE;
}

Why is no exception thrown? I see the sync gateway logging output

BulkDocs: Doc "eric@consultant.com" --> 403 wrong user (wrong user)

How can I know a problem occurred in the client code?

Thank you,
Brian

> Mostly what I read on the internet says to use userCtx.name == "something".

Then you've been reading about CouchDB validation functions, not Sync Gateway sync functions :) They are not the same thing.