From 23f68111a347afd6cb61252a7ad3e1e997ff6d10 Mon Sep 17 00:00:00 2001 From: Ivan ROPITEAUX Date: Thu, 1 Jun 2023 19:03:00 +0200 Subject: [PATCH] Use certificate to authenticate devices and edge devices (#2143) * Fix code * Use DeviceName for certificates * Display certificates credentials on ConnectionStringDialog * Add on edge device screen and allow file download * Fix unit tests --------- Co-authored-by: ropiteauxi Co-authored-by: Kevin BEAUGRAND --- .../Services/IDeviceService.cs | 2 +- .../Services/IExternalDeviceService.cs | 2 +- .../Devices/ConnectionStringDialog.razor | 85 +++++++++++--- .../EdgeDevices/ConnectionStringDialog.razor | 105 +++++++++++++----- .../Services/DeviceClientService.cs | 4 +- .../Services/EdgeDeviceClientService.cs | 4 +- .../Services/IDeviceClientService.cs | 2 +- .../Services/IEdgeDeviceClientService.cs | 2 +- .../Services/AwsExternalDeviceService.cs | 48 ++++---- .../Services/DeviceServiceBase.cs | 4 +- .../Controllers/v1.0/DevicesControllerBase.cs | 9 +- .../Devices/ConnectionStringDialogTests.cs | 4 +- .../ConnectionStringDialogTests.cs | 6 +- .../Services/DeviceClientServiceTests.cs | 2 +- .../Services/EdgeDeviceClientServiceTests.cs | 2 +- .../v1.0/DevicesControllerTests.cs | 10 +- .../Server/Services/DeviceServiceTests.cs | 4 +- 17 files changed, 205 insertions(+), 90 deletions(-) diff --git a/src/AzureIoTHub.Portal.Application/Services/IDeviceService.cs b/src/AzureIoTHub.Portal.Application/Services/IDeviceService.cs index 68822d04d..092527173 100644 --- a/src/AzureIoTHub.Portal.Application/Services/IDeviceService.cs +++ b/src/AzureIoTHub.Portal.Application/Services/IDeviceService.cs @@ -35,7 +35,7 @@ Task> GetDevices( Task DeleteDevice(string deviceId); - Task GetCredentials(string deviceId); + Task GetCredentials(TDto device); Task> GetDeviceTelemetry(string deviceId); diff --git a/src/AzureIoTHub.Portal.Application/Services/IExternalDeviceService.cs b/src/AzureIoTHub.Portal.Application/Services/IExternalDeviceService.cs index 3b5578b38..819e82eeb 100644 --- a/src/AzureIoTHub.Portal.Application/Services/IExternalDeviceService.cs +++ b/src/AzureIoTHub.Portal.Application/Services/IExternalDeviceService.cs @@ -68,7 +68,7 @@ Task> GetAllEdgeDevice( Task GetConcentratorsCount(); - Task GetDeviceCredentials(string deviceId); + Task GetDeviceCredentials(string deviceName); Task GetEdgeDeviceCredentials(IoTEdgeDevice device); diff --git a/src/AzureIoTHub.Portal.Client/Pages/Devices/ConnectionStringDialog.razor b/src/AzureIoTHub.Portal.Client/Pages/Devices/ConnectionStringDialog.razor index bf944f6c1..6c08a1b12 100644 --- a/src/AzureIoTHub.Portal.Client/Pages/Devices/ConnectionStringDialog.razor +++ b/src/AzureIoTHub.Portal.Client/Pages/Devices/ConnectionStringDialog.razor @@ -1,7 +1,10 @@ @using AzureIoTHub.Portal.Models.v10 +@using AzureIoTHub.Portal.Shared.Models.v10 +@using System.Text @inject ClipboardService ClipboardService @inject IDeviceClientService DeviceClientService +@inject IJSRuntime JS
@@ -9,22 +12,46 @@ - - Service Endpoint - - - - Registration Id - - - - Scope Id - - - - Symmetric Key - - + @if (credentials.AuthenticationMode != null && AuthenticationMode.SymmetricKey.Equals(credentials.AuthenticationMode)) + { + @if (credentials.SymmetricCredentials != null) + { + + Service Endpoint + + + + Registration Id + + + + Scope Id + + + + Symmetric Key + + + } + } + else + { + @if (credentials.CertificateCredentials != null) + { + + Certificate Pem + + + + Public Key + + + + Private Key + + + } + } @@ -38,10 +65,10 @@ @code { [CascadingParameter] public Error Error { get; set; } = default!; - + [CascadingParameter] MudDialogInstance MudDialog { get; set; } = default!; [Parameter] public string deviceId { get; set; } = default!; - private SymmetricCredentials credentials = new(); + private DeviceCredentials credentials = new(); protected override async Task OnInitializedAsync() { @@ -58,5 +85,27 @@ } } + private async Task DownloadPemFile() + { + var stream = new DotNetStreamReference(stream: new MemoryStream( + Encoding.UTF8.GetBytes(credentials.CertificateCredentials.CertificatePem))); + await JS.InvokeVoidAsync("downloadFileFromStream", "certificate.pem", stream); + } + + private async Task DownloadPublicKeyFile() + { + var stream = new DotNetStreamReference(stream: new MemoryStream( + Encoding.UTF8.GetBytes(credentials.CertificateCredentials.PublicKey))); + await JS.InvokeVoidAsync("downloadFileFromStream", "key.pub", stream); + } + + private async Task DownloadPrivateKeyFile() + { + var stream = new DotNetStreamReference(stream: new MemoryStream( + Encoding.UTF8.GetBytes(credentials.CertificateCredentials.PrivateKey))); + await JS.InvokeVoidAsync("downloadFileFromStream", "key", stream); + } + + void Cancel() => MudDialog.Cancel(); } diff --git a/src/AzureIoTHub.Portal.Client/Pages/EdgeDevices/ConnectionStringDialog.razor b/src/AzureIoTHub.Portal.Client/Pages/EdgeDevices/ConnectionStringDialog.razor index dc3e2b363..668e82a70 100644 --- a/src/AzureIoTHub.Portal.Client/Pages/EdgeDevices/ConnectionStringDialog.razor +++ b/src/AzureIoTHub.Portal.Client/Pages/EdgeDevices/ConnectionStringDialog.razor @@ -1,6 +1,7 @@ -@using AzureIoTHub.Portal.Models.v10 -@using AzureIoTHub.Portal.Shared.Constants; - +@using AzureIoTHub.Portal.Shared.Models.v10 +@using AzureIoTHub.Portal.Models.v10 +@using System.Text +@inject IJSRuntime JS @inject ClipboardService ClipboardService @inject IEdgeDeviceClientService EdgeDeviceClientService @inject PortalSettings Portal @@ -10,52 +11,75 @@ - @if (Portal.CloudProvider.Equals(CloudProviders.Azure)) + @if (Credentials.AuthenticationMode != null && AuthenticationMode.SymmetricKey.Equals(Credentials.AuthenticationMode)) { - - Service Endpoint - - - - Registration Id - - - - Scope Id - - - - Symmetric Key - - + @if (Credentials.SymmetricCredentials != null) + { + + Service Endpoint + + + + Registration Id + + + + Scope Id + + + + Symmetric Key + + + } } - else if (Portal.CloudProvider.Equals(CloudProviders.AWS)) + else { + @if (Credentials.CertificateCredentials != null) + { + + Certificate Pem + + + + Public Key + + + + Private Key + + + } + +
+ OR +
+ @if (string.IsNullOrEmpty(EnrollementScriptCommand)) { Quick connect -
+
Quiclky connect your Edge device on the platform by executing one command. -
+
Get the magic command } else { -
+
Operating system - Debian 11 (Bulleseye) + Debian 11 (Bulleseye) -
+
- Copy this command line above and paste it into the device prompt.
+ Copy this command line above and paste it into the device prompt.
Note that you should have administrative rights on the device to execute the command.
-
- +
+ }
} @@ -76,7 +100,7 @@ [Parameter] public string deviceId { get; set; } = default!; - private SymmetricCredentials Credentials = new SymmetricCredentials(); + private DeviceCredentials Credentials = new DeviceCredentials(); public string EnrollementScriptCommand { get; set; } = default!; @@ -103,5 +127,26 @@ EnrollementScriptCommand = $"curl -s {url} | bash"; } + private async Task DownloadPemFile() + { + var stream = new DotNetStreamReference(stream: new MemoryStream( + Encoding.UTF8.GetBytes(Credentials.CertificateCredentials.CertificatePem))); + await JS.InvokeVoidAsync("downloadFileFromStream", "certificate.pem", stream); + } + + private async Task DownloadPublicKeyFile() + { + var stream = new DotNetStreamReference(stream: new MemoryStream( + Encoding.UTF8.GetBytes(Credentials.CertificateCredentials.PublicKey))); + await JS.InvokeVoidAsync("downloadFileFromStream", "key.pub", stream); + } + + private async Task DownloadPrivateKeyFile() + { + var stream = new DotNetStreamReference(stream: new MemoryStream( + Encoding.UTF8.GetBytes(Credentials.CertificateCredentials.PrivateKey))); + await JS.InvokeVoidAsync("downloadFileFromStream", "key", stream); + } + void Close() => MudDialog.Cancel(); } diff --git a/src/AzureIoTHub.Portal.Client/Services/DeviceClientService.cs b/src/AzureIoTHub.Portal.Client/Services/DeviceClientService.cs index 3643232d7..b072f7902 100644 --- a/src/AzureIoTHub.Portal.Client/Services/DeviceClientService.cs +++ b/src/AzureIoTHub.Portal.Client/Services/DeviceClientService.cs @@ -60,9 +60,9 @@ public Task SetDeviceProperties(string deviceId, IList devi return this.http.PostAsJsonAsync($"api/devices/{deviceId}/properties", deviceProperties); } - public Task GetEnrollmentCredentials(string deviceId) + public Task GetEnrollmentCredentials(string deviceId) { - return this.http.GetFromJsonAsync($"api/devices/{deviceId}/credentials")!; + return this.http.GetFromJsonAsync($"api/devices/{deviceId}/credentials")!; } public Task DeleteDevice(string deviceId) diff --git a/src/AzureIoTHub.Portal.Client/Services/EdgeDeviceClientService.cs b/src/AzureIoTHub.Portal.Client/Services/EdgeDeviceClientService.cs index 8fd6146f7..18adca77a 100644 --- a/src/AzureIoTHub.Portal.Client/Services/EdgeDeviceClientService.cs +++ b/src/AzureIoTHub.Portal.Client/Services/EdgeDeviceClientService.cs @@ -44,9 +44,9 @@ public Task DeleteDevice(string deviceId) return this.http.DeleteAsync($"api/edge/devices/{deviceId}"); } - public Task GetEnrollmentCredentials(string deviceId) + public Task GetEnrollmentCredentials(string deviceId) { - return this.http.GetFromJsonAsync($"api/edge/devices/{deviceId}/credentials")!; + return this.http.GetFromJsonAsync($"api/edge/devices/{deviceId}/credentials")!; } public Task GetEnrollmentScriptUrl(string deviceId, string templateName) diff --git a/src/AzureIoTHub.Portal.Client/Services/IDeviceClientService.cs b/src/AzureIoTHub.Portal.Client/Services/IDeviceClientService.cs index 33ea49404..bfb3ff984 100644 --- a/src/AzureIoTHub.Portal.Client/Services/IDeviceClientService.cs +++ b/src/AzureIoTHub.Portal.Client/Services/IDeviceClientService.cs @@ -23,7 +23,7 @@ public interface IDeviceClientService Task SetDeviceProperties(string deviceId, IList deviceProperties); - Task GetEnrollmentCredentials(string deviceId); + Task GetEnrollmentCredentials(string deviceId); Task DeleteDevice(string deviceId); diff --git a/src/AzureIoTHub.Portal.Client/Services/IEdgeDeviceClientService.cs b/src/AzureIoTHub.Portal.Client/Services/IEdgeDeviceClientService.cs index 8167a37dd..c2788a763 100644 --- a/src/AzureIoTHub.Portal.Client/Services/IEdgeDeviceClientService.cs +++ b/src/AzureIoTHub.Portal.Client/Services/IEdgeDeviceClientService.cs @@ -20,7 +20,7 @@ public interface IEdgeDeviceClientService Task DeleteDevice(string deviceId); - Task GetEnrollmentCredentials(string deviceId); + Task GetEnrollmentCredentials(string deviceId); Task GetEnrollmentScriptUrl(string deviceId, string templateName); diff --git a/src/AzureIoTHub.Portal.Infrastructure/Services/AwsExternalDeviceService.cs b/src/AzureIoTHub.Portal.Infrastructure/Services/AwsExternalDeviceService.cs index f695a6f14..5c49acedc 100644 --- a/src/AzureIoTHub.Portal.Infrastructure/Services/AwsExternalDeviceService.cs +++ b/src/AzureIoTHub.Portal.Infrastructure/Services/AwsExternalDeviceService.cs @@ -236,15 +236,15 @@ public Task GetEdgeDevicesCount() throw new NotImplementedException(); } - public async Task GetDeviceCredentials(string deviceId) + public async Task GetDeviceCredentials(string deviceName) { try { - return await GetDeviceCredentialsFromSecretsManager(deviceId); + return await GetDeviceCredentialsFromSecretsManager(deviceName); } catch (Amazon.SecretsManager.Model.ResourceNotFoundException) { - var deviceCredentialsTuple = await GenerateCertificate(deviceId); + var deviceCredentialsTuple = await GenerateCertificate(deviceName); return deviceCredentialsTuple.Item1; } @@ -296,15 +296,16 @@ private async Task CreateDynamicGroupForThingType(string thingTypeName) } } - private async Task> GenerateCertificate(string deviceId) + private async Task> GenerateCertificate(string deviceName) { var response = await this.amazonIoTClient.CreateKeysAndCertificateAsync(true); - _ = await this.amazonIoTClient.AttachThingPrincipalAsync(deviceId, response.CertificateArn); + _ = await this.amazonIoTClient.AttachThingPrincipalAsync(deviceName, response.CertificateArn); - _ = await CreatePrivateKeySecret(deviceId, response.KeyPair.PrivateKey); - _ = await CreatePublicKeySecret(deviceId, response.KeyPair.PublicKey); - _ = await CreateCertificateSecret(deviceId, response.CertificatePem); + _ = await CreatePrivateKeySecret(deviceName, response.KeyPair.PrivateKey); + _ = await CreatePublicKeySecret(deviceName, response.KeyPair.PublicKey); + _ = await CreateCertificateSecret(deviceName, response.CertificatePem); + _ = await AttachCertificateToThing(deviceName, response.CertificateArn); return new Tuple(new DeviceCredentials { @@ -318,45 +319,50 @@ private async Task> GenerateCertificate(string }, response.CertificateArn); } - private async Task CreatePrivateKeySecret(string deviceId, string privateKey) + private async Task AttachCertificateToThing(string deviceName, string certificateArn) + { + return await this.amazonIoTClient.AttachThingPrincipalAsync(deviceName, certificateArn); + } + + private async Task CreatePrivateKeySecret(string deviceName, string privateKey) { var request = new CreateSecretRequest { - Name = deviceId + PrivateKeyKey, - Description = "Private key for the certificate of device " + deviceId, + Name = deviceName + PrivateKeyKey, + Description = "Private key for the certificate of device " + deviceName, SecretString = privateKey }; return await this.amazonSecretsManager.CreateSecretAsync(request); } - private async Task CreatePublicKeySecret(string deviceId, string privateKey) + private async Task CreatePublicKeySecret(string deviceName, string privateKey) { var request = new CreateSecretRequest { - Name = deviceId + PublicKeyKey, - Description = "Public key for the certificate of device " + deviceId, + Name = deviceName + PublicKeyKey, + Description = "Public key for the certificate of device " + deviceName, SecretString = privateKey }; return await this.amazonSecretsManager.CreateSecretAsync(request); } - private async Task CreateCertificateSecret(string deviceId, string certificatePem) + private async Task CreateCertificateSecret(string deviceName, string certificatePem) { var request = new CreateSecretRequest { - Name = deviceId + CertificateKey, - Description = "Certificate for the certificate of device " + deviceId, + Name = deviceName + CertificateKey, + Description = "Certificate for the certificate of device " + deviceName, SecretString = certificatePem }; return await this.amazonSecretsManager.CreateSecretAsync(request); } - private async Task GetDeviceCredentialsFromSecretsManager(string deviceId) + private async Task GetDeviceCredentialsFromSecretsManager(string deviceName) { - var certificate = await GetSecret(deviceId + CertificateKey); - var privateKey = await GetSecret(deviceId + PrivateKeyKey); - var publicKey = await GetSecret(deviceId + PublicKeyKey); + var certificate = await GetSecret(deviceName + CertificateKey); + var privateKey = await GetSecret(deviceName + PrivateKeyKey); + var publicKey = await GetSecret(deviceName + PublicKeyKey); return new DeviceCredentials { AuthenticationMode = AuthenticationMode.Certificate, diff --git a/src/AzureIoTHub.Portal.Infrastructure/Services/DeviceServiceBase.cs b/src/AzureIoTHub.Portal.Infrastructure/Services/DeviceServiceBase.cs index 5d482a3ed..d625f63a4 100644 --- a/src/AzureIoTHub.Portal.Infrastructure/Services/DeviceServiceBase.cs +++ b/src/AzureIoTHub.Portal.Infrastructure/Services/DeviceServiceBase.cs @@ -200,9 +200,9 @@ public virtual async Task DeleteDevice(string deviceId) protected abstract Task DeleteDeviceInDatabase(string deviceId); - public virtual Task GetCredentials(string deviceId) + public virtual Task GetCredentials(TDto device) { - return this.externalDevicesService.GetDeviceCredentials(deviceId); + return this.externalDevicesService.GetDeviceCredentials(device.DeviceName); } public abstract Task> GetDeviceTelemetry(string deviceId); diff --git a/src/AzureIoTHub.Portal.Server/Controllers/v1.0/DevicesControllerBase.cs b/src/AzureIoTHub.Portal.Server/Controllers/v1.0/DevicesControllerBase.cs index a21808109..59e52fb53 100644 --- a/src/AzureIoTHub.Portal.Server/Controllers/v1.0/DevicesControllerBase.cs +++ b/src/AzureIoTHub.Portal.Server/Controllers/v1.0/DevicesControllerBase.cs @@ -172,7 +172,14 @@ public virtual Task> GetAvailableLabels() /// The device identifier. public virtual async Task> GetCredentials(string deviceID) { - return Ok(await this.deviceService.GetCredentials(deviceID)); + var device = await this.deviceService.GetDevice(deviceID); + + if (device == null) + { + return NotFound(); + } + + return Ok(await this.deviceService.GetCredentials(device)); } private static Dictionary GetTagsFromQueryString(IQueryCollection queryCollection) diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/Devices/ConnectionStringDialogTests.cs b/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/Devices/ConnectionStringDialogTests.cs index 2d8a8c727..17010d194 100644 --- a/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/Devices/ConnectionStringDialogTests.cs +++ b/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/Devices/ConnectionStringDialogTests.cs @@ -9,7 +9,6 @@ namespace AzureIoTHub.Portal.Tests.Unit.Client.Pages.Devices using AzureIoTHub.Portal.Client.Models; using AzureIoTHub.Portal.Client.Pages.Devices; using AzureIoTHub.Portal.Client.Services; - using Models.v10; using UnitTests.Bases; using Bunit; using FluentAssertions; @@ -17,6 +16,7 @@ namespace AzureIoTHub.Portal.Tests.Unit.Client.Pages.Devices using Moq; using MudBlazor; using NUnit.Framework; + using Portal.Shared.Models.v10; [TestFixture] public class ConnectionStringDialogTests : BlazorUnitTest @@ -40,7 +40,7 @@ public async Task ConnectionStringDialogMustBeRenderedOnShow() var deviceId = Guid.NewGuid().ToString(); _ = this.mockDeviceClientService.Setup(service => service.GetEnrollmentCredentials(deviceId)) - .ReturnsAsync(new SymmetricCredentials()); + .ReturnsAsync(new DeviceCredentials()); var cut = RenderComponent(); var service = Services.GetService() as DialogService; diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/EdgeDevices/ConnectionStringDialogTests.cs b/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/EdgeDevices/ConnectionStringDialogTests.cs index 145b89675..8b958b7c5 100644 --- a/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/EdgeDevices/ConnectionStringDialogTests.cs +++ b/src/AzureIoTHub.Portal.Tests.Unit/Client/Pages/EdgeDevices/ConnectionStringDialogTests.cs @@ -18,6 +18,8 @@ namespace AzureIoTHub.Portal.Tests.Unit.Client.Pages.EdgeDevices using MudBlazor; using NUnit.Framework; using AzureIoTHub.Portal.Shared.Constants; + using AzureIoTHub.Portal.Shared.Models.v10; + using AutoFixture; [TestFixture] public class ConnectionStringDialogTests : BlazorUnitTest @@ -45,7 +47,7 @@ public async Task ConnectionStringDialogMustShowEnrollmentCredentials() var deviceId = Guid.NewGuid().ToString(); _ = this.mockEdgeDeviceClientService.Setup(service => service.GetEnrollmentCredentials(deviceId)) - .ReturnsAsync(new SymmetricCredentials()); + .ReturnsAsync(Fixture.Create()); var cut = RenderComponent(); @@ -101,7 +103,7 @@ public async Task ConnectionStringDialogMustBeClosedOnClickOnOk() var deviceId = Guid.NewGuid().ToString(); _ = this.mockEdgeDeviceClientService.Setup(service => service.GetEnrollmentCredentials(deviceId)) - .ReturnsAsync(new SymmetricCredentials()); + .ReturnsAsync(new DeviceCredentials()); var cut = RenderComponent(); diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Client/Services/DeviceClientServiceTests.cs b/src/AzureIoTHub.Portal.Tests.Unit/Client/Services/DeviceClientServiceTests.cs index 5948eae2e..fd0112474 100644 --- a/src/AzureIoTHub.Portal.Tests.Unit/Client/Services/DeviceClientServiceTests.cs +++ b/src/AzureIoTHub.Portal.Tests.Unit/Client/Services/DeviceClientServiceTests.cs @@ -183,7 +183,7 @@ public async Task GetEnrollmentCredentialsShouldReturnEnrollmentCredentials() { // Arrange var deviceId = Fixture.Create(); - var expectedEnrollmentCredentials = Fixture.Create(); + var expectedEnrollmentCredentials = Fixture.Create(); _ = MockHttpClient.When(HttpMethod.Get, $"/api/devices/{deviceId}/credentials") .RespondJson(expectedEnrollmentCredentials); diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Client/Services/EdgeDeviceClientServiceTests.cs b/src/AzureIoTHub.Portal.Tests.Unit/Client/Services/EdgeDeviceClientServiceTests.cs index d40e15258..8e8789938 100644 --- a/src/AzureIoTHub.Portal.Tests.Unit/Client/Services/EdgeDeviceClientServiceTests.cs +++ b/src/AzureIoTHub.Portal.Tests.Unit/Client/Services/EdgeDeviceClientServiceTests.cs @@ -160,7 +160,7 @@ public async Task GetEnrollmentCredentialsShouldReturnEnrollmentCredentials() // Arrange var deviceId = Fixture.Create(); - var expectedEnrollmentCredentials = Fixture.Create(); + var expectedEnrollmentCredentials = Fixture.Create(); _ = MockHttpClient.When(HttpMethod.Get, $"/api/edge/devices/{deviceId}/credentials") .RespondJson(expectedEnrollmentCredentials); diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Server/Controllers/v1.0/DevicesControllerTests.cs b/src/AzureIoTHub.Portal.Tests.Unit/Server/Controllers/v1.0/DevicesControllerTests.cs index b1904025b..19b711f6c 100644 --- a/src/AzureIoTHub.Portal.Tests.Unit/Server/Controllers/v1.0/DevicesControllerTests.cs +++ b/src/AzureIoTHub.Portal.Tests.Unit/Server/Controllers/v1.0/DevicesControllerTests.cs @@ -249,6 +249,10 @@ public async Task GetEnrollmentCredentialsShouldReturnEnrollmentCredentials() // Arrange var devicesController = CreateDevicesController(); const string deviceId = "aaa"; + var deviceDetails = new DeviceDetails + { + DeviceName = "aaa" + }; var expectedEnrollmentCredentials = new DeviceCredentials { @@ -260,11 +264,13 @@ public async Task GetEnrollmentCredentialsShouldReturnEnrollmentCredentials() } }; - _ = this.mockDeviceService.Setup(service => service.GetCredentials(deviceId)) + _ = this.mockDeviceService.Setup(service => service.GetCredentials(deviceDetails)) .ReturnsAsync(expectedEnrollmentCredentials); + _ = this.mockDeviceService.Setup(service => service.GetDevice(deviceDetails.DeviceID)) + .ReturnsAsync(deviceDetails); // Act - var response = await devicesController.GetCredentials(deviceId); + var response = await devicesController.GetCredentials(deviceDetails.DeviceID); // Assert Assert.IsNotNull(response); diff --git a/src/AzureIoTHub.Portal.Tests.Unit/Server/Services/DeviceServiceTests.cs b/src/AzureIoTHub.Portal.Tests.Unit/Server/Services/DeviceServiceTests.cs index 2084168d9..0274cb1c5 100644 --- a/src/AzureIoTHub.Portal.Tests.Unit/Server/Services/DeviceServiceTests.cs +++ b/src/AzureIoTHub.Portal.Tests.Unit/Server/Services/DeviceServiceTests.cs @@ -552,11 +552,11 @@ public async Task GetCredentials_DeviceExist_ReturnsEnrollmentCredentials() var expectedEnrollmentCredentials = Fixture.Create(); - _ = this.mockExternalDevicesService.Setup(service => service.GetDeviceCredentials(deviceDto.DeviceID)) + _ = this.mockExternalDevicesService.Setup(service => service.GetDeviceCredentials(deviceDto.DeviceName)) .ReturnsAsync(expectedEnrollmentCredentials); // Act - var result = await this.deviceService.GetCredentials(deviceDto.DeviceID); + var result = await this.deviceService.GetCredentials(deviceDto); // Assert _ = result.Should().BeEquivalentTo(expectedEnrollmentCredentials);