Couchbase-ruby-client broken by libcouchbase 2.7.4

Changes to lcb_AUTHENTICATOR broke couchbase-ruby-client.

See http://stackoverflow.com/questions/43495114/couchbase-401-unauthorized

Hi @grant. Thank you for report. I will take a look at it.

I answered at SO, but replicate the answer here too.

As a workaround, you should now explicitly pass user credentials. It is also done in preparations to Couchbase Server 5, where authentication and security in general has been improved a lot.

require 'couchbase'
@client = Couchbase.new(:node_list => ['172.19.4.22'], :bucket => 'markets',
                        :username => 'markets')
@client.design_docs

There is an issue on if you use include_docs = true when calling a view.

The error.
Couchbase::Error::Auth:
failed to get value, Authentication failed. You may have provided an invalid username/password combination

Sample code

url =  { :hostname => "192.168.1.6", :port => 8091, :bucket => 'bucket', :timeout => 15000000, :username=> 'admin'  :password => 'password'}
conn = Couchbase.connect(url)

conn.design_docs[‘sample’].get_all_samples( include_docs: true ).fetch ← THIS will fall because include_docs == true

Also

conn.get(‘blah-key’) ← fails also

If I remove the username and password the GET works but view fails.

We are using 2.7.5 libcouchbase

what server version do you use? and could you run your test script with LCB_LOGLEVEL=5 in its environment?

EE 4.6.1. I think the issue is the get command for the bucket did not have a password, while the server did. The is no way to set the bucket password.

Password specified by :password option to connection

I am using libcouchbase 2.7.5
If look at the sample above. I send the username and password and if set include_docs=true it fails, authentication. If I include_docs=false, I get the results without docs.

if i do conn.get(‘blah’) I get an Auth error.

Here is a sample using the test bucket.

This fails

 url =  { :hostname => '192.68.50.101',
          :port => 8091, :bucket => 'beer-sample',
          :timeout => 15000000, :username=> 'blah',  :password => 'something' }
conn = Couchbase.connect(url)
documents = conn.design_docs['beer'].brewery_beers( include_docs: true ).fetch

Error = in `get’: failed to get value, Authentication failed. You may have provided an invalid username/password combination (key=“21st_amendment_brewery_cafe”, error=0x02) (Couchbase::Error::Auth)

Changing include_docs = false, I get the list of keys.

This also fails

conn.get('21st_amendment_brewery_cafe')

Here is the trace from LCB_LOGLEVEL

Include_docs=true

3104ms [I0] {81335/307} [DEBUG] (ioctx - L:151) <192.68.50.101:11210> (CTX=0x7f819090a1a0,sasl) Destroying context. Pending Writes=0, Entered=true, Socket Refcount=1
3379ms [I0] {81335/307} [DEBUG] (lcbio_mgr - L:408) <192.68.50.101:11210> (HE=0x7f819003f080) Creating new connection because none are available in the pool
3379ms [I0] {81335/307} [TRACE] (lcbio_mgr - L:323) <192.68.50.101:11210> (HE=0x7f819003f080) New pool entry: I=0x7f818792da60
3379ms [I0] {81335/307} [INFO] (connection - L:465) <192.68.50.101:11210> (SOCK=0x7f8187945700) Starting. Timeout=15000000us
3379ms [I0] {81335/307} [DEBUG] (connection - L:230) <192.68.50.101:11210> (SOCK=0x7f8187945700) Created new socket with FD=15
3379ms [I0] {81335/307} [TRACE] (connection - L:332) <192.68.50.101:11210> (SOCK=0x7f8187945700) Scheduling I/O watcher for asynchronous connection completion.
3380ms [I0] {81335/307} [INFO] (connection - L:139) <192.68.50.101:11210> (SOCK=0x7f8187945700) Connected established
3380ms [I0] {81335/307} [DEBUG] (connection - L:98) <192.68.50.101:11210> (SOCK=0x7f8187945700) Successfuly set TCP_NODELAY
3380ms [I0] {81335/307} [DEBUG] (connection - L:98) <192.68.50.101:11210> (SOCK=0x7f8187945700) Successfuly set TCP_KEEPALIVE
3380ms [I0] {81335/307} [DEBUG] (lcbio_mgr - L:282) <192.68.50.101:11210> (HE=0x7f819003f080) Received result for I=0x7f818792da60,C=0x0; E=0x0
3380ms [I0] {81335/307} [DEBUG] (lcbio_mgr - L:242) <192.68.50.101:11210> (HE=0x7f819003f080) Assigning R=0x7f818795c2b0 SOCKET=0x7f8187945700
3380ms [I0] {81335/307} [TRACE] (server - L:595) <192.68.50.101:11210> (SRV=0x7f81907b30d0) Session not yet negotiated. Negotiating
3380ms [I0] {81335/307} [DEBUG] (ioctx - L:101) <192.68.50.101:11210> (CTX=0x7f81852372c0,unknown) Pairing with SOCK=0x7f8187945700
3380ms [I0] {81335/307} [DEBUG] (negotiation - L:397) <192.68.50.101:11210> (SASLREQ=0x7f8185233490) Server supports feature: 0x3 (TCP NODELAY)
3380ms [I0] {81335/307} [TRACE] (negotiation - L:542) <192.68.50.101:11210> (SASLREQ=0x7f8185233490) GET_ERRORMAP unsupported/disabled
3382ms [I0] {81335/307} [WARN] (negotiation - L:519) <192.68.50.101:11210> (SASLREQ=0x7f8185233490) SASL auth failed with STATUS=0x20
3382ms [I0] {81335/307} [ERROR] (negotiation - L:132) <192.68.50.101:11210> (SASLREQ=0x7f8185233490) Error: 0x2, SASL Step Failed
3382ms [I0] {81335/307} [ERROR] (server - L:583) <NOHOST:NOPORT> (SRV=0x7f81907b30d0,IX=0) Connection attempt failed. Received LCB_AUTH_ERROR (0x02) from libcouchbase, received 0 from operating system

Include_docs=false (works)

1718/307} [DEBUG] (lcbio_mgr - L:408) <192.68.50.101:8091> (HE=0x7fe3904d61a0) Creating new connection because none are available in the pool
27ms [I0] {81718/307} [TRACE] (lcbio_mgr - L:323) <192.68.50.101:8091> (HE=0x7fe3904d61a0) New pool entry: I=0x7fe3904d0ac0
27ms [I0] {81718/307} [INFO] (connection - L:465) <192.68.50.101:8091> (SOCK=0x7fe3904e6520) Starting. Timeout=75000000us
27ms [I0] {81718/307} [DEBUG] (connection - L:230) <192.68.50.101:8091> (SOCK=0x7fe3904e6520) Created new socket with FD=14
28ms [I0] {81718/307} [TRACE] (connection - L:332) <192.68.50.101:8091> (SOCK=0x7fe3904e6520) Scheduling I/O watcher for asynchronous connection completion.
28ms [I0] {81718/307} [INFO] (connection - L:139) <192.68.50.101:8091> (SOCK=0x7fe3904e6520) Connected established
28ms [I0] {81718/307} [DEBUG] (connection - L:98) <192.68.50.101:8091> (SOCK=0x7fe3904e6520) Successfuly set TCP_NODELAY
28ms [I0] {81718/307} [DEBUG] (connection - L:98) <192.68.50.101:8091> (SOCK=0x7fe3904e6520) Successfuly set TCP_KEEPALIVE
28ms [I0] {81718/307} [DEBUG] (lcbio_mgr - L:282) <192.68.50.101:8091> (HE=0x7fe3904d61a0) Received result for I=0x7fe3904d0ac0,C=0x0; E=0x0
28ms [I0] {81718/307} [DEBUG] (lcbio_mgr - L:242) <192.68.50.101:8091> (HE=0x7fe3904d61a0) Assigning R=0x7fe3904cca00 SOCKET=0x7fe3904e6520
28ms [I0] {81718/307} [DEBUG] (ioctx - L:101) <192.68.50.101:8091> (CTX=0x7fe39aca3450,unknown) Pairing with SOCK=0x7fe3904e6520
29ms [I0] {81718/307} [DEBUG] (ioctx - L:151) <192.68.50.101:8091> (CTX=0x7fe39aca3450,mgmt/capi) Destroying context. Pending Writes=0, Entered=true, Socket Refcount=1
29ms [I0] {81718/307} [TRACE] (http-io - L:228) <192.68.50.101:8092> GET  http://192.68.50.101:8092/beer-sample/_design/beer/_view/brewery_beers?connection_timeout=75000. Body=0 bytes
29ms [I0] {81718/307} [DEBUG] (lcbio_mgr - L:408) <192.68.50.101:8092> (HE=0x7fe3906be150) Creating new connection because none are available in the pool
29ms [I0] {81718/307} [TRACE] (lcbio_mgr - L:323) <192.68.50.101:8092> (HE=0x7fe3906be150) New pool entry: I=0x7fe3906c30d0
29ms [I0] {81718/307} [INFO] (connection - L:465) <192.68.50.101:8092> (SOCK=0x7fe3906ba4f0) Starting. Timeout=75000000us
30ms [I0] {81718/307} [DEBUG] (connection - L:230) <192.68.50.101:8092> (SOCK=0x7fe3906ba4f0) Created new socket with FD=14
30ms [I0] {81718/307} [TRACE] (connection - L:332) <192.68.50.101:8092> (SOCK=0x7fe3906ba4f0) Scheduling I/O watcher for asynchronous connection completion.
30ms [I0] {81718/307} [INFO] (connection - L:139) <192.68.50.101:8092> (SOCK=0x7fe3906ba4f0) Connected established
30ms [I0] {81718/307} [DEBUG] (connection - L:98) <192.68.50.101:8092> (SOCK=0x7fe3906ba4f0) Successfuly set TCP_NODELAY
30ms [I0] {81718/307} [DEBUG] (connection - L:98) <192.68.50.101:8092> (SOCK=0x7fe3906ba4f0) Successfuly set TCP_KEEPALIVE
30ms [I0] {81718/307} [DEBUG] (lcbio_mgr - L:282) <192.68.50.101:8092> (HE=0x7fe3906be150) Received result for I=0x7fe3906c30d0,C=0x0; E=0x0
30ms [I0] {81718/307} [DEBUG] (lcbio_mgr - L:242) <192.68.50.101:8092> (HE=0x7fe3906be150) Assigning R=0x7fe3906ba590 SOCKET=0x7fe3906ba4f0
30ms [I0] {81718/307} [DEBUG] (ioctx - L:101) <192.68.50.101:8092> (CTX=0x7fe3904d87a0,unknown) Pairing with SOCK=0x7fe3906ba4f0
79ms [I0] {81718/307} [DEBUG] (ioctx - L:151) <192.68.50.101:8092> (CTX=0x7fe3904d87a0,mgmt/capi) Destroying context. Pending Writes=0, Entered=true, Socket Refcount=1
79ms [I0] {81718/307} [INFO] (lcbio_mgr - L:458) <192.68.50.101:8092> (HE=0x7fe3906be150) Placing socket back into the pool. I=0x7fe3906c30d0,C=0x7fe3906ba4f0
196ms [I0] {81718/307} [DEBUG] (ioctx - L:151) <192.68.50.101:8091> (CTX=0x7fe39a901a00,bc_http) Destroying context. Pending Writes=0, Entered=false, Socket Refcount=1

Hi @grant and @dipen_patel

I have updated ruby client, and this issue has been fixed on master. Now ruby SDK completely support recent libcouchbase and RBAC authentication. This is how you can test it

git clone git://github.com/couchbase/couchbase-ruby-client.git
cd couchbase-ruby-client
bundle install
bundle exec rake compile
bundle exec rake console
irb(main):001:0> cb = Couchbase.connect('couchbase://127.0.0.1/beer-sample', password: 'password', username: 'Administrator')
=> #<Couchbase::Bucket:0x0000555f63923390 "couchbase://127.0.0.1/beer-sample/" transcoder=Couchbase::Transcoder::Document, default_flags=0x0, connected=true, timeout=2500000, bootstrap_transport=:cccp>

irb(main):002:0> view = cb.design_docs['brewery'].all(limit: 3)
=> #<Couchbase::View:46934090392060 @endpoint="_design/brewery/_view/all" @params={:connection_timeout=>75000, :limit=>3}>

irb(main):003:0> view.each { |e| puts e.key }
21st_amendment_brewery_cafe
3_fonteinen_brouwerij_ambachtelijke_geuzestekerij
357
=> nil

Note, that you would need to use connection string (couchbase://127.0.0.1/beer-sample/) instead of node list or separate host/port options.