public static Func<string, string, IOStrategy, IByteConverter, ISaslMechanism> GetFactory3()
 {
     return (username, password, strategy, converter) =>
     {
         ISaslMechanism saslMechanism = null;
         var connection = strategy.ConnectionPool.Acquire();
         try
         {
             var saslListResult = strategy.Execute(new SaslList(converter), connection);
             if (saslListResult.Success)
             {
                 if (saslListResult.Value.Contains("CRAM-MD5"))
                 {
                     saslMechanism = new CramMd5Mechanism(strategy ,username, password, converter);
                 }
                 else
                 {
                     saslMechanism = new PlainTextMechanism(strategy, username, password, converter);
                 }
             }
         }
         catch (Exception e)
         {
             Log.Error(e);
         }
         return saslMechanism;
     };
 } 
 public static Func <string, string, IOStrategy, IByteConverter, ISaslMechanism> GetFactory3()
 {
     return((username, password, strategy, converter) =>
     {
         ISaslMechanism saslMechanism = null;
         var connection = strategy.ConnectionPool.Acquire();
         try
         {
             var saslListResult = strategy.Execute(new SaslList(converter), connection);
             if (saslListResult.Success)
             {
                 if (saslListResult.Value.Contains("CRAM-MD5"))
                 {
                     saslMechanism = new CramMd5Mechanism(strategy, username, password, converter);
                 }
                 else
                 {
                     saslMechanism = new PlainTextMechanism(strategy, username, password, converter);
                 }
             }
         }
         catch (Exception e)
         {
             Log.Error(e);
         }
         if (saslMechanism != null)
         {
             saslMechanism.IOStrategy = strategy;
         }
         return saslMechanism;
     });
 }
        public const uint DefaultTimeout = 2500; //2.5sec

        public static Func <string, string, IOStrategy, ITypeTranscoder, ISaslMechanism> GetFactory3()
        {
            return((username, password, strategy, transcoder) =>
            {
                ISaslMechanism saslMechanism = null;
                var connection = strategy.ConnectionPool.Acquire();
                try
                {
                    var saslListResult = strategy.Execute(new SaslList(transcoder, DefaultTimeout), connection);
                    if (saslListResult.Success)
                    {
                        if (saslListResult.Value.Contains("CRAM-MD5"))
                        {
                            saslMechanism = new CramMd5Mechanism(strategy, username, password, transcoder);
                        }
                        else
                        {
                            saslMechanism = new PlainTextMechanism(strategy, username, password, transcoder);
                        }
                    }
                }
                catch (Exception e)
                {
                    Log.Error(e);
                }
                finally
                {
                    strategy.ConnectionPool.Release(connection);
                }
                return saslMechanism;
            });
        }
        public void When_Authentication_Fails_AuthenticationException_Or_ConnectionUnavailableException_Is_Thrown()
        {
            var authenticator = new CramMd5Mechanism(_ioStrategy, "authenticated", "secretw", new DefaultTranscoder());
            _ioStrategy.SaslMechanism = authenticator;

            //The first two iterations will throw auth exceptions and then a CUE;
            //you will never find yourself in an infinite loop waiting for connections that don't exist.
            int count = 0;
            while (count < 3)
            {
                count++;
                try
                {
                    var config = new Config(new DefaultTranscoder(), OperationLifespan, UriExtensions.GetEndPoint(Address));
                    var result = _ioStrategy.Execute(config);
                    Console.WriteLine(result.Success);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    var type = e.GetType();
                    if (type == typeof (AuthenticationException) || type == typeof (ConnectionUnavailableException))
                    {
                        continue;
                    }
                    Assert.Fail();
                }
            }
            Assert.Pass();
        }
        public void When_InValid_Credentials_Provided_Authenticate_Returns_False2()
        {
            var authenticator = new CramMd5Mechanism(_ioService, "authenticated", "wrongpass", new DefaultTranscoder());
            _ioService.SaslMechanism = authenticator;

            foreach (var connection in _ioService.ConnectionPool.Connections)
            {
                var isAuthenticated = authenticator.Authenticate(connection);
                Assert.IsFalse(isAuthenticated);
            }
        }
        public void When_Valid_Credentials_Provided_Authenticate_Returns_True()
        {
            var authenticator = new CramMd5Mechanism(_ioService, new DefaultTranscoder());
            _ioService.SaslMechanism = authenticator;

            foreach (var connection in _ioService.ConnectionPool.Connections)
            {
                var isAuthenticated = authenticator.Authenticate(connection, "authenticated", "secret");
                Assert.IsTrue(isAuthenticated);
            }
        }
        public void When_InValid_Credentials_Provided_Authenticate_Returns_False2()
        {
            var authenticator = new CramMd5Mechanism(_ioStrategy, "authenticated", "wrongpass", new ManualByteConverter());
            _ioStrategy.ConnectionPool.Initialize();
            _ioStrategy.SaslMechanism = authenticator;

            foreach (var connection in _ioStrategy.ConnectionPool.Connections)
            {
                var isAuthenticated = authenticator.Authenticate(connection);
                Assert.IsFalse(isAuthenticated);
            }
        }
        public const uint DefaultTimeout = 2500; //2.5sec

        #endregion Fields

        #region Methods

        public static Func<string, string, IIOService, ITypeTranscoder, ISaslMechanism> GetFactory(ILoggerFactory loggerFactory)
        {
            return (username, password, service, transcoder) =>
            {
                var logger = loggerFactory.CreateLogger("Couchbase.Authentication.SASL." + nameof(SaslFactory));

                ISaslMechanism saslMechanism = null;
                IConnection connection = null;
                try
                {
                    connection = service.ConnectionPool.Acquire();

                    var saslListResult = service.Execute(new SaslList(transcoder, DefaultTimeout), connection);
                    if (saslListResult.Success)
                    {
                        if (saslListResult.Value.Contains("CRAM-MD5"))
                        {
                            saslMechanism = new CramMd5Mechanism(service, username, password, transcoder, loggerFactory);
                        }
                        else
                        {
                            saslMechanism = new PlainTextMechanism(service, username, password, transcoder, loggerFactory);
                        }
                    }
                }
                catch (Exception e)
                {
                    logger.LogError(e.Message, e);
                }
                finally
                {
                    if (connection != null)
                    {
                        service.ConnectionPool.Release(connection);
                    }
                }
                return saslMechanism;
            };
        }
        public const uint DefaultTimeout = 2500; //2.5sec

        public static Func<string, string, IOStrategy, ITypeTranscoder, ISaslMechanism> GetFactory()
        {
            return (username, password, strategy, transcoder) =>
            {
                ISaslMechanism saslMechanism = null;
                IConnection connection = null;
                try
                {
                    connection = strategy.ConnectionPool.Acquire();
                    var saslListResult = strategy.Execute(new SaslList(transcoder, DefaultTimeout), connection);
                    if (saslListResult.Success)
                    {
                        if (saslListResult.Value.Contains("CRAM-MD5"))
                        {
                            saslMechanism = new CramMd5Mechanism(strategy, username, password, transcoder);
                        }
                        else
                        {
                            saslMechanism = new PlainTextMechanism(strategy, username, password, transcoder);
                        }
                    }
                }
                catch (Exception e)
                {
                    Log.Error(e);
                }
                finally
                {
                    if (connection != null)
                    {
                        strategy.ConnectionPool.Release(connection);
                    }
                }
                return saslMechanism;
            };
        }
        public void When_Bucket_Has_No_Password_And_Password_Is_Null_Authenticate_Succeeds()
        {
            var authenticator = new CramMd5Mechanism(_ioService, "default", null, new DefaultTranscoder());
            _ioService.ConnectionPool.Initialize();
            _ioService.SaslMechanism = authenticator;

            foreach (var connection in _ioService.ConnectionPool.Connections)
            {
                var isAuthenticated = authenticator.Authenticate(connection);
                Assert.IsTrue(isAuthenticated);
            }
        }
        public void When_IOException_Occurs_Authenticate_Throws_Exception()
        {
            var authenticator = new CramMd5Mechanism(_ioService, "default", string.Empty, new DefaultTranscoder());
            _ioService.ConnectionPool.Initialize();

            var connection = _ioService.ConnectionPool.Acquire();
            connection.Socket.Disconnect(false);

            Assert.Throws<SocketException>(() => authenticator.Authenticate(connection));
        }
        public void Test_ComputeResponse()
        {
            var authenticator = new CramMd5Mechanism(_ioService, "protected", "secret", new DefaultTranscoder());
            const string challenge = "6382f3e79a804548"; //"15cedeaaf8b06c34";
            const string expected = "protected 3ca7b9f1b81bc7f6c2c9e5f48af3311d"; //"protected 06f8b68edb01c7b453f50429d4bfb195";

            var actual = authenticator.ComputeResponse(challenge);
            Assert.AreEqual(expected, actual);
        }
        public void When_Bucket_Has_No_Password_Authenticate_Succeeds()
        {
            var authenticator = new CramMd5Mechanism(_ioStrategy, "default", string.Empty, new DefaultTranscoder());
            _ioStrategy.ConnectionPool.Initialize();

            foreach (var connection in _ioStrategy.ConnectionPool.Connections)
            {
                var isAuthenticated = authenticator.Authenticate(connection);
                Assert.IsTrue(isAuthenticated);
            }
        }
        public void When_IOException_Occurs_Authenticate_Throws_Exception()
        {
            var authenticator = new CramMd5Mechanism(_ioStrategy, "default", string.Empty, new ManualByteConverter());
            _ioStrategy.ConnectionPool.Initialize();

            var connection = _ioStrategy.ConnectionPool.Acquire();
            connection.Socket.Disconnect(false);

            authenticator.Authenticate(connection);
        }