Skip to content

Commit 79bef25

Browse files
authored
CSHARP-4961: Rearchitect User Acquisition in Authentication and Authorization Workflow (#1628)
1 parent 2d5eac9 commit 79bef25

File tree

2 files changed

+122
-0
lines changed

2 files changed

+122
-0
lines changed

tests/MongoDB.Driver.Tests/Core/Connections/HelloResultTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,18 @@ public void ElectionId_should_parse_document_correctly(string json, string expec
107107
subject.ElectionId.Should().Be(expected);
108108
}
109109

110+
[Theory]
111+
[InlineData("{ }", false)]
112+
[InlineData("{ saslSupportedMechs : [] }", true)]
113+
[InlineData("{ saslSupportedMechs : ['SCRAM-SHA-128'] }", true)]
114+
[InlineData("{ saslSupportedMechs : ['unknown'] }", true)]
115+
public void HasSaslSupportedMechs_should_parse_document_correctly(string json, bool expected)
116+
{
117+
var subject = new HelloResult(BsonDocument.Parse(json));
118+
119+
subject.HasSaslSupportedMechs.Should().Be(expected);
120+
}
121+
110122
[Theory]
111123
[InlineData("{ lastWrite : { lastWriteDate : ISODate(\"2015-01-01T00:00:00Z\") } }", 2015)]
112124
[InlineData("{ lastWrite : { lastWriteDate : ISODate(\"2016-01-01T00:00:00Z\") } }", 2016)]
@@ -205,6 +217,18 @@ public void Me_should_parse_document_correctly(string json, string expectedEndPo
205217
subject.Me.Should().Be(endPoint);
206218
}
207219

220+
[Theory]
221+
[InlineData("{ }", new string[0])]
222+
[InlineData("{ saslSupportedMechs : ['SCRAM-SHA-128'] }", new[] { "SCRAM-SHA-128" })]
223+
[InlineData("{ saslSupportedMechs : ['SCRAM-SHA-128', 'SCRAM-SHA-256'] }", new[] { "SCRAM-SHA-128", "SCRAM-SHA-256" })]
224+
[InlineData("{ saslSupportedMechs : ['unknown'] }", new[] { "unknown" })]
225+
public void SaslSupportedMechs_should_parse_document_correctly(string json, string[] expectedMechs)
226+
{
227+
var subject = new HelloResult(BsonDocument.Parse(json));
228+
229+
subject.SaslSupportedMechs.Should().BeEquivalentTo(expectedMechs);
230+
}
231+
208232
[Theory]
209233
[InlineData("{ ok: 1, isreplicaset: true, setName: \"awesome\", isWritablePrimary: true }", ServerType.ReplicaSetGhost)]
210234
[InlineData("{ ok: 1, setName: \"awesome\", " + OppressiveLanguageConstants.LegacyHelloResponseIsWritablePrimaryFieldName + ": true }", ServerType.ReplicaSetPrimary)]
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/* Copyright 2010-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System.Net;
17+
using System.Threading;
18+
using System.Threading.Tasks;
19+
using FluentAssertions;
20+
using MongoDB.Bson;
21+
using MongoDB.Bson.TestHelpers;
22+
using MongoDB.Driver.Core;
23+
using MongoDB.Driver.Core.Clusters;
24+
using MongoDB.Driver.Core.Configuration;
25+
using MongoDB.Driver.Core.Connections;
26+
using MongoDB.Driver.Core.Misc;
27+
using MongoDB.Driver.Core.Servers;
28+
using MongoDB.Driver.Core.TestHelpers.Logging;
29+
using MongoDB.TestHelpers.XunitExtensions;
30+
using Moq;
31+
using Xunit;
32+
using Xunit.Abstractions;
33+
34+
namespace MongoDB.Driver.Tests.Specifications.mongodb_handshake
35+
{
36+
public class MongoDbHandshakeProseTests : LoggableTestClass
37+
{
38+
// https://github.com/mongodb/specifications/blob/75027a8e91ff50778aed2ad5a67c005f2694705f/source/mongodb-handshake/tests/README.md?plain=1#L77
39+
public MongoDbHandshakeProseTests(ITestOutputHelper output) : base(output)
40+
{
41+
}
42+
43+
[Theory]
44+
[ParameterAttributeData]
45+
public async Task DriverAcceptsArbitraryAuthMechanism([Values(false, true)] bool async)
46+
{
47+
var capturedEvents = new EventCapturer();
48+
var mockStreamFactory = new Mock<IStreamFactory>();
49+
var endPoint = new DnsEndPoint("localhost", 27017);
50+
var serverId = new ServerId(new ClusterId(), endPoint);
51+
var connectionId = new ConnectionId(serverId);
52+
var helloResult = new HelloResult(BsonDocument.Parse("{ ok: 1, saslSupportedMechs : ['arbitrary string'] }"));
53+
var connectionDescription = new ConnectionDescription(connectionId, helloResult);
54+
var connectionInitializerContext = new ConnectionInitializerContext(connectionDescription, null);
55+
var connectionInitializerContextAfterAuthentication = new ConnectionInitializerContext(connectionDescription, null);
56+
57+
var mockConnectionInitializer = new Mock<IConnectionInitializer>();
58+
mockConnectionInitializer
59+
.Setup(i => i.SendHello(It.IsAny<IConnection>(), CancellationToken.None))
60+
.Returns(connectionInitializerContext);
61+
mockConnectionInitializer
62+
.Setup(i => i.Authenticate(It.IsAny<IConnection>(), It.IsAny<ConnectionInitializerContext>(), CancellationToken.None))
63+
.Returns(connectionInitializerContextAfterAuthentication);
64+
mockConnectionInitializer
65+
.Setup(i => i.SendHelloAsync(It.IsAny<IConnection>(), CancellationToken.None))
66+
.ReturnsAsync(connectionInitializerContext);
67+
mockConnectionInitializer
68+
.Setup(i => i.AuthenticateAsync(It.IsAny<IConnection>(), It.IsAny<ConnectionInitializerContext>(), CancellationToken.None))
69+
.ReturnsAsync(connectionInitializerContextAfterAuthentication);
70+
71+
using var subject = new BinaryConnection(
72+
serverId: serverId,
73+
endPoint: endPoint,
74+
settings: new ConnectionSettings(),
75+
streamFactory: mockStreamFactory.Object,
76+
connectionInitializer: mockConnectionInitializer.Object,
77+
eventSubscriber: capturedEvents,
78+
LoggerFactory);
79+
80+
if (async)
81+
{
82+
await subject.OpenAsync(CancellationToken.None);
83+
}
84+
else
85+
{
86+
subject.Open(CancellationToken.None);
87+
}
88+
89+
subject._state().Should().Be(3); // 3 - open.
90+
}
91+
}
92+
93+
internal static class BinaryConnectionReflector
94+
{
95+
public static int _state(this BinaryConnection subject)
96+
=> ((InterlockedInt32)Reflector.GetFieldValue(subject, nameof(_state))).Value;
97+
}
98+
}

0 commit comments

Comments
 (0)