public void InitializeConnectionA_should_build_the_ConnectionDescription_correctly( [Values(false, true)] bool async) { var isMasterReply = MessageHelper.BuildReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1 }")); var buildInfoReply = MessageHelper.BuildReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1, version: \"2.6.3\" }")); var gleReply = MessageHelper.BuildReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1, connectionId: 10 }")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(isMasterReply); connection.EnqueueReplyMessage(buildInfoReply); connection.EnqueueReplyMessage(gleReply); ConnectionDescription result; if (async) { result = _subject.InitializeConnectionAsync(connection, CancellationToken.None).GetAwaiter().GetResult(); } else { result = _subject.InitializeConnection(connection, CancellationToken.None); } result.ServerVersion.Should().Be(new SemanticVersion(2, 6, 3)); result.ConnectionId.ServerValue.Should().Be(10); }
public void InitializeConnection_without_serverApi_should_send_legacy_hello_and_buildInfo([Values(false, true)] bool async) { var connection = new MockConnection(__serverId); var helloReply = RawBsonDocumentHelper.FromJson("{ ok : 1, connectionId : 1 }"); connection.EnqueueReplyMessage(MessageHelper.BuildReply(helloReply)); var buildInfoReply = RawBsonDocumentHelper.FromJson("{ ok : 1, version : \"4.2.0\" }"); connection.EnqueueReplyMessage(MessageHelper.BuildReply(buildInfoReply)); var subject = CreateSubject(); var result = InitializeConnection(subject, connection, async, CancellationToken.None); result.ConnectionId.ServerValue.Should().Be(1); SpinWait.SpinUntil(() => connection.GetSentMessages().Count >= 2, TimeSpan.FromSeconds(5)).Should().BeTrue(); var sentMessages = MessageHelper.TranslateMessagesToBsonDocuments(connection.GetSentMessages()); sentMessages.Count.Should().Be(2); var actualRequestId1 = sentMessages[1]["requestId"].AsInt32; sentMessages[0]["opcode"].AsString.Should().Be("query"); sentMessages[0]["query"][OppressiveLanguageConstants.LegacyHelloCommandName].AsInt32.Should().Be(1); sentMessages[0]["query"].AsBsonDocument.TryGetElement("apiVersion", out _).Should().BeFalse(); sentMessages[0]["query"].AsBsonDocument.TryGetElement("apiStrict", out _).Should().BeFalse(); sentMessages[0]["query"].AsBsonDocument.TryGetElement("apiDeprecationErrors", out _).Should().BeFalse(); sentMessages[1].Should().Be($"{{ opcode : \"query\", requestId : {actualRequestId1}, database : \"admin\", collection : \"$cmd\", batchSize : -1, slaveOk : true, query : {{ buildInfo : 1 }}}}"); }
public void AuthenticateAsync_should_not_throw_when_authentication_succeeds() { var randomStringGenerator = new ConstantRandomStringGenerator("fyko+d2lbbFgONRv9qkxdawL"); var subject = new ScramSha1Authenticator(__credential, randomStringGenerator); var saslStartReply = MessageHelper.BuildSuccessReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{conversationId: 1, payload: BinData(0,\"cj1meWtvK2QybGJiRmdPTlJ2OXFreGRhd0xIbytWZ2s3cXZVT0tVd3VXTElXZzRsLzlTcmFHTUhFRSxzPXJROVpZM01udEJldVAzRTFURFZDNHc9PSxpPTEwMDAw\"), done: false, ok: 1}")); var saslContinueReply = MessageHelper.BuildSuccessReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{conversationId: 1, payload: BinData(0,\"dj1VTVdlSTI1SkQxeU5ZWlJNcFo0Vkh2aFo5ZTA9\"), done: true, ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(saslStartReply); connection.EnqueueReplyMessage(saslContinueReply); var currentRequestId = RequestMessage.CurrentGlobalRequestId; Action act = () => subject.AuthenticateAsync(connection, Timeout.InfiniteTimeSpan, CancellationToken.None).Wait(); act.ShouldNotThrow(); var sentMessages = MessageHelper.TranslateMessagesToBsonDocuments(connection.GetSentMessages()); sentMessages.Count.Should().Be(2); sentMessages[0].Should().Be("{opcode: \"query\", requestId: " + (currentRequestId + 1) + ", database: \"source\", collection: \"$cmd\", batchSize: -1, slaveOk: true, query: {saslStart: 1, mechanism: \"SCRAM-SHA-1\", payload: new BinData(0, \"biwsbj11c2VyLHI9ZnlrbytkMmxiYkZnT05Sdjlxa3hkYXdM\")}}"); sentMessages[1].Should().Be("{opcode: \"query\", requestId: " + (currentRequestId + 2) + ", database: \"source\", collection: \"$cmd\", batchSize: -1, slaveOk: true, query: {saslContinue: 1, conversationId: 1, payload: new BinData(0, \"Yz1iaXdzLHI9ZnlrbytkMmxiYkZnT05Sdjlxa3hkYXdMSG8rVmdrN3F2VU9LVXd1V0xJV2c0bC85U3JhR01IRUUscD1NQzJUOEJ2Ym1XUmNrRHc4b1dsNUlWZ2h3Q1k9\")}}"); }
public void InitializeConnectionA_should_build_the_ConnectionDescription_correctly( [Values(false, true)] bool async) { var isMasterReply = MessageHelper.BuildReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1 }")); var buildInfoReply = MessageHelper.BuildReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1, version: \"2.6.3\" }")); var gleReply = MessageHelper.BuildReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1, connectionId: 10 }")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(isMasterReply); connection.EnqueueReplyMessage(buildInfoReply); connection.EnqueueReplyMessage(gleReply); ConnectionDescription result; if (async) { result = _subject.InitializeConnectionAsync(connection, CancellationToken.None).GetAwaiter().GetResult(); } else { result = _subject.InitializeConnection(connection, CancellationToken.None); } result.ServerVersion.Should().Be(new SemanticVersion(2, 6, 3)); result.ConnectionId.ServerValue.Should().Be(10); }
public void InitializeConnection_should_acquire_connectionId_from_isMaster_response([Values(false, true)] bool async) { var isMasterReply = MessageHelper.BuildReply( RawBsonDocumentHelper.FromJson("{ ok : 1, connectionId : 1 }")); var buildInfoReply = MessageHelper.BuildReply( RawBsonDocumentHelper.FromJson("{ ok : 1, version : \"4.2.0\" }")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(isMasterReply); connection.EnqueueReplyMessage(buildInfoReply); ConnectionDescription result; if (async) { result = _subject.InitializeConnectionAsync(connection, CancellationToken.None).GetAwaiter().GetResult(); } else { result = _subject.InitializeConnection(connection, CancellationToken.None); } var sentMessages = connection.GetSentMessages(); sentMessages.Should().HaveCount(2); result.ConnectionId.ServerValue.Should().Be(1); }
public void AuthenticateAsync_should_not_throw_when_authentication_succeeds() { var subject = new MongoDBCRAuthenticator(__credential); var getNonceReply = MessageHelper.BuildSuccessReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{nonce: \"2375531c32080ae8\", ok: 1}")); var authenticateReply = MessageHelper.BuildSuccessReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(getNonceReply); connection.EnqueueReplyMessage(authenticateReply); var currentRequestId = RequestMessage.CurrentGlobalRequestId; Action act = () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).Wait(); act.ShouldNotThrow(); var sentMessages = MessageHelper.TranslateMessagesToBsonDocuments(connection.GetSentMessages()); sentMessages.Count.Should().Be(2); sentMessages[0].Should().Be("{opcode: \"query\", requestId: " + (currentRequestId + 1) + ", database: \"source\", collection: \"$cmd\", batchSize: -1, slaveOk: true, query: {getnonce: 1}}"); sentMessages[1].Should().Be("{opcode: \"query\", requestId: " + (currentRequestId + 2) + ", database: \"source\", collection: \"$cmd\", batchSize: -1, slaveOk: true, query: {authenticate: 1, user: \"user\", nonce: \"2375531c32080ae8\", key: \"21742f26431831d5cfca035a08c5bdf6\"}}"); }
public void Authenticate_should_throw_when_server_provides_invalid_serverSignature( [Values(false, true)] bool async) { var randomStringGenerator = new ConstantRandomStringGenerator("fyko+d2lbbFgONRv9qkxdawL"); var subject = new ScramSha1Authenticator(__credential, randomStringGenerator, serverApi: null); var saslStartReply = MessageHelper.BuildReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{conversationId: 1, payload: BinData(0,'cj1meWtvK2QybGJiRmdPTlJ2OXFreGRhd0xIbytWZ2s3cXZVT0tVd3VXTElXZzRsLzlTcmFHTUhFRSxzPXJROVpZM01udEJldVAzRTFURFZDNHc9PSxpPTEwMDAw'), done: false, ok: 1}")); var saslContinueReply = MessageHelper.BuildReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{conversationId: 1, payload: BinData(0,'dj1VTVdlSTI1SkQxeU5ZWlJNcFo0Vkh2aFo5ZTBh'), done: true, ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(saslStartReply); connection.EnqueueReplyMessage(saslContinueReply); Action act; if (async) { act = () => subject.AuthenticateAsync(connection, __descriptionQueryWireProtocol, CancellationToken.None).GetAwaiter().GetResult(); } else { act = () => subject.Authenticate(connection, __descriptionQueryWireProtocol, CancellationToken.None); } act.ShouldThrow <MongoAuthenticationException>(); }
public void Authenticate_should_use_cache( [Values(false, true)] bool async) { var randomStringGenerator = new ConstantRandomStringGenerator("fyko+d2lbbFgONRv9qkxdawL"); var subject = new ScramSha1Authenticator(__credential, randomStringGenerator, serverApi: null); var saslStartReply = MessageHelper.BuildReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson( "{conversationId: 1, payload: BinData(0,'cj1meWtvK2QybGJiRmdPTlJ2OXFreGRhd0xIbytWZ2s3cXZVT0tVd3VXTElXZzRsLzlTcmFHTUhFRSxzPXJROVpZM01udEJldVAzRTFURFZDNHc9PSxpPTEwMDAw'), done: false, ok: 1}")); var saslContinueReply = MessageHelper.BuildReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson( "{conversationId: 1, payload: BinData(0,'dj1VTVdlSTI1SkQxeU5ZWlJNcFo0Vkh2aFo5ZTA9'), done: true, ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(saslStartReply); connection.EnqueueReplyMessage(saslContinueReply); if (async) { subject.AuthenticateAsync(connection, __descriptionQueryWireProtocol, CancellationToken.None).GetAwaiter() .GetResult(); } else { subject.Authenticate(connection, __descriptionQueryWireProtocol, CancellationToken.None); } SpinWait.SpinUntil(() => connection.GetSentMessages().Count >= 2, TimeSpan.FromSeconds(5)).Should() .BeTrue(); subject._cache().Should().NotBe(null); subject._cache()._cacheKey().Should().NotBe(null); subject._cache()._cachedEntry().Should().NotBe(null); }
public void Authenticate_should_send_serverApi_with_command_wire_protocol_if_serverApi_is_provided( [Values(false, true)] bool useServerApi, [Values(false, true)] bool async) { var serverApi = useServerApi ? new ServerApi(ServerApiVersion.V1, true, true) : null; #pragma warning disable 618 var subject = new MongoDBCRAuthenticator(__credential, serverApi); #pragma warning restore 618 var connection = new MockConnection(__serverId); var getNonceReply = RawBsonDocumentHelper.FromJson("{nonce: \"2375531c32080ae8\", ok: 1}"); var authenticateReply = RawBsonDocumentHelper.FromJson("{ok: 1}"); if (useServerApi) { connection.EnqueueCommandResponseMessage(MessageHelper.BuildCommandResponse(getNonceReply)); connection.EnqueueCommandResponseMessage(MessageHelper.BuildCommandResponse(authenticateReply)); } else { connection.EnqueueReplyMessage(MessageHelper.BuildReply(getNonceReply)); connection.EnqueueReplyMessage(MessageHelper.BuildReply(authenticateReply)); } connection.Description = __descriptionQueryWireProtocol; var expectedRequestId = RequestMessage.CurrentGlobalRequestId + 1; if (async) { subject.AuthenticateAsync(connection, __descriptionQueryWireProtocol, CancellationToken.None).GetAwaiter().GetResult(); } else { subject.Authenticate(connection, __descriptionQueryWireProtocol, CancellationToken.None); } SpinWait.SpinUntil(() => connection.GetSentMessages().Count >= 2, TimeSpan.FromSeconds(5)).Should().BeTrue(); var sentMessages = MessageHelper.TranslateMessagesToBsonDocuments(connection.GetSentMessages()); sentMessages.Count.Should().Be(2); var actualRequestId0 = sentMessages[0]["requestId"].AsInt32; var actualRequestId1 = sentMessages[1]["requestId"].AsInt32; actualRequestId0.Should().BeInRange(expectedRequestId, expectedRequestId + 10); actualRequestId1.Should().BeInRange(actualRequestId0 + 1, actualRequestId0 + 11); if (useServerApi) { sentMessages[0].Should().Be($"{{opcode : \"opmsg\", requestId : {actualRequestId0}, responseTo : 0, sections : [{{ \"payloadType\" : 0, \"document\" : {{ \"getnonce\" : 1, \"$db\" : \"source\", \"apiVersion\" : \"1\", \"apiStrict\" : true, \"apiDeprecationErrors\" : true }} }}]}}"); sentMessages[1].Should().Be($"{{opcode : \"opmsg\", requestId : {actualRequestId1}, responseTo : 0, sections : [{{ \"payloadType\" : 0, \"document\" : {{ \"authenticate\" : 1, \"user\" : \"user\", \"nonce\" : \"2375531c32080ae8\", \"key\" : \"21742f26431831d5cfca035a08c5bdf6\", \"$db\" : \"source\", \"apiVersion\" : \"1\", \"apiStrict\" : true, \"apiDeprecationErrors\" : true }} }}]}}"); } else { sentMessages[0].Should().Be($"{{ opcode : \"query\", requestId : {actualRequestId0}, database : \"source\", collection : \"$cmd\", batchSize : -1, slaveOk : true, query : {{ getnonce : 1 }} }}"); sentMessages[1].Should().Be($"{{ opcode : \"query\", requestId : {actualRequestId1}, database : \"source\", collection : \"$cmd\", batchSize : -1, slaveOk : true, query : {{ authenticate : 1, user : \"user\", nonce : \"2375531c32080ae8\", key : \"21742f26431831d5cfca035a08c5bdf6\" }} }}"); } }
private void SetupHeartbeatConnection() { var isMasterReply = MessageHelper.BuildSuccessReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1 }")); var buildInfoReply = MessageHelper.BuildSuccessReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1, version: \"2.6.3\" }")); _heartbeatConnection.EnqueueReplyMessage(isMasterReply); _heartbeatConnection.EnqueueReplyMessage(buildInfoReply); }
public void InitializeConnection_should_send_serverApi_in_isMaster_and_buildInfo( [Values(false, true)] bool useServerApi, [Values(false, true)] bool async) { var serverApi = useServerApi ? new ServerApi(ServerApiVersion.V1, true, true) : null; var isMasterReply = MessageHelper.BuildReply(RawBsonDocumentHelper.FromJson("{ ok : 1, connectionId : 1 }")); var buildInfoReply = MessageHelper.BuildReply(RawBsonDocumentHelper.FromJson("{ ok : 1, version : \"4.2.0\" }")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(isMasterReply); connection.EnqueueReplyMessage(buildInfoReply); var subject = new ConnectionInitializer("test", new[] { new CompressorConfiguration(CompressorType.Zlib) }, serverApi); ConnectionDescription result; if (async) { result = subject.InitializeConnectionAsync(connection, CancellationToken.None).GetAwaiter().GetResult(); } else { result = subject.InitializeConnection(connection, CancellationToken.None); } result.ConnectionId.ServerValue.Should().Be(1); SpinWait.SpinUntil(() => connection.GetSentMessages().Count >= 2, TimeSpan.FromSeconds(5)).Should().BeTrue(); var sentMessages = MessageHelper.TranslateMessagesToBsonDocuments(connection.GetSentMessages()); sentMessages.Count.Should().Be(2); var actualRequestId1 = sentMessages[1]["requestId"].AsInt32; sentMessages[0]["opcode"].AsString.Should().Be("query"); sentMessages[0]["query"]["isMaster"].AsInt32.Should().Be(1); if (useServerApi) { sentMessages[0]["query"]["apiVersion"].AsString.Should().Be("1"); sentMessages[0]["query"]["apiStrict"].AsBoolean.Should().Be(true); sentMessages[0]["query"]["apiDeprecationErrors"].AsBoolean.Should().Be(true); } else { sentMessages[0]["query"].AsBsonDocument.TryGetElement("apiVersion", out _).Should().BeFalse(); sentMessages[0]["query"].AsBsonDocument.TryGetElement("apiStrict", out _).Should().BeFalse(); sentMessages[0]["query"].AsBsonDocument.TryGetElement("apiDeprecationErrors", out _).Should().BeFalse(); } var expectedServerApiBuildInfoString = useServerApi ? ", apiVersion : \"1\", apiStrict : false, apiDeprecationErrors : true" : ""; sentMessages[1].Should().Be($"{{ opcode : \"query\", requestId : {actualRequestId1}, database : \"admin\", collection : \"$cmd\", batchSize : -1, slaveOk : true, query : {{ buildInfo : 1{expectedServerApiBuildInfoString} }}}}"); }
public void Authenticate_should_send_serverApi_with_command_wire_protocol_if_serverApi_is_provided( [Values(false, true)] bool useServerApi, [Values(false, true)] bool async) { var serverApi = useServerApi ? new ServerApi(ServerApiVersion.V1, true, true) : null; var randomStringGenerator = new ConstantRandomStringGenerator(_clientNonce); var subject = new ScramSha256Authenticator(__credential, randomStringGenerator, serverApi); var connection = new MockConnection(__serverId); var saslStartReply = RawBsonDocumentHelper.FromJson($"{{ conversationId : 1, payload : BinData(0,'{ToUtf8Base64(__serverResponse1)}'), done : false, ok : 1 }}"); var saslContinueReply = RawBsonDocumentHelper.FromJson($"{{ conversationId : 1, payload : BinData(0,'{ToUtf8Base64(__serverResponse2)}'), done : true, ok : 1}}"); if (useServerApi) { connection.EnqueueCommandResponseMessage(MessageHelper.BuildCommandResponse(saslStartReply)); connection.EnqueueCommandResponseMessage(MessageHelper.BuildCommandResponse(saslContinueReply)); } else { connection.EnqueueReplyMessage(MessageHelper.BuildReply(saslStartReply)); connection.EnqueueReplyMessage(MessageHelper.BuildReply(saslContinueReply)); } connection.Description = __descriptionQueryWireProtocol; if (async) { subject.AuthenticateAsync(connection, __descriptionQueryWireProtocol, CancellationToken.None).GetAwaiter().GetResult(); } else { subject.Authenticate(connection, __descriptionQueryWireProtocol, CancellationToken.None); } SpinWait.SpinUntil(() => connection.GetSentMessages().Count >= 2, TimeSpan.FromSeconds(5)).Should().BeTrue(); var sentMessages = MessageHelper.TranslateMessagesToBsonDocuments(connection.GetSentMessages()); sentMessages.Count.Should().Be(2); var actualRequestId0 = sentMessages[0]["requestId"].AsInt32; var actualRequestId1 = sentMessages[1]["requestId"].AsInt32; if (useServerApi) { sentMessages[0].Should().Be($"{{opcode : \"opmsg\", requestId : {actualRequestId0}, responseTo : 0, sections : [{{ payloadType : 0, document : {{ saslStart : 1, mechanism : \"SCRAM-SHA-256\", payload : new BinData(0, \"biwsbj11c2VyLHI9ck9wck5HZndFYmVSV2diTkVrcU8=\"), options : {{ skipEmptyExchange : true }}, \"$db\" : \"source\", apiVersion : \"1\", apiStrict : true, apiDeprecationErrors : true }} }}]}}"); sentMessages[1].Should().Be($"{{opcode : \"opmsg\", requestId : {actualRequestId1}, responseTo : 0, sections : [{{ payloadType : 0, document : {{ saslContinue : 1, conversationId : 1, payload : new BinData(0, \"Yz1iaXdzLHI9ck9wck5HZndFYmVSV2diTkVrcU8laHZZRHBXVWEyUmFUQ0FmdXhGSWxqKWhObEYkazAscD1kSHpiWmFwV0lrNGpVaE4rVXRlOXl0YWc5empmTUhnc3FtbWl6N0FuZFZRPQ==\"), \"$db\" : \"source\", apiVersion : \"1\", apiStrict : true, apiDeprecationErrors : true }} }}]}}"); } else { sentMessages[0].Should().Be($"{{ opcode : \"query\", requestId : {actualRequestId0}, database : \"source\", collection : \"$cmd\", batchSize : -1, slaveOk : true, query : {{ saslStart : 1, mechanism : \"SCRAM-SHA-256\", payload : new BinData(0, \"{ToUtf8Base64(__clientRequest1)}\"), options : {{ \"skipEmptyExchange\" : true }} }} }}"); sentMessages[1].Should().Be($"{{ opcode : \"query\", requestId : {actualRequestId1}, database : \"source\", collection : \"$cmd\", batchSize : -1, slaveOk : true, query : {{ saslContinue : 1, conversationId : 1, payload : new BinData(0, \"{ToUtf8Base64(__clientRequest2)}\") }} }}"); } }
public void Authenticate_should_send_serverApi_with_command_wire_protocol_if_serverApi_is_provided( [Values(false, true)] bool useServerApi, [Values(false, true)] bool async) { var serverApi = useServerApi ? new ServerApi(ServerApiVersion.V1, true, true) : null; var randomStringGenerator = new ConstantRandomStringGenerator("fyko+d2lbbFgONRv9qkxdawL"); var subject = new ScramSha1Authenticator(__credential, randomStringGenerator, serverApi); var connection = new MockConnection(__serverId); var saslStartReply = RawBsonDocumentHelper.FromJson("{ conversationId : 1, payload : BinData(0,'cj1meWtvK2QybGJiRmdPTlJ2OXFreGRhd0xIbytWZ2s3cXZVT0tVd3VXTElXZzRsLzlTcmFHTUhFRSxzPXJROVpZM01udEJldVAzRTFURFZDNHc9PSxpPTEwMDAw'), done : false, ok : 1 }"); var saslContinueReply = RawBsonDocumentHelper.FromJson("{ conversationId : 1, payload : BinData(0,'dj1VTVdlSTI1SkQxeU5ZWlJNcFo0Vkh2aFo5ZTA9'), done : true, ok : 1}"); if (useServerApi) { connection.EnqueueCommandResponseMessage(MessageHelper.BuildCommandResponse(saslStartReply)); connection.EnqueueCommandResponseMessage(MessageHelper.BuildCommandResponse(saslContinueReply)); } else { connection.EnqueueReplyMessage(MessageHelper.BuildReply(saslStartReply)); connection.EnqueueReplyMessage(MessageHelper.BuildReply(saslContinueReply)); } connection.Description = __descriptionQueryWireProtocol; if (async) { subject.AuthenticateAsync(connection, __descriptionQueryWireProtocol, CancellationToken.None).GetAwaiter().GetResult(); } else { subject.Authenticate(connection, __descriptionQueryWireProtocol, CancellationToken.None); } SpinWait.SpinUntil(() => connection.GetSentMessages().Count >= 2, TimeSpan.FromSeconds(5)).Should().BeTrue(); var sentMessages = MessageHelper.TranslateMessagesToBsonDocuments(connection.GetSentMessages()); sentMessages.Count.Should().Be(2); var actualRequestId0 = sentMessages[0]["requestId"].AsInt32; var actualRequestId1 = sentMessages[1]["requestId"].AsInt32; if (useServerApi) { sentMessages[0].Should().Be($"{{opcode : \"opmsg\", requestId : {actualRequestId0}, responseTo : 0, sections : [{{ payloadType : 0, document : {{ saslStart : 1, mechanism : \"SCRAM-SHA-1\", payload : new BinData(0, \"biwsbj11c2VyLHI9ZnlrbytkMmxiYkZnT05Sdjlxa3hkYXdM\"), options : {{ skipEmptyExchange : true }}, \"$db\" : \"source\", apiVersion : \"1\", apiStrict : true, apiDeprecationErrors : true }} }}]}}"); sentMessages[1].Should().Be($"{{opcode : \"opmsg\", requestId : {actualRequestId1}, responseTo : 0, sections : [{{ payloadType : 0, document : {{ saslContinue : 1, conversationId : 1, payload : new BinData(0, \"Yz1iaXdzLHI9ZnlrbytkMmxiYkZnT05Sdjlxa3hkYXdMSG8rVmdrN3F2VU9LVXd1V0xJV2c0bC85U3JhR01IRUUscD1NQzJUOEJ2Ym1XUmNrRHc4b1dsNUlWZ2h3Q1k9\"), \"$db\" : \"source\", apiVersion : \"1\", apiStrict : true, apiDeprecationErrors : true }} }}]}}"); } else { sentMessages[0].Should().Be($"{{ opcode : \"query\", requestId : {actualRequestId0}, database : \"source\", collection : \"$cmd\", batchSize : -1, slaveOk : true, query : {{ saslStart : 1, mechanism : \"SCRAM-SHA-1\", payload : new BinData(0, \"biwsbj11c2VyLHI9ZnlrbytkMmxiYkZnT05Sdjlxa3hkYXdM\"), options : {{ \"skipEmptyExchange\" : true }} }} }}"); sentMessages[1].Should().Be($"{{ opcode : \"query\", requestId : {actualRequestId1}, database : \"source\", collection : \"$cmd\", batchSize : -1, slaveOk : true, query : {{ saslContinue : 1, conversationId : 1, payload : new BinData(0, \"Yz1iaXdzLHI9ZnlrbytkMmxiYkZnT05Sdjlxa3hkYXdMSG8rVmdrN3F2VU9LVXd1V0xJV2c0bC85U3JhR01IRUUscD1NQzJUOEJ2Ym1XUmNrRHc4b1dsNUlWZ2h3Q1k9\") }} }}"); } }
public void InitializeConnectionA_should_build_the_ConnectionDescription_correctly( [Values("noop", "zlib", "snappy", "zstd")] string compressorType, [Values(false, true)] bool async) { var isMasterReply = MessageHelper.BuildReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson($"{{ ok: 1, compression: ['{compressorType}'] }}")); var buildInfoReply = MessageHelper.BuildReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1, version: \"2.6.3\" }")); var gleReply = MessageHelper.BuildReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1, connectionId: 10 }")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(isMasterReply); connection.EnqueueReplyMessage(buildInfoReply); connection.EnqueueReplyMessage(gleReply); ConnectionDescription result; if (async) { result = _subject.InitializeConnectionAsync(connection, CancellationToken.None).GetAwaiter().GetResult(); } else { result = _subject.InitializeConnection(connection, CancellationToken.None); } result.ServerVersion.Should().Be(new SemanticVersion(2, 6, 3)); result.ConnectionId.ServerValue.Should().Be(10); result.AvailableCompressors.Count.Should().Be(1); result.AvailableCompressors.Should().Contain(ToCompressorTypeEnum(compressorType)); CompressorType ToCompressorTypeEnum(string ct) { switch (ct) { case "noop": return(CompressorType.Noop); case "zlib": return(CompressorType.Zlib); case "snappy": return(CompressorType.Snappy); case "zstd": return(CompressorType.ZStandard); default: throw new InvalidOperationException($"Unexpected compression {compressorType}."); } } }
public void InitializeConnection_should_call_Authenticator_CustomizeInitialIsMasterCommand( [Values("default", "SCRAM-SHA-256", "SCRAM-SHA-1")] string authenticatorType, [Values(false, true)] bool async) { var isMasterReply = MessageHelper.BuildReply( RawBsonDocumentHelper.FromJson("{ ok : 1, connectionId : 1 }")); var buildInfoReply = MessageHelper.BuildReply( RawBsonDocumentHelper.FromJson("{ ok : 1, version : \"4.2.0\" }")); var credentials = new UsernamePasswordCredential( source: "Voyager", username: "******", password: "******"); var authenticator = CreateAuthenticator(authenticatorType, credentials); var connectionSettings = new ConnectionSettings(new[] { new AuthenticatorFactory(() => authenticator) }); var connection = new MockConnection(__serverId, connectionSettings, eventSubscriber: null); connection.EnqueueReplyMessage(isMasterReply); connection.EnqueueReplyMessage(buildInfoReply); // We expect authentication to fail since we have not enqueued the expected authentication replies try { if (async) { _subject.InitializeConnectionAsync(connection, CancellationToken.None).GetAwaiter().GetResult(); } else { _subject.InitializeConnection(connection, CancellationToken.None); } } catch (InvalidOperationException ex) { ex.Message.Should().Be("Queue empty."); } var sentMessages = connection.GetSentMessages(); var isMasterQuery = (QueryMessage)sentMessages[0]; var isMasterDocument = isMasterQuery.Query; isMasterDocument.Should().Contain("speculativeAuthenticate"); var speculativeAuthenticateDocument = isMasterDocument["speculativeAuthenticate"].AsBsonDocument; speculativeAuthenticateDocument.Should().Contain("mechanism"); var expectedMechanism = new BsonString( authenticatorType == "default" ? "SCRAM-SHA-256" : authenticatorType); speculativeAuthenticateDocument["mechanism"].Should().Be(expectedMechanism); speculativeAuthenticateDocument["db"].Should().Be(new BsonString(credentials.Source)); }
public void Authenticate_should_throw_an_AuthenticationException_when_authentication_fails( [Values(false, true)] bool async) { var subject = new MongoDBX509Authenticator("CN=client,OU=kerneluser,O=10Gen,L=New York City,ST=New York,C=US", serverApi: null); var reply = MessageHelper.BuildNoDocumentsReturnedReply <RawBsonDocument>(); var connection = new MockConnection(__serverId); connection.Description = CreateConnectionDescription(new SemanticVersion(3, 2, 0)); connection.EnqueueReplyMessage(reply); Action act; if (async) { act = () => subject.AuthenticateAsync(connection, __descriptionQueryWireProtocol, CancellationToken.None).GetAwaiter().GetResult(); } else { act = () => subject.Authenticate(connection, __descriptionQueryWireProtocol, CancellationToken.None); } act.ShouldThrow <MongoAuthenticationException>(); }
public void Authenticate_should_throw_when_server_provides_invalid_r_value( [Values(false, true)] bool async) { var randomStringGenerator = new ConstantRandomStringGenerator(_clientNonce); var subject = new ScramSha256Authenticator(__credential, randomStringGenerator); var poisonedSaslStart = PoisonSaslMessage(message: __clientRequest1, poison: "bluePill"); var poisonedSaslStartReply = CreateSaslStartReply(poisonedSaslStart, _serverNonce, _serverSalt, _iterationCount); var poisonedSaslStartReplyMessage = MessageHelper.BuildReply(RawBsonDocumentHelper.FromJson( @"{conversationId: 1, " + $" payload: BinData(0,\"{ToUtf8Base64(poisonedSaslStartReply)}\")," + @" done: false, ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(poisonedSaslStartReplyMessage); var act = async ? () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).GetAwaiter().GetResult() : (Action)(() => subject.Authenticate(connection, __description, CancellationToken.None)); var exception = Record.Exception(act); exception.Should().BeOfType <MongoAuthenticationException>(); }
public void Authenticate_should_not_throw_when_authentication_succeeds( [Values(false, true)] bool async) { var subject = new PlainAuthenticator(__credential); var saslStartReply = MessageHelper.BuildReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{conversationId: 0, payload: BinData(0,\"\"), done: true, ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(saslStartReply); var currentRequestId = RequestMessage.CurrentGlobalRequestId; Action act; if (async) { act = () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).GetAwaiter().GetResult(); } else { act = () => subject.Authenticate(connection, __description, CancellationToken.None); } act.ShouldNotThrow(); var sentMessages = MessageHelper.TranslateMessagesToBsonDocuments(connection.GetSentMessages()); sentMessages.Count.Should().Be(1); sentMessages[0].Should().Be("{opcode: \"query\", requestId: " + (currentRequestId + 1) + ", database: \"source\", collection: \"$cmd\", batchSize: -1, slaveOk: true, query: {saslStart: 1, mechanism: \"PLAIN\", payload: new BinData(0, \"AHVzZXIAcGVuY2ls\")}}"); }
public void InitializeConnection_without_serverApi_should_send_legacy_hello([Values(false, true)] bool async) { var connection = new MockConnection(__serverId); var helloReply = RawBsonDocumentHelper.FromJson($"{{ ok : 1, connectionId : 1, maxWireVersion : {WireVersion.Server42} }}"); connection.EnqueueReplyMessage(MessageHelper.BuildReply(helloReply)); var subject = CreateSubject(); var result = InitializeConnection(subject, connection, async, CancellationToken.None); result.ConnectionId.ServerValue.Should().Be(1); SpinWait.SpinUntil(() => connection.GetSentMessages().Count >= 1, TimeSpan.FromSeconds(5)).Should().BeTrue(); var sentMessages = MessageHelper.TranslateMessagesToBsonDocuments(connection.GetSentMessages()); sentMessages.Count.Should().Be(1); sentMessages[0]["opcode"].AsString.Should().Be("query"); sentMessages[0]["query"][OppressiveLanguageConstants.LegacyHelloCommandName].AsInt32.Should().Be(1); sentMessages[0]["query"].AsBsonDocument.TryGetElement("apiVersion", out _).Should().BeFalse(); sentMessages[0]["query"].AsBsonDocument.TryGetElement("apiStrict", out _).Should().BeFalse(); sentMessages[0]["query"].AsBsonDocument.TryGetElement("apiDeprecationErrors", out _).Should().BeFalse(); }
public void Authenticate_should_not_throw_when_authentication_succeeds( [Values(false, true)] bool async) { var subject = new MongoDBX509Authenticator("CN=client,OU=kerneluser,O=10Gen,L=New York City,ST=New York,C=US"); var reply = MessageHelper.BuildReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ok: 1}")); var connection = new MockConnection(__serverId); connection.Description = CreateConnectionDescription(new SemanticVersion(3, 2, 0)); connection.EnqueueReplyMessage(reply); Action act; if (async) { act = () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).GetAwaiter().GetResult(); } else { act = () => subject.Authenticate(connection, __description, CancellationToken.None); } act.ShouldNotThrow(); }
public void Authenticate_should_not_throw_when_authentication_succeeds( [Values(false, true)] bool async) { var subject = new PlainAuthenticator(__credential); var saslStartReply = MessageHelper.BuildReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{conversationId: 0, payload: BinData(0,\"\"), done: true, ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(saslStartReply); var expectedRequestId = RequestMessage.CurrentGlobalRequestId + 1; Action act; if (async) { act = () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).GetAwaiter().GetResult(); } else { act = () => subject.Authenticate(connection, __description, CancellationToken.None); } act.ShouldNotThrow(); SpinWait.SpinUntil(() => connection.GetSentMessages().Count >= 1, 100).Should().BeTrue(); var sentMessages = MessageHelper.TranslateMessagesToBsonDocuments(connection.GetSentMessages()); sentMessages.Count.Should().Be(1); var actualRequestId = sentMessages[0]["requestId"].AsInt32; actualRequestId.Should().BeInRange(expectedRequestId, expectedRequestId + 10); sentMessages[0].Should().Be("{opcode: \"query\", requestId: " + actualRequestId + ", database: \"source\", collection: \"$cmd\", batchSize: -1, slaveOk: true, query: {saslStart: 1, mechanism: \"PLAIN\", payload: new BinData(0, \"AHVzZXIAcGVuY2ls\")}}"); }
public void Authenticate_should_not_throw_when_username_is_null_and_server_support_null_username( [Values(false, true)] bool async) { var subject = new MongoDBX509Authenticator(null); var reply = MessageHelper.BuildReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(reply); var description = CreateConnectionDescription(new SemanticVersion(3, 4, 0)); Exception exception; if (async) { exception = Record.Exception(() => subject.AuthenticateAsync(connection, description, CancellationToken.None).GetAwaiter().GetResult()); } else { exception = Record.Exception(() => subject.Authenticate(connection, description, CancellationToken.None)); } exception.Should().BeNull(); }
public void Authenticate_should_not_throw_when_authentication_succeeds( [Values(false, true)] bool async) { var subject = new MongoDBCRAuthenticator(__credential); var getNonceReply = MessageHelper.BuildReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{nonce: \"2375531c32080ae8\", ok: 1}")); var authenticateReply = MessageHelper.BuildReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(getNonceReply); connection.EnqueueReplyMessage(authenticateReply); var expectedRequestId = RequestMessage.CurrentGlobalRequestId + 1; Action act; if (async) { act = () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).GetAwaiter().GetResult(); } else { act = () => subject.Authenticate(connection, __description, CancellationToken.None); } act.ShouldNotThrow(); SpinWait.SpinUntil(() => connection.GetSentMessages().Count >= 2, TimeSpan.FromSeconds(5)).Should().BeTrue(); var sentMessages = MessageHelper.TranslateMessagesToBsonDocuments(connection.GetSentMessages()); sentMessages.Count.Should().Be(2); var actualRequestId0 = sentMessages[0]["requestId"].AsInt32; var actualRequestId1 = sentMessages[1]["requestId"].AsInt32; actualRequestId0.Should().BeInRange(expectedRequestId, expectedRequestId + 10); actualRequestId1.Should().BeInRange(actualRequestId0 + 1, actualRequestId0 + 11); sentMessages[0].Should().Be("{opcode: \"query\", requestId: " + actualRequestId0 + ", database: \"source\", collection: \"$cmd\", batchSize: -1, slaveOk: true, query: {getnonce: 1}}"); sentMessages[1].Should().Be("{opcode: \"query\", requestId: " + actualRequestId1 + ", database: \"source\", collection: \"$cmd\", batchSize: -1, slaveOk: true, query: {authenticate: 1, user: \"user\", nonce: \"2375531c32080ae8\", key: \"21742f26431831d5cfca035a08c5bdf6\"}}"); }
public void Authenticate_should_throw_when_server_provides_unexpected_field( [Values(false, true)] bool async) { var clientNonce = __randomByteGenerator.Generate(ClientNonceLength); var serverNonce = Combine(clientNonce, __randomByteGenerator.Generate(ClientNonceLength)); var host = "sts.amazonaws.com"; var credential = new UsernamePasswordCredential("$external", "permanentuser", "FAKEFAKEFAKEFAKEFAKEfakefakefakefakefake"); var mockRandomByteGenerator = new Mock <IRandomByteGenerator>(); mockRandomByteGenerator.Setup(x => x.Generate(It.IsAny <int>())).Returns(clientNonce); var serverFirstMessage = new BsonDocument { { "s", serverNonce }, { "h", host }, { "u", "unexpected" } }; var saslStartReply = MessageHelper.BuildReply <RawBsonDocument>(RawBsonDocumentHelper.FromJson( $"{{ conversationId : 1, done : false, payload : BinData(0,\"{ToBase64(serverFirstMessage.ToBson())}\"), ok : 1 }}")); var saslContinueReply = MessageHelper.BuildReply <RawBsonDocument>(RawBsonDocumentHelper.FromJson( "{ conversationId : 1, done : true, payload : BinData(0,\"\"), ok : 1}")); var subject = new MongoAWSAuthenticator(credential, null, mockRandomByteGenerator.Object, SystemClock.Instance, serverApi: null); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(saslStartReply); connection.EnqueueReplyMessage(saslContinueReply); Exception exception; if (async) { exception = Record.Exception(() => subject.AuthenticateAsync(connection, __descriptionQueryWireProtocol, CancellationToken.None).GetAwaiter().GetResult()); } else { exception = Record.Exception(() => subject.Authenticate(connection, __descriptionQueryWireProtocol, CancellationToken.None)); } exception.Should().BeOfType <MongoAuthenticationException>(); exception.Message.Should().Be("Server returned unexpected fields: u."); }
public void Authenticate_should_work_regardless_of_culture( [Values("da-DK", "en-US")] string name, [Values(false, true)] bool async) { SetCultureAndResetAfterTest(name, () => { var randomStringGenerator = new ConstantRandomStringGenerator("a"); // ScramSha1Authenticator will have exactly the same code paths var subject = new ScramSha256Authenticator(__credential, randomStringGenerator); var mockConnection = new MockConnection(); var payload1 = $"r=aa,s={_serverSalt},i=1"; var serverResponse1 = $"{{ ok : 1, payload : BinData(0,\"{ToUtf8Base64(payload1)}\"), done : true, conversationId : 1 }}"; var serverResponseRawDocument1 = RawBsonDocumentHelper.FromJson(serverResponse1); var serverResponseMessage1 = MessageHelper.BuildReply(serverResponseRawDocument1); var payload2 = $"v=v1wZS02d7kZVSzuKoB7TuI+jIpSsKvnQUkU9Oqj2t+w="; var serverResponse2 = $"{{ ok : 1, payload : BinData(0,\"{ToUtf8Base64(payload2)}\"), done : true }}"; var serverResponseRawDocument2 = RawBsonDocumentHelper.FromJson(serverResponse2); var serverResponseMessage2 = MessageHelper.BuildReply(serverResponseRawDocument2); mockConnection.EnqueueReplyMessage(serverResponseMessage1); mockConnection.EnqueueReplyMessage(serverResponseMessage2); Authenticate(subject, mockConnection, async); }); void SetCultureAndResetAfterTest(string cultureName, Action test) { var originalCulture = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureName); try { test(); } finally { Thread.CurrentThread.CurrentCulture = originalCulture; } } }
public void InitializeConnectionAsync_should_build_the_ConnectionDescription_correctly() { var isMasterReply = MessageHelper.BuildSuccessReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1 }")); var buildInfoReply = MessageHelper.BuildSuccessReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1, version: \"2.6.3\" }")); var gleReply = MessageHelper.BuildSuccessReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1, connectionId: 10 }")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(isMasterReply); connection.EnqueueReplyMessage(buildInfoReply); connection.EnqueueReplyMessage(gleReply); var result = _subject.InitializeConnectionAsync(connection, __connectionId, Timeout.InfiniteTimeSpan, CancellationToken.None).Result; result.ServerVersion.Should().Be(new SemanticVersion(2, 6, 3)); result.ConnectionId.ServerValue.Should().Be(10); }
public void Authenticate_should_not_throw_when_authentication_succeeds( [Values(false, true)] bool async) { var randomStringGenerator = new ConstantRandomStringGenerator("fyko+d2lbbFgONRv9qkxdawL"); var subject = new ScramSha1Authenticator(__credential, randomStringGenerator); var saslStartReply = MessageHelper.BuildReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{conversationId: 1, payload: BinData(0,\"cj1meWtvK2QybGJiRmdPTlJ2OXFreGRhd0xIbytWZ2s3cXZVT0tVd3VXTElXZzRsLzlTcmFHTUhFRSxzPXJROVpZM01udEJldVAzRTFURFZDNHc9PSxpPTEwMDAw\"), done: false, ok: 1}")); var saslContinueReply = MessageHelper.BuildReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{conversationId: 1, payload: BinData(0,\"dj1VTVdlSTI1SkQxeU5ZWlJNcFo0Vkh2aFo5ZTA9\"), done: true, ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(saslStartReply); connection.EnqueueReplyMessage(saslContinueReply); var expectedRequestId = RequestMessage.CurrentGlobalRequestId + 1; Action act; if (async) { act = () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).GetAwaiter().GetResult(); } else { act = () => subject.Authenticate(connection, __description, CancellationToken.None); } act.ShouldNotThrow(); SpinWait.SpinUntil(() => connection.GetSentMessages().Count >= 2, 100).Should().BeTrue(); var sentMessages = MessageHelper.TranslateMessagesToBsonDocuments(connection.GetSentMessages()); sentMessages.Count.Should().Be(2); var actualRequestId0 = sentMessages[0]["requestId"].AsInt32; var actualRequestId1 = sentMessages[1]["requestId"].AsInt32; actualRequestId0.Should().BeInRange(expectedRequestId, expectedRequestId + 10); actualRequestId1.Should().BeInRange(actualRequestId0 + 1, actualRequestId0 + 11); sentMessages[0].Should().Be("{opcode: \"query\", requestId: " + actualRequestId0 + ", database: \"source\", collection: \"$cmd\", batchSize: -1, slaveOk: true, query: {saslStart: 1, mechanism: \"SCRAM-SHA-1\", payload: new BinData(0, \"biwsbj11c2VyLHI9ZnlrbytkMmxiYkZnT05Sdjlxa3hkYXdM\")}}"); sentMessages[1].Should().Be("{opcode: \"query\", requestId: " + actualRequestId1 + ", database: \"source\", collection: \"$cmd\", batchSize: -1, slaveOk: true, query: {saslContinue: 1, conversationId: 1, payload: new BinData(0, \"Yz1iaXdzLHI9ZnlrbytkMmxiYkZnT05Sdjlxa3hkYXdMSG8rVmdrN3F2VU9LVXd1V0xJV2c0bC85U3JhR01IRUUscD1NQzJUOEJ2Ym1XUmNrRHc4b1dsNUlWZ2h3Q1k9\")}}"); }
public void InitializeConnection_should_acquire_connectionId_from_legacy_hello_response([Values(false, true)] bool async) { var legacyHelloReply = MessageHelper.BuildReply( RawBsonDocumentHelper.FromJson("{ ok : 1, connectionId : 1 }")); var buildInfoReply = MessageHelper.BuildReply( RawBsonDocumentHelper.FromJson("{ ok : 1, version : \"4.2.0\" }")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(legacyHelloReply); connection.EnqueueReplyMessage(buildInfoReply); var subject = CreateSubject(); var result = InitializeConnection(subject, connection, async, CancellationToken.None); var sentMessages = connection.GetSentMessages(); sentMessages.Should().HaveCount(2); result.ConnectionId.ServerValue.Should().Be(1); }
public void AuthenticateAsync_should_throw_when_server_provides_invalid_serverSignature() { var randomStringGenerator = new ConstantRandomStringGenerator("fyko+d2lbbFgONRv9qkxdawL"); var subject = new ScramSha1Authenticator(__credential, randomStringGenerator); var saslStartReply = MessageHelper.BuildSuccessReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{conversationId: 1, payload: BinData(0,\"cj1meWtvK2QybGJiRmdPTlJ2OXFreGRhd0xIbytWZ2s3cXZVT0tVd3VXTElXZzRsLzlTcmFHTUhFRSxzPXJROVpZM01udEJldVAzRTFURFZDNHc9PSxpPTEwMDAw\"), done: false, ok: 1}")); var saslContinueReply = MessageHelper.BuildSuccessReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{conversationId: 1, payload: BinData(0,\"dj1VTVdlSTI1SkQxeU5ZWlJNcFo0Vkh2aFo5ZTBh\"), done: true, ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(saslStartReply); connection.EnqueueReplyMessage(saslContinueReply); var currentRequestId = RequestMessage.CurrentGlobalRequestId; Action act = () => subject.AuthenticateAsync(connection, Timeout.InfiniteTimeSpan, CancellationToken.None).Wait(); act.ShouldThrow <MongoAuthenticationException>(); }
public void InitializeConnectionAsync_should_build_the_ConnectionDescription_correctly() { var isMasterReply = MessageHelper.BuildSuccessReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1 }")); var buildInfoReply = MessageHelper.BuildSuccessReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1, version: \"2.6.3\" }")); var gleReply = MessageHelper.BuildSuccessReply <RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1, connectionId: 10 }")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(isMasterReply); connection.EnqueueReplyMessage(buildInfoReply); connection.EnqueueReplyMessage(gleReply); var result = _subject.InitializeConnectionAsync(connection, __connectionId, Timeout.InfiniteTimeSpan, CancellationToken.None).Result; result.ServerVersion.Should().Be(new SemanticVersion(2, 6, 3)); result.ConnectionId.ServerValue.Should().Be(10); }
public void Authenticate_should_not_throw_when_authentication_succeeds( [Values(false, true)] bool async) { var subject = new MongoDBCRAuthenticator(__credential); var getNonceReply = MessageHelper.BuildReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{nonce: \"2375531c32080ae8\", ok: 1}")); var authenticateReply = MessageHelper.BuildReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(getNonceReply); connection.EnqueueReplyMessage(authenticateReply); var expectedRequestId = RequestMessage.CurrentGlobalRequestId + 1; Action act; if (async) { act = () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).GetAwaiter().GetResult(); } else { act = () => subject.Authenticate(connection, __description, CancellationToken.None); } act.ShouldNotThrow(); SpinWait.SpinUntil(() => connection.GetSentMessages().Count >= 2, 100).Should().BeTrue(); var sentMessages = MessageHelper.TranslateMessagesToBsonDocuments(connection.GetSentMessages()); sentMessages.Count.Should().Be(2); var actualRequestId0 = sentMessages[0]["requestId"].AsInt32; var actualRequestId1 = sentMessages[1]["requestId"].AsInt32; actualRequestId0.Should().BeInRange(expectedRequestId, expectedRequestId + 10); actualRequestId1.Should().BeInRange(actualRequestId0 + 1, actualRequestId0 + 11); sentMessages[0].Should().Be("{opcode: \"query\", requestId: " + actualRequestId0 + ", database: \"source\", collection: \"$cmd\", batchSize: -1, slaveOk: true, query: {getnonce: 1}}"); sentMessages[1].Should().Be("{opcode: \"query\", requestId: " + actualRequestId1 + ", database: \"source\", collection: \"$cmd\", batchSize: -1, slaveOk: true, query: {authenticate: 1, user: \"user\", nonce: \"2375531c32080ae8\", key: \"21742f26431831d5cfca035a08c5bdf6\"}}"); }
public void AuthenticateAsync_should_throw_an_AuthenticationException_when_authentication_fails() { var subject = new MongoDBCRAuthenticator(__credential); var reply = MessageHelper.BuildNoDocumentsReturnedReply<RawBsonDocument>(); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(reply); Action act = () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).Wait(); act.ShouldThrow<MongoAuthenticationException>(); }
public void AuthenticateAsync_should_throw_an_AuthenticationException_when_authentication_fails() { var subject = new MongoDBX509Authenticator("CN=client,OU=kerneluser,O=10Gen,L=New York City,ST=New York,C=US"); var reply = MessageHelper.BuildNoDocumentsReturnedReply<RawBsonDocument>(); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(reply); Action act = () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).Wait(); act.ShouldThrow<MongoAuthenticationException>(); }
public void Authenticate_should_send_serverApi_with_command_wire_protocol_if_serverApi_is_provided( [Values(false, true)] bool useServerApi, [Values(false, true)] bool async) { var serverApi = useServerApi ? new ServerApi(ServerApiVersion.V1, true, true) : null; var subject = new MongoDBX509Authenticator("CN=client,OU=kerneluser,O=10Gen,L=New York City,ST=New York,C=US", serverApi); var connection = new MockConnection(__serverId); if (useServerApi) { var reply = MessageHelper.BuildCommandResponse(RawBsonDocumentHelper.FromJson("{ok: 1}")); connection.EnqueueCommandResponseMessage(reply); } else { var reply = MessageHelper.BuildReply(RawBsonDocumentHelper.FromJson("{ok: 1}")); connection.EnqueueReplyMessage(reply); } connection.Description = __descriptionQueryWireProtocol; var expectedRequestId = RequestMessage.CurrentGlobalRequestId + 1; if (async) { subject.AuthenticateAsync(connection, __descriptionQueryWireProtocol, CancellationToken.None).GetAwaiter().GetResult(); } else { subject.Authenticate(connection, __descriptionQueryWireProtocol, CancellationToken.None); } SpinWait.SpinUntil(() => connection.GetSentMessages().Count >= 1, TimeSpan.FromSeconds(5)).Should().BeTrue(); var sentMessages = MessageHelper.TranslateMessagesToBsonDocuments(connection.GetSentMessages()); sentMessages.Count.Should().Be(1); var actualRequestId = sentMessages[0]["requestId"].AsInt32; actualRequestId.Should().BeInRange(expectedRequestId, expectedRequestId + 10); if (useServerApi) { sentMessages[0].Should().Be($"{{ \"opcode\" : \"opmsg\", \"requestId\" : {actualRequestId}, \"responseTo\" : 0, \"sections\" : [{{ \"payloadType\" : 0, \"document\" : {{ \"authenticate\" : 1, \"mechanism\" : \"MONGODB-X509\", \"user\" : \"CN=client,OU=kerneluser,O=10Gen,L=New York City,ST=New York,C=US\", \"$db\" : \"$external\", \"apiVersion\" : \"1\", \"apiStrict\" : true, \"apiDeprecationErrors\" : true }} }}] }}"); } else { sentMessages[0].Should().Be($"{{ opcode : \"query\", requestId : {actualRequestId}, database : \"$external\", collection : \"$cmd\", batchSize : -1, slaveOk : true, query : {{ authenticate : 1, mechanism : \"MONGODB-X509\", user : \"CN=client,OU=kerneluser,O=10Gen,L=New York City,ST=New York,C=US\" }} }}"); } }
public void Authenticate_should_send_serverApi_with_command_wire_protocol_if_serverApi_is_provided( [Values(false, true)] bool useServerApi, [Values(false, true)] bool async) { var serverApi = useServerApi ? new ServerApi(ServerApiVersion.V1, true, true) : null; var subject = new PlainAuthenticator(__credential, serverApi); var connection = new MockConnection(__serverId); var saslStartReply = RawBsonDocumentHelper.FromJson("{ conversationId : 0, payload : BinData(0,\"\"), done : true, ok : 1 }"); if (useServerApi) { connection.EnqueueCommandResponseMessage(MessageHelper.BuildCommandResponse(saslStartReply)); } else { connection.EnqueueReplyMessage(MessageHelper.BuildReply(saslStartReply)); } connection.Description = __descriptionQueryWireProtocol; var expectedRequestId = RequestMessage.CurrentGlobalRequestId + 1; if (async) { subject.AuthenticateAsync(connection, __descriptionQueryWireProtocol, CancellationToken.None).GetAwaiter().GetResult(); } else { subject.Authenticate(connection, __descriptionQueryWireProtocol, CancellationToken.None); } SpinWait.SpinUntil(() => connection.GetSentMessages().Count >= 1, TimeSpan.FromSeconds(5)).Should().BeTrue(); var sentMessages = MessageHelper.TranslateMessagesToBsonDocuments(connection.GetSentMessages()); sentMessages.Count.Should().Be(1); var actualRequestId = sentMessages[0]["requestId"].AsInt32; actualRequestId.Should().BeInRange(expectedRequestId, expectedRequestId + 10); if (useServerApi) { sentMessages[0].Should().Be($"{{ opcode : \"opmsg\", requestId : {actualRequestId}, responseTo : 0, sections : [{{ payloadType : 0, document : {{ saslStart : 1, mechanism : \"PLAIN\", payload : new BinData(0, \"AHVzZXIAcGVuY2ls\"), \"$db\" : \"source\", apiVersion : \"1\", apiStrict : true, apiDeprecationErrors : true }} }}] }}"); } else { sentMessages[0].Should().Be($"{{ opcode : \"query\", requestId : {actualRequestId}, database : \"source\", collection : \"$cmd\", batchSize : -1, slaveOk : true, query : {{ saslStart : 1, mechanism : \"PLAIN\", payload : new BinData(0, \"AHVzZXIAcGVuY2ls\") }} }}"); } }
public void Authenticate_should_use_cache( [Values(false, true)] bool async) { var randomStringGenerator = new ConstantRandomStringGenerator(_clientNonce); var subject = new ScramSha256Authenticator(__credential, randomStringGenerator); var saslStartReply = MessageHelper.BuildReply <RawBsonDocument>(RawBsonDocumentHelper.FromJson( @"{conversationId: 1," + $" payload: BinData(0,\"{ToUtf8Base64(__serverResponse1)}\")," + @" done: false, ok: 1}")); var saslContinueReply = MessageHelper.BuildReply <RawBsonDocument>(RawBsonDocumentHelper.FromJson( @"{conversationId: 1," + $" payload: BinData(0,\"{ToUtf8Base64(__serverResponse2)}\")," + @" done: true, ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(saslStartReply); connection.EnqueueReplyMessage(saslContinueReply); if (async) { subject.AuthenticateAsync(connection, __description, CancellationToken.None).GetAwaiter() .GetResult(); } else { subject.Authenticate(connection, __description, CancellationToken.None); } SpinWait.SpinUntil(() => connection.GetSentMessages().Count >= 2, TimeSpan.FromSeconds(5)).Should() .BeTrue(); subject._cache().Should().NotBe(null); subject._cache()._cacheKey().Should().NotBe(null); subject._cache()._cachedEntry().Should().NotBe(null); }
public void AuthenticateAsync_should_throw_an_AuthenticationException_when_authentication_fails() { var subject = new MongoDBCRAuthenticator(__credential); var reply = MessageHelper.BuildNoDocumentsReturnedReply <RawBsonDocument>(); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(reply); Action act = () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).Wait(); act.ShouldThrow <MongoAuthenticationException>(); }
public void AuthenticateAsync_should_not_throw_when_authentication_succeeds() { var subject = new MongoDBCRAuthenticator(__credential); var getNonceReply = MessageHelper.BuildReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{nonce: \"2375531c32080ae8\", ok: 1}")); var authenticateReply = MessageHelper.BuildReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(getNonceReply); connection.EnqueueReplyMessage(authenticateReply); var currentRequestId = RequestMessage.CurrentGlobalRequestId; Action act = () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).Wait(); act.ShouldNotThrow(); var sentMessages = MessageHelper.TranslateMessagesToBsonDocuments(connection.GetSentMessages()); sentMessages.Count.Should().Be(2); sentMessages[0].Should().Be("{opcode: \"query\", requestId: " + (currentRequestId + 1) + ", database: \"source\", collection: \"$cmd\", batchSize: -1, slaveOk: true, query: {getnonce: 1}}"); sentMessages[1].Should().Be("{opcode: \"query\", requestId: " + (currentRequestId + 2) + ", database: \"source\", collection: \"$cmd\", batchSize: -1, slaveOk: true, query: {authenticate: 1, user: \"user\", nonce: \"2375531c32080ae8\", key: \"21742f26431831d5cfca035a08c5bdf6\"}}"); }
public void AuthenticateAsync_should_not_throw_when_authentication_succeeds() { var subject = new MongoDBX509Authenticator("CN=client,OU=kerneluser,O=10Gen,L=New York City,ST=New York,C=US"); var reply = MessageHelper.BuildReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(reply); Action act = () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).Wait(); act.ShouldNotThrow(); }
public void AuthenticateAsync_should_throw_when_server_provides_invalid_r_value() { var randomStringGenerator = new ConstantRandomStringGenerator("fyko+d2lbbFgONRv9qkxdawL"); var subject = new ScramSha1Authenticator(__credential, randomStringGenerator); var saslStartReply = MessageHelper.BuildSuccessReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{conversationId: 1, payload: BinData(0,\"cj1meWtvLWQybGJiRmdPTlJ2OXFreGRhd0xIbytWZ2s3cXZVT0tVd3VXTElXZzRsLzlTcmFHTUhFRSxzPXJROVpZM01udEJldVAzRTFURFZDNHc9PSxpPTEwMDAw\"), done: false, ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(saslStartReply); var currentRequestId = RequestMessage.CurrentGlobalRequestId; Action act = () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).Wait(); act.ShouldThrow<MongoAuthenticationException>(); }
public void AuthenticateAsync_should_not_throw_when_authentication_succeeds() { var subject = new PlainAuthenticator(__credential); var saslStartReply = MessageHelper.BuildReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{conversationId: 0, payload: BinData(0,\"\"), done: true, ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(saslStartReply); var currentRequestId = RequestMessage.CurrentGlobalRequestId; Action act = () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).Wait(); act.ShouldNotThrow(); var sentMessages = MessageHelper.TranslateMessagesToBsonDocuments(connection.GetSentMessages()); sentMessages.Count.Should().Be(1); sentMessages[0].Should().Be("{opcode: \"query\", requestId: " + (currentRequestId + 1) + ", database: \"source\", collection: \"$cmd\", batchSize: -1, slaveOk: true, query: {saslStart: 1, mechanism: \"PLAIN\", payload: new BinData(0, \"AHVzZXIAcGVuY2ls\")}}"); }
public void Authenticate_should_throw_an_AuthenticationException_when_authentication_fails( [Values(false, true)] bool async) { var subject = new MongoDBCRAuthenticator(__credential); var reply = MessageHelper.BuildNoDocumentsReturnedReply<RawBsonDocument>(); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(reply); Action act; if (async) { act = () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).GetAwaiter().GetResult(); } else { act = () => subject.Authenticate(connection, __description, CancellationToken.None); } act.ShouldThrow<MongoAuthenticationException>(); }
public void Authenticate_should_throw_an_AuthenticationException_when_authentication_fails( [Values(false, true)] bool async) { var subject = new MongoDBX509Authenticator("CN=client,OU=kerneluser,O=10Gen,L=New York City,ST=New York,C=US"); var reply = MessageHelper.BuildNoDocumentsReturnedReply<RawBsonDocument>(); var connection = new MockConnection(__serverId); connection.Description = CreateConnectionDescription(new SemanticVersion(3, 2, 0)); connection.EnqueueReplyMessage(reply); Action act; if (async) { act = () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).GetAwaiter().GetResult(); } else { act = () => subject.Authenticate(connection, __description, CancellationToken.None); } act.ShouldThrow<MongoAuthenticationException>(); }
public void InitializeConnectionAsync_should_invoke_authenticators_when_they_exist() { var isMasterReply = MessageHelper.BuildSuccessReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1 }")); var buildInfoReply = MessageHelper.BuildSuccessReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1, version: \"2.6.3\" }")); var gleReply = MessageHelper.BuildSuccessReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ ok: 1, connectionId: 10 }")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(isMasterReply); connection.EnqueueReplyMessage(buildInfoReply); connection.EnqueueReplyMessage(gleReply); var authenticator = Substitute.For<IAuthenticator>(); connection.Settings = new ConnectionSettings() .WithAuthenticators(new[] { authenticator }); _subject.InitializeConnectionAsync(connection, __connectionId, Timeout.InfiniteTimeSpan, CancellationToken.None).Wait(); authenticator.ReceivedWithAnyArgs().AuthenticateAsync(null, Timeout.InfiniteTimeSpan, CancellationToken.None); }
public void Authenticate_should_not_throw_when_username_is_null_and_server_support_null_username( [Values(false, true)] bool async) { var subject = new MongoDBX509Authenticator(null); var reply = MessageHelper.BuildReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{ok: 1}")); var connection = new MockConnection(__serverId); connection.Description = CreateConnectionDescription(new SemanticVersion(3, 4, 0)); connection.EnqueueReplyMessage(reply); Exception exception; if (async) { exception = Record.Exception(() => subject.AuthenticateAsync(connection, __description, CancellationToken.None).GetAwaiter().GetResult()); } else { exception = Record.Exception(() => subject.Authenticate(connection, __description, CancellationToken.None)); } exception.Should().BeNull(); }
public void Authenticate_should_throw_when_server_provides_invalid_serverSignature( [Values(false, true)] bool async) { var randomStringGenerator = new ConstantRandomStringGenerator("fyko+d2lbbFgONRv9qkxdawL"); var subject = new ScramSha1Authenticator(__credential, randomStringGenerator); var saslStartReply = MessageHelper.BuildReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{conversationId: 1, payload: BinData(0,\"cj1meWtvK2QybGJiRmdPTlJ2OXFreGRhd0xIbytWZ2s3cXZVT0tVd3VXTElXZzRsLzlTcmFHTUhFRSxzPXJROVpZM01udEJldVAzRTFURFZDNHc9PSxpPTEwMDAw\"), done: false, ok: 1}")); var saslContinueReply = MessageHelper.BuildReply<RawBsonDocument>( RawBsonDocumentHelper.FromJson("{conversationId: 1, payload: BinData(0,\"dj1VTVdlSTI1SkQxeU5ZWlJNcFo0Vkh2aFo5ZTBh\"), done: true, ok: 1}")); var connection = new MockConnection(__serverId); connection.EnqueueReplyMessage(saslStartReply); connection.EnqueueReplyMessage(saslContinueReply); Action act; if (async) { act = () => subject.AuthenticateAsync(connection, __description, CancellationToken.None).GetAwaiter().GetResult(); } else { act = () => subject.Authenticate(connection, __description, CancellationToken.None); } act.ShouldThrow<MongoAuthenticationException>(); }