Views seem to ignore custom password?

Hi,

I'm currently stuck with an issue with .NET SDK (1.2.9, server 2.2 enterprise), configuration and password management.

Steps to reproduce:

1) I have a beer-sample bucket on localhost, with SASL password set to 123

2) Configuration file of my application is as below (note that bucket password is not there):

<?xml version="1.0"?>
<configuration>
  <configSections>
  	<section name="couchbase" type="Couchbase.Configuration.CouchbaseClientSection, Couchbase"/>
  </configSections>
 <couchbase>
    <servers bucket="beer-sample" >
      <add uri="http://localhost:8091/pools"/>
    </servers>
  </couchbase>
</configuration>

3) Sample C# code specifies the password as parameter:

class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var client = new CouchbaseClient("couchbase", "beer-sample", "123");
                var res = client.ExecuteGet("21st_amendment_brewery_cafe");
                if (res.Success)
                    Console.WriteLine("Get worked!");
                else
                    Console.WriteLine("Get failed!");
 
                var f = client.GetView("beer", "by_location").GroupAt(1);
                foreach (var zz in f)
                    Console.WriteLine(zz.ViewKey[0]);
            }
            catch (ViewException ve)
            {
                Console.WriteLine("ViewException: {0} / {1}",ve.Message, ve.Reason);
            }
            catch (Exception eee)
            {
                Console.WriteLine("Exception: "+eee.Message);
            }
        }
    }

and produces output:

Get worked!
ViewException: Query failed for view by_location in design document beer / password required

.

So the password provided in C# code is working for Get operation, as expected, but not for views, which ignore it. If I add the "123" bucket password to the configuration file, it works fine.

Is it a .NET SDK bug?

1 Answer

« Back to question.

After inspection, it seems like omission in the CouchbaseClientSection.

A workaround is to create a custom configuration class, like below:

class CouchbaseClientConfigurationFix : ICouchbaseClientConfiguration
    {
        private ICouchbaseClientConfiguration _base;
        private string _passOverride;
        private string _bucketOverride;
        private IHttpClientFactory _clientFactory;
 
        public CouchbaseClientConfigurationFix(string sectionName, string bucketName, string bucketPassword)
        {
            var section = (CouchbaseClientSection)System.Configuration.ConfigurationManager.GetSection(sectionName);
            if (section == null)
                throw new System.Configuration.ConfigurationException("Could not find Couchbase section '" + sectionName + "'");
 
            _base = section;
 
            var tmp = section.HttpClientFactory;
            _clientFactory = tmp == null ? DefaultHttpClientFactory.Instance : tmp.CreateInstance();
            _bucketOverride = bucketName;
            _passOverride = bucketPassword;
        }
        public string Bucket { get{ return _bucketOverride??_base.Bucket;}}
        public string BucketPassword { get { return _passOverride??_base.Password;}}
        public IHttpClient CreateHttpClient(Uri baseUri)
        {
            return _clientFactory.Create(baseUri, this.Bucket, this.BucketPassword, HttpClient.Timeout, HttpClient.InitializeConnection);
        }
 
        public INameTransformer CreateDesignDocumentNameTransformer() { return _base.CreateDesignDocumentNameTransformer(); }
        public Enyim.Caching.Memcached.IMemcachedKeyTransformer CreateKeyTransformer() { return _base.CreateKeyTransformer(); }
        public Enyim.Caching.Memcached.IMemcachedNodeLocator CreateNodeLocator() { return _base.CreateNodeLocator(); }
        public Enyim.Caching.Memcached.IPerformanceMonitor CreatePerformanceMonitor() { return _base.CreatePerformanceMonitor(); }
        public Enyim.Caching.Memcached.ITranscoder CreateTranscoder() { return _base.CreateTranscoder(); }
        public IHeartbeatMonitorConfiguration HeartbeatMonitor { get { return _base.HeartbeatMonitor; } }
        public IHttpClientConfiguration HttpClient { get { return _base.HttpClient; } }
        public TimeSpan HttpRequestTimeout { get { return _base.HttpRequestTimeout; } }
        public TimeSpan ObserveTimeout { get { return _base.ObserveTimeout; } }
        public string Password { get { return _base.Password; } }
        public int RetryCount { get { return _base.RetryCount; } }
        public TimeSpan RetryTimeout { get { return _base.RetryTimeout; } }
        public Enyim.Caching.Configuration.ISocketPoolConfiguration SocketPool { get { return _base.SocketPool; } }
        public IList<Uri> Urls { get { return _base.Urls; } }
        public string Username { get { return _base.Username; } }
    }

and then

var config = new CouchbaseClientConfigurationFix("couchbase", "beer-sample", "123");
var client = new CouchbaseClient(config);
var res = client.ExecuteGet("21st_amendment_brewery_cafe");
if (res.Success)
                ...