Skip to content

Commit

Permalink
Exception on passing different gateway hostnames through different in…
Browse files Browse the repository at this point in the history
…puts (#3330)
  • Loading branch information
abhipsaMisra authored May 8, 2023
1 parent 8289847 commit 7c33b87
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 11 deletions.
14 changes: 13 additions & 1 deletion iothub/device/src/Authentication/IotHubConnectionCredentials.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ public IotHubConnectionCredentials(IAuthenticationMethod authenticationMethod, s
/// <returns>A new instance of this class.</returns>
/// <exception cref="ArgumentNullException"><paramref name="iotHubConnectionString"/>, IoT hub host name or device Id is null.</exception>
/// <exception cref="ArgumentException"><paramref name="iotHubConnectionString"/>, IoT hub host name or device Id are an empty string or consist only of white-space characters.</exception>
/// <exception cref="InvalidOperationException">Different gateway hostnames were specified through the connection string and <see cref="IotHubClientOptions.GatewayHostName"/>.
/// It is recommended to use <see cref="IotHubClientOptions"/> to specify values for the additional fields rather than hand edit connection strings.</exception>
/// <exception cref="FormatException">Neither shared access key nor shared access signature were presented for authentication.</exception>
/// <exception cref="FormatException">Either shared access key or shared access signature where presented together with X509 certificates for authentication.</exception>
public IotHubConnectionCredentials(string iotHubConnectionString, string gatewayHostName = default)
Expand All @@ -70,8 +72,18 @@ public IotHubConnectionCredentials(string iotHubConnectionString, string gateway

// We'll parse the connection string and use that to build an auth method
IotHubConnectionString parsedConnectionString = IotHubConnectionStringParser.Parse(iotHubConnectionString);
AuthenticationMethod = GetAuthenticationMethodFromConnectionString(parsedConnectionString);

// The gateway hostname shouldn't be specified in both the connection string and in IotHubClientOptions
// If they are specified in both places then they should always be equal (case-sensitive and culture-insensitive comparison).
if (!string.IsNullOrWhiteSpace(parsedConnectionString.GatewayHostName) && !string.IsNullOrWhiteSpace(gatewayHostName))
{
if (parsedConnectionString.GatewayHostName != gatewayHostName)
{
throw new InvalidOperationException("Different gateway host names were supplied through the connection string and IotHubClientOptions. Please supply the gateway host name through one argument only.");
}
}

AuthenticationMethod = GetAuthenticationMethodFromConnectionString(parsedConnectionString);
PopulatePropertiesFromConnectionString(parsedConnectionString, gatewayHostName);
SetAuthenticationModel();
SetTokenRefresherIfApplicable();
Expand Down
4 changes: 0 additions & 4 deletions iothub/device/src/IotHubClientOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,6 @@ public IotHubClientOptions(IotHubClientTransportSettings transportSettings)
/// <para>
/// It can also be used for other, custom transparent or protocol gateways.
/// </para>
/// <para>
/// If the client uses a connection string-based authentication mechanism, and has a gateway hostname specified in the connection string
/// then the value set in options will be ignored.
/// </para>
/// </remarks>
public string GatewayHostName { get; set; }

Expand Down
2 changes: 2 additions & 0 deletions iothub/device/src/IotHubDeviceClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public class IotHubDeviceClient : IotHubBaseClient
/// or the IoT hub host name or device Id in the connection string are an empty string or consist only of white-space characters.</exception>
/// <exception cref="ArgumentException">Neither shared access key nor shared access signature were presented for authentication.</exception>
/// <exception cref="InvalidOperationException">A module Id was specified in the connection string. <see cref="IotHubModuleClient"/> should be used for modules.</exception>
/// <exception cref="InvalidOperationException">Different gateway hostnames were specified through the connection string and <see cref="IotHubClientOptions.GatewayHostName"/>.
/// It is recommended to use <see cref="IotHubClientOptions"/> to specify values for the additional fields rather than hand edit connection strings.</exception>
/// <example>
/// <code language="csharp">
/// await using var client = new IotHubDeviceClient(
Expand Down
2 changes: 2 additions & 0 deletions iothub/device/src/IotHubModuleClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public class IotHubModuleClient : IotHubBaseClient
/// <exception cref="InvalidOperationException">Required key/value pairs were missing from the connection string.</exception>
/// <returns>A disposable client instance.</returns>
/// <exception cref="InvalidOperationException">A module Id was missing in the connection string. <see cref="IotHubDeviceClient"/> should be used for devices.</exception>
/// <exception cref="InvalidOperationException">Different gateway hostnames were specified through the connection string and <see cref="IotHubClientOptions.GatewayHostName"/>.
/// It is recommended to use <see cref="IotHubClientOptions"/> to specify values for the additional fields rather than hand edit connection strings.</exception>
/// <example>
/// <code language="csharp">
/// await using var client = new IotHubModuleClient(
Expand Down
22 changes: 16 additions & 6 deletions iothub/device/tests/IotHubDeviceClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1634,7 +1634,7 @@ private static void IotHubDeviceClient_InitWithNonHttpTransportAndModelId_DoesNo
}

[TestMethod]
public async Task IotHubDeviceClient_CreateFromConnectionString_WithoutWithGatewayHostname_UseIotHubClientOptionsGatewayHostName()
public async Task IotHubDeviceClient_CreateFromConnectionString_UseIotHubClientOptionsGatewayHostName()
{
// arrange
var clientOptions = new IotHubClientOptions
Expand All @@ -1652,7 +1652,19 @@ public async Task IotHubDeviceClient_CreateFromConnectionString_WithoutWithGatew
}

[TestMethod]
public async Task IotHubDeviceClient_CreateFromConnectionString_WithGatewayHostname_OverrideIotHubClientOptionsGatewayHostName()
public async Task IotHubDeviceClient_CreateFromConnectionString__UseConnectionStringGatewayHostName()
{
// arrange and act
await using var deviceClient = new IotHubDeviceClient(s_fakeConnectionStringWithGatewayHostName);

// assert
deviceClient.IotHubConnectionCredentials.IotHubHostName.Should().Be(FakeHostName);
deviceClient.IotHubConnectionCredentials.GatewayHostName.Should().Be(FakeGatewayHostNameCs);
deviceClient.IotHubConnectionCredentials.HostName.Should().Be(FakeGatewayHostNameCs);
}

[TestMethod]
public void IotHubDeviceClient_CreateFromConnectionString_PassMultipleGatewayHostName_ThrowsException()
{
// arrange
var clientOptions = new IotHubClientOptions
Expand All @@ -1661,12 +1673,10 @@ public async Task IotHubDeviceClient_CreateFromConnectionString_WithGatewayHostn
};

// act
await using var deviceClient = new IotHubDeviceClient(s_fakeConnectionStringWithGatewayHostName, clientOptions);
Func<IotHubDeviceClient> act = () => new IotHubDeviceClient(s_fakeConnectionStringWithGatewayHostName, clientOptions);

// assert
deviceClient.IotHubConnectionCredentials.IotHubHostName.Should().Be(FakeHostName);
deviceClient.IotHubConnectionCredentials.GatewayHostName.Should().Be(FakeGatewayHostNameCs);
deviceClient.IotHubConnectionCredentials.HostName.Should().Be(FakeGatewayHostNameCs);
act.Should().Throw<InvalidOperationException>();
}

private class TestDeviceAuthenticationWithTokenRefresh : ClientAuthenticationWithTokenRefresh
Expand Down

0 comments on commit 7c33b87

Please sign in to comment.