How to get more info in debug log

When an error occurs I’m only seeing some basic info.

2021-04-08T21:35:45.037Z [INF] HTTP:  #37869: PUT /salesrabbit/_user/auth0%7CQonGEZfIY45NQt-9F172k (as ADMIN)
2021-04-08T21:35:45.038Z [INF] HTTP: #37869:     --> 400 Empty passwords are not allowed   (1.1 ms)

The body of the request from the client app is

{"admin_channels": ["O.R_1_3617", "U_1_11716850"], "email": "test@example.com"}

I wish I could see in the debug log the body and headers of the request. I can make this call work locally using curl but not in the stage cluster env. I suspect there is a missing header but getting difficult to debug

That error does occur with curl for me if I add "password": "" to the json body, but works if I don’t include the password key

I had a quick look through the code around this error and it doesn’t look like it can be coming from any kind of missing header. We only ever look in the request body for the password.

The only thing I can see happening would be the allow_empty_password config option is different between your local and staging env?

If you want to look at traffic on the wire between your client and Sync Gateway, you could take a look at Wireshark, or if that’s too complicated, have a HTTP proxy running that logs everything that goes through it (like mitmproxy).

The only thing I can see happening would be the allow_empty_password config option is different between your local and staging env?

Interesting, it’s setup for oidc which allows empty passwords, but we aren’t setting that explicitly.

Actually looking at using wireshark to try and shed light.

I had a quick look through the code around this error and it doesn’t look like it can be coming from any kind of missing header. We only ever look in the request body for the password.

When the Host header is missing it throws a 400 error, and ofcourse if the Content-Length header is missing it blows up and returns a HTML error. Content-Type as text caused another error.

tcpdump shows no signs of issues with the headers or content. This call is going thru a nginx proxy nothing looks out of the ordinary.

Haha, it was the silly double encoding issue in the url. That is such a weird concern.

Ah interesting - so the request was being treated as creating a new user, rather than updating an existing one? Glad you found the issue!

Not sure what we could do in SG to improve the visibility of that, maybe just a bit of additional logging if we don’t find an existing user?

Maybe don’t overload the REST command PUT to allow creation and let REST do it’s thing. If it’s not found then throw 404 error. Solved. It at least would force the API consumer to evaluate the user it is sending.

In addition, don’t transform data. If a client has a value that needs to be encoded then store that value as decoded and make sure it is returned decoded. There seem to be a lot of small concerns being pushed to the client that can lead to issues like this.

The encoding/decoding thing I do agree with - the API should be consistent either one way or the other. What API endpoint specifically is returning encoded IDs? (i.e. Where did you get auth0%7CQonGEZfIY45NQt-9F172k from?)

That’s not how PUT is supposed to work, per RFC-7231, nor have I seen any REST API do that on PUT before, so I’m not sure we should do that, even if Sync Gateway is not the best shining example of a REST API today.

4.3.4. PUT
The PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload.

Fair enough about PUT. I’d submit that it’s widely accepted that PUT is used to only update/replace.

auth0%7CQonGEZfIY45NQt-9F172k came from a GET call to the admin api. It’s the users “name”

The errors should state that it was trying to create vs update.

Single responsibility comes to mind. I’m still stewing a bit on this

I’m sorry but you’re stewing about standard HTTP/REST API behaviour. PUT is idempotent, and will create non-existent objects at the location you’ve asked for. We’re really not doing anything weird here in that regard.

I opened a PR to improve the error message in the create/update code paths:

$ curl -X PUT http://localhost:4985/db1/_user/foo1 -d '{"password":""}'
{"error":"Bad Request","reason":"Error creating user: Empty passwords are not allowed "}

$ curl -X PUT http://localhost:4985/db1/_user/foo1 -d '{"password":"bar"}'

$ curl -X PUT http://localhost:4985/db1/_user/foo1 -d '{"password":""}'
{"error":"Bad Request","reason":"Error updating user/role: Empty passwords are not allowed "}