Skip to content

Commit a52b95e

Browse files
authored
CSHARP-2091: Remove MongoClient constructors that take multiple credentials. (#1404)
1 parent 960b74e commit a52b95e

18 files changed

+103
-321
lines changed

src/MongoDB.Driver/ClusterKey.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
using System;
1717
using System.Collections.Generic;
1818
using System.Linq;
19-
using Microsoft.Extensions.Logging;
2019
using MongoDB.Driver.Core.Clusters;
2120
using MongoDB.Driver.Core.Configuration;
2221
using MongoDB.Driver.Core.Servers;
@@ -36,7 +35,7 @@ internal class ClusterKey
3635
private readonly ConnectionModeSwitch _connectionModeSwitch;
3736
#pragma warning restore CS0618 // Type or member is obsolete
3837
private readonly TimeSpan _connectTimeout;
39-
private readonly IReadOnlyList<MongoCredential> _credentials;
38+
private readonly MongoCredential _credential;
4039
private readonly CryptClientSettings _cryptClientSettings;
4140
private readonly bool? _directConnection;
4241
private readonly int _hashCode;
@@ -80,7 +79,7 @@ public ClusterKey(
8079
ConnectionModeSwitch connectionModeSwitch,
8180
#pragma warning restore CS0618 // Type or member is obsolete
8281
TimeSpan connectTimeout,
83-
IReadOnlyList<MongoCredential> credentials,
82+
MongoCredential credential,
8483
CryptClientSettings cryptClientSettings,
8584
bool? directConnection,
8685
TimeSpan heartbeatInterval,
@@ -121,7 +120,7 @@ public ClusterKey(
121120
_connectionMode = connectionMode;
122121
_connectionModeSwitch = connectionModeSwitch;
123122
_connectTimeout = connectTimeout;
124-
_credentials = credentials;
123+
_credential = credential;
125124
_cryptClientSettings = cryptClientSettings;
126125
_directConnection = directConnection;
127126
_heartbeatInterval = heartbeatInterval;
@@ -176,7 +175,7 @@ public ConnectionMode ConnectionMode
176175
[Obsolete("This property will be removed in a later release.")]
177176
public ConnectionModeSwitch ConnectionModeSwitch => _connectionModeSwitch;
178177
public TimeSpan ConnectTimeout { get { return _connectTimeout; } }
179-
public IReadOnlyList<MongoCredential> Credentials { get { return _credentials; } }
178+
public MongoCredential Credential { get { return _credential; } }
180179
public CryptClientSettings CryptClientSettings { get { return _cryptClientSettings; } }
181180
public bool? DirectConnection
182181
{
@@ -225,7 +224,7 @@ private int CalculateHashCode()
225224
{
226225
// keep calculation simple (leave out fields that are rarely used)
227226
return new Hasher()
228-
.HashElements(_credentials)
227+
.Hash(_credential)
229228
.HashElements(_servers)
230229
.GetHashCode();
231230
}
@@ -246,7 +245,7 @@ public override bool Equals(object obj)
246245
_connectionMode == rhs._connectionMode &&
247246
_connectionModeSwitch == rhs._connectionModeSwitch &&
248247
_connectTimeout == rhs._connectTimeout &&
249-
_credentials.SequenceEqual(rhs._credentials) &&
248+
_credential == rhs._credential &&
250249
object.Equals(_cryptClientSettings, rhs._cryptClientSettings) &&
251250
_directConnection.Equals(rhs._directConnection) &&
252251
_heartbeatInterval == rhs._heartbeatInterval &&

src/MongoDB.Driver/ClusterRegistry.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* limitations under the License.
1414
*/
1515

16+
using System;
1617
using System.Collections.Generic;
1718
using System.Linq;
1819
using System.Net;
@@ -119,7 +120,16 @@ private ConnectionPoolSettings ConfigureConnectionPool(ConnectionPoolSettings se
119120
private ConnectionSettings ConfigureConnection(ConnectionSettings settings, ClusterKey clusterKey)
120121
{
121122
var endPoints = clusterKey.Servers.Select(s => new DnsEndPoint(s.Host, s.Port)).ToArray();
122-
var authenticatorFactories = clusterKey.Credentials.Select(c => new AuthenticatorFactory(() => c.ToAuthenticator(endPoints, clusterKey.ServerApi)));
123+
var authenticatorFactories = Array.Empty<IAuthenticatorFactory>();
124+
125+
if (clusterKey.Credential != null)
126+
{
127+
authenticatorFactories = new[]
128+
{
129+
new AuthenticatorFactory(() => clusterKey.Credential.ToAuthenticator(endPoints, clusterKey.ServerApi))
130+
};
131+
}
132+
123133
return settings.With(
124134
authenticatorFactories: Optional.Enumerable<IAuthenticatorFactory>(authenticatorFactories),
125135
compressors: Optional.Enumerable(clusterKey.Compressors),

src/MongoDB.Driver/Core/Core/Authentication/AuthenticationHelper.cs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
*/
1515

1616
using System;
17-
using System.Collections.Generic;
1817
using System.Runtime.InteropServices;
1918
using System.Security;
2019
using System.Security.Cryptography;
@@ -29,35 +28,37 @@ namespace MongoDB.Driver.Core.Authentication
2928
{
3029
internal static class AuthenticationHelper
3130
{
32-
public static void Authenticate(IConnection connection, ConnectionDescription description, IReadOnlyList<IAuthenticator> authenticators, CancellationToken cancellationToken)
31+
public static void Authenticate(IConnection connection, ConnectionDescription description, IAuthenticator authenticator, CancellationToken cancellationToken)
3332
{
3433
Ensure.IsNotNull(connection, nameof(connection));
3534
Ensure.IsNotNull(description, nameof(description));
36-
Ensure.IsNotNull(authenticators, nameof(authenticators));
35+
36+
if (authenticator == null)
37+
{
38+
return;
39+
}
3740

3841
// authentication is currently broken on arbiters
3942
if (!description.HelloResult.IsArbiter)
4043
{
41-
foreach (var authenticator in authenticators)
42-
{
43-
authenticator.Authenticate(connection, description, cancellationToken);
44-
}
44+
authenticator.Authenticate(connection, description, cancellationToken);
4545
}
4646
}
4747

48-
public static async Task AuthenticateAsync(IConnection connection, ConnectionDescription description, IReadOnlyList<IAuthenticator> authenticators, CancellationToken cancellationToken)
48+
public static async Task AuthenticateAsync(IConnection connection, ConnectionDescription description, IAuthenticator authenticator, CancellationToken cancellationToken)
4949
{
5050
Ensure.IsNotNull(connection, nameof(connection));
5151
Ensure.IsNotNull(description, nameof(description));
52-
Ensure.IsNotNull(authenticators, nameof(authenticators));
52+
53+
if (authenticator == null)
54+
{
55+
return;
56+
}
5357

5458
// authentication is currently broken on arbiters
5559
if (!description.HelloResult.IsArbiter)
5660
{
57-
foreach (var authenticator in authenticators)
58-
{
5961
await authenticator.AuthenticateAsync(connection, description, cancellationToken).ConfigureAwait(false);
60-
}
6162
}
6263
}
6364

src/MongoDB.Driver/Core/Core/Connections/BinaryConnection.cs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -313,24 +313,21 @@ private async Task OpenHelperAsync(CancellationToken cancellationToken)
313313

314314
public void Reauthenticate(CancellationToken cancellationToken)
315315
{
316-
InvalidateAuthenticators();
316+
InvalidateAuthenticator();
317317
_connectionInitializerContext = _connectionInitializer.Authenticate(this, _connectionInitializerContext, cancellationToken);
318318
}
319319

320320
public async Task ReauthenticateAsync(CancellationToken cancellationToken)
321321
{
322-
InvalidateAuthenticators();
322+
InvalidateAuthenticator();
323323
_connectionInitializerContext = await _connectionInitializer.AuthenticateAsync(this, _connectionInitializerContext, cancellationToken).ConfigureAwait(false);
324324
}
325325

326-
private void InvalidateAuthenticators()
326+
private void InvalidateAuthenticator()
327327
{
328-
foreach (var authenticator in _connectionInitializerContext.Authenticators)
328+
if (_connectionInitializerContext?.Authenticator is MongoOidcAuthenticator oidcAuthenticator)
329329
{
330-
if (authenticator is MongoOidcAuthenticator oidcAuthenticator)
331-
{
332-
oidcAuthenticator.ClearCredentialsCache();
333-
}
330+
oidcAuthenticator.ClearCredentialsCache();
334331
}
335332
}
336333

src/MongoDB.Driver/Core/Core/Connections/ConnectionInitializer.cs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,9 @@ public ConnectionInitializerContext Authenticate(IConnection connection, Connect
5151
{
5252
Ensure.IsNotNull(connection, nameof(connection));
5353
Ensure.IsNotNull(connectionInitializerContext, nameof(connectionInitializerContext));
54-
var authenticators = Ensure.IsNotNull(connectionInitializerContext.Authenticators, nameof(connectionInitializerContext.Authenticators));
5554
var description = Ensure.IsNotNull(connectionInitializerContext.Description, nameof(connectionInitializerContext.Description));
5655

57-
AuthenticationHelper.Authenticate(connection, description, authenticators, cancellationToken);
56+
AuthenticationHelper.Authenticate(connection, description, connectionInitializerContext.Authenticator, cancellationToken);
5857

5958
// Connection description should be updated only on the initial handshake and not after reauthentication
6059
if (!description.IsInitialized())
@@ -80,17 +79,16 @@ public ConnectionInitializerContext Authenticate(IConnection connection, Connect
8079
}
8180
}
8281

83-
return new ConnectionInitializerContext(description, authenticators);
82+
return new ConnectionInitializerContext(description, connectionInitializerContext.Authenticator);
8483
}
8584

8685
public async Task<ConnectionInitializerContext> AuthenticateAsync(IConnection connection, ConnectionInitializerContext connectionInitializerContext, CancellationToken cancellationToken)
8786
{
8887
Ensure.IsNotNull(connection, nameof(connection));
8988
Ensure.IsNotNull(connectionInitializerContext, nameof(connectionInitializerContext));
90-
var authenticators = Ensure.IsNotNull(connectionInitializerContext.Authenticators, nameof(connectionInitializerContext.Authenticators));
9189
var description = Ensure.IsNotNull(connectionInitializerContext.Description, nameof(connectionInitializerContext.Description));
9290

93-
await AuthenticationHelper.AuthenticateAsync(connection, description, authenticators, cancellationToken).ConfigureAwait(false);
91+
await AuthenticationHelper.AuthenticateAsync(connection, description, connectionInitializerContext.Authenticator, cancellationToken).ConfigureAwait(false);
9492

9593
// Connection description should be updated only on the initial handshake and not while reauthentication
9694
if (!description.IsInitialized())
@@ -118,37 +116,37 @@ public async Task<ConnectionInitializerContext> AuthenticateAsync(IConnection co
118116
}
119117
}
120118

121-
return new ConnectionInitializerContext(description, authenticators);
119+
return new ConnectionInitializerContext(description, connectionInitializerContext.Authenticator);
122120
}
123121

124122
public ConnectionInitializerContext SendHello(IConnection connection, CancellationToken cancellationToken)
125123
{
126124
Ensure.IsNotNull(connection, nameof(connection));
127-
var authenticators = CreateAuthenticators(connection);
128-
var helloCommand = CreateInitialHelloCommand(authenticators, connection.Settings.LoadBalanced, cancellationToken);
125+
var authenticator = CreateAuthenticator(connection);
126+
var helloCommand = CreateInitialHelloCommand(authenticator, connection.Settings.LoadBalanced, cancellationToken);
129127
var helloProtocol = HelloHelper.CreateProtocol(helloCommand, _serverApi);
130128
var helloResult = HelloHelper.GetResult(connection, helloProtocol, cancellationToken);
131129
if (connection.Settings.LoadBalanced && !helloResult.ServiceId.HasValue)
132130
{
133131
throw new InvalidOperationException("Driver attempted to initialize in load balancing mode, but the server does not support this mode.");
134132
}
135133

136-
return new (new ConnectionDescription(connection.ConnectionId, helloResult), authenticators);
134+
return new (new ConnectionDescription(connection.ConnectionId, helloResult), authenticator);
137135
}
138136

139137
public async Task<ConnectionInitializerContext> SendHelloAsync(IConnection connection, CancellationToken cancellationToken)
140138
{
141139
Ensure.IsNotNull(connection, nameof(connection));
142-
var authenticators = CreateAuthenticators(connection);
143-
var helloCommand = CreateInitialHelloCommand(authenticators, connection.Settings.LoadBalanced, cancellationToken);
140+
var authenticator = CreateAuthenticator(connection);
141+
var helloCommand = CreateInitialHelloCommand(authenticator, connection.Settings.LoadBalanced, cancellationToken);
144142
var helloProtocol = HelloHelper.CreateProtocol(helloCommand, _serverApi);
145143
var helloResult = await HelloHelper.GetResultAsync(connection, helloProtocol, cancellationToken).ConfigureAwait(false);
146144
if (connection.Settings.LoadBalanced && !helloResult.ServiceId.HasValue)
147145
{
148146
throw new InvalidOperationException("Driver attempted to initialize in load balancing mode, but the server does not support this mode.");
149147
}
150148

151-
return new (new ConnectionDescription(connection.ConnectionId, helloResult), authenticators);
149+
return new (new ConnectionDescription(connection.ConnectionId, helloResult), authenticator);
152150
}
153151

154152
// private methods
@@ -165,24 +163,24 @@ private CommandWireProtocol<BsonDocument> CreateGetLastErrorProtocol(ServerApi s
165163
return getLastErrorProtocol;
166164
}
167165

168-
private BsonDocument CreateInitialHelloCommand(IReadOnlyList<IAuthenticator> authenticators, bool loadBalanced = false, CancellationToken cancellationToken = default)
166+
private BsonDocument CreateInitialHelloCommand(IAuthenticator authenticator, bool loadBalanced = false, CancellationToken cancellationToken = default)
169167
{
170168
var command = HelloHelper.CreateCommand(_serverApi, loadBalanced: loadBalanced);
171169
HelloHelper.AddClientDocumentToCommand(command, _clientDocument);
172170
HelloHelper.AddCompressorsToCommand(command, _compressors);
173-
return HelloHelper.CustomizeCommand(command, authenticators, cancellationToken);
171+
return HelloHelper.CustomizeCommand(command, authenticator, cancellationToken);
174172
}
175173

176-
private List<IAuthenticator> CreateAuthenticators(IConnection connection)
174+
private IAuthenticator CreateAuthenticator(IConnection connection)
177175
{
178176
if (connection.Description.IsInitialized())
179177
{
180178
// should never be here.
181179
throw new InvalidOperationException();
182180
}
183181

184-
var authenticatorFactories = connection.Settings.AuthenticatorFactories;
185-
return authenticatorFactories.Select(c => c.Create()).ToList();
182+
var authenticatorFactory = connection.Settings.AuthenticatorFactories.SingleOrDefault();
183+
return authenticatorFactory?.Create();
186184
}
187185

188186
private ConnectionDescription UpdateConnectionIdWithServerValue(ConnectionDescription description, BsonDocument getLastErrorResult)

src/MongoDB.Driver/Core/Core/Connections/HelloHelper.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,11 @@ internal static BsonDocument CreateCommand(ServerApi serverApi, bool helloOk = f
6161
};
6262
}
6363

64-
internal static BsonDocument CustomizeCommand(BsonDocument command, IReadOnlyList<IAuthenticator> authenticators, CancellationToken cancellationToken)
64+
internal static BsonDocument CustomizeCommand(BsonDocument command, IAuthenticator authenticator, CancellationToken cancellationToken)
6565
{
66-
return authenticators.Count == 1 ? authenticators[0].CustomizeInitialHelloCommand(command, cancellationToken) : command;
66+
return authenticator != null
67+
? authenticator.CustomizeInitialHelloCommand(command, cancellationToken)
68+
: command;
6769
}
6870

6971
internal static CommandWireProtocol<BsonDocument> CreateProtocol(

src/MongoDB.Driver/Core/Core/Connections/IConnectionInitializer.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ namespace MongoDB.Driver.Core.Connections
2323
{
2424
internal sealed class ConnectionInitializerContext
2525
{
26-
public ConnectionInitializerContext(ConnectionDescription description, IReadOnlyList<IAuthenticator> authenticators)
26+
public ConnectionInitializerContext(ConnectionDescription description, IAuthenticator authenticator)
2727
{
2828
Description = Ensure.IsNotNull(description, nameof(description));
29-
Authenticators = Ensure.IsNotNull(authenticators, nameof(authenticators));
29+
Authenticator = authenticator;
3030
}
3131

32-
public IReadOnlyList<IAuthenticator> Authenticators { get; }
32+
public IAuthenticator Authenticator { get; }
3333
public ConnectionDescription Description { get; }
3434
}
3535

src/MongoDB.Driver/MongoClient.cs

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -538,20 +538,7 @@ private MessageEncoderSettings GetMessageEncoderSettings()
538538
private IClientSessionHandle StartImplicitSession()
539539
{
540540
var options = new ClientSessionOptions { CausalConsistency = false, Snapshot = false };
541-
542-
ICoreSessionHandle coreSession;
543-
#pragma warning disable 618
544-
var areMultipleUsersAuthenticated = _settings.Credentials.Count() > 1;
545-
#pragma warning restore
546-
if (!areMultipleUsersAuthenticated)
547-
{
548-
coreSession = _cluster.StartSession(options.ToCore(isImplicit: true));
549-
}
550-
else
551-
{
552-
coreSession = NoCoreSession.NewHandle();
553-
}
554-
541+
ICoreSessionHandle coreSession = _cluster.StartSession(options.ToCore(isImplicit: true));
555542
return new ClientSessionHandle(this, options, coreSession);
556543
}
557544

0 commit comments

Comments
 (0)