diff --git a/src/Build.Common.StandardAndLegacy.props b/src/Build.Common.StandardAndLegacy.props index a38f359..1b97df5 100644 --- a/src/Build.Common.StandardAndLegacy.props +++ b/src/Build.Common.StandardAndLegacy.props @@ -4,7 +4,7 @@ - net6.0;net48;net462 + net8.0;net48;net462 netstandard2.0;net48;net462 false diff --git a/src/Build.Common.core.props b/src/Build.Common.core.props index 22cc767..1878754 100644 --- a/src/Build.Common.core.props +++ b/src/Build.Common.core.props @@ -5,7 +5,7 @@ - net462;net472;net48;netstandard2.0;net6.0;net8.0 + net462;net472;net48;netstandard2.0;net8.0 false NU5104 diff --git a/src/GeneralTools/DataverseClient/Client/Auth/AuthProcessor.cs b/src/GeneralTools/DataverseClient/Client/Auth/AuthProcessor.cs index 15dcb51..ff3a623 100644 --- a/src/GeneralTools/DataverseClient/Client/Auth/AuthProcessor.cs +++ b/src/GeneralTools/DataverseClient/Client/Auth/AuthProcessor.cs @@ -152,7 +152,7 @@ internal async static Task ExecuteAuthenticateServ if (userCert != null) { logSink.Log("Initial ObtainAccessToken - CERT", TraceEventType.Verbose); - cApp = cAppBuilder.WithCertificate(userCert).Build(); + cApp = cAppBuilder.WithCertificate(userCert, true).Build(); memoryBackedTokenCache.Initialize(cApp.AppTokenCache); _authenticationResult = await ObtainAccessTokenAsync(cApp, Scopes, logSink).ConfigureAwait(false); } diff --git a/src/GeneralTools/DataverseClient/Client/Auth/AuthorityResolver.cs b/src/GeneralTools/DataverseClient/Client/Auth/AuthorityResolver.cs index f66f10e..61ef572 100644 --- a/src/GeneralTools/DataverseClient/Client/Auth/AuthorityResolver.cs +++ b/src/GeneralTools/DataverseClient/Client/Auth/AuthorityResolver.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using System.Net; using System.Net.Http; using System.Threading.Tasks; @@ -28,6 +27,11 @@ public sealed class AuthenticationDetails /// OAuth resource to request authentication for. /// public Uri Resource { get; internal set; } + + /// + /// Error message if probing failed. + /// + public string ErrorMessage { get; internal set; } = string.Empty; } /// @@ -57,7 +61,7 @@ public AuthorityResolver(HttpClient httpClient, Action l } /// - /// Attemtps to solicit a WWW-Authenticate reply using an unauthenticated GET call to the given endpoint. + /// Attempts to solicit a WWW-Authenticate reply using an unauthenticated GET call to the given endpoint. /// Parses returned header for details /// /// endpoint to challenge for authority and resource @@ -81,7 +85,9 @@ public async Task ProbeForExpectedAuthentication(Uri endp { errDetails = $"; details: {wex.Message} ({wex.Status})"; } - LogError($"Failed to get response from: {endpoint}; error: {ex.Message}{errDetails}"); + + details.ErrorMessage = $"Failed to get response from: {endpoint}; error: {ex.Message}{errDetails}"; + LogError(details.ErrorMessage); return details; } @@ -89,7 +95,8 @@ public async Task ProbeForExpectedAuthentication(Uri endp if (response.StatusCode == HttpStatusCode.NotFound || response.StatusCode == HttpStatusCode.BadRequest) { // didn't find endpoint. - LogError($"Failed to get Authority and Resource error. Attempt to Access Endpoint {endpoint} resulted in {response.StatusCode}."); + details.ErrorMessage = $"Failed to get Authority and Resource error. Attempt to Access Endpoint {endpoint} resulted in {response.StatusCode}."; + LogError(details.ErrorMessage); return details; } @@ -97,12 +104,12 @@ public async Task ProbeForExpectedAuthentication(Uri endp { var authenticateHeaders = response.Headers.GetValues(AuthenticateHeader); // need to support OnPrem returning multiple Authentication headers. - foreach (var authenticateHeaderraw in authenticateHeaders) + foreach (var authenticateHeaderRaw in authenticateHeaders) { if (details.Success) break; - string authenticateHeader = authenticateHeaderraw.Trim(); + string authenticateHeader = authenticateHeaderRaw.Trim(); // This also checks for cases like "BearerXXXX authorization_uri=...." and "Bearer" and "Bearer " if (!authenticateHeader.StartsWith(Bearer, StringComparison.OrdinalIgnoreCase) @@ -112,7 +119,8 @@ public async Task ProbeForExpectedAuthentication(Uri endp if (isOnPrem) continue; - LogError($"Malformed 'Bearer' format: {authenticateHeader}"); + details.ErrorMessage = $"Malformed 'Bearer' format: {authenticateHeader}"; + LogError(details.ErrorMessage); return details; } @@ -126,7 +134,8 @@ public async Task ProbeForExpectedAuthentication(Uri endp } catch (ArgumentException) { - LogError($"Malformed arguments in '{AuthenticateHeader}: {authenticateHeader}"); + details.ErrorMessage = $"Malformed arguments in '{AuthenticateHeader}: {authenticateHeader}"; + LogError(details.ErrorMessage); return details; } @@ -134,7 +143,8 @@ public async Task ProbeForExpectedAuthentication(Uri endp { if (!authenticateHeaderItems.TryGetValue(AuthorityKey, out var auth)) { - LogError($"Response header from {endpoint} is missing expected key/value for {AuthorityKey}"); + details.ErrorMessage = $"Response header from {endpoint} is missing expected key/value for {AuthorityKey}"; + LogError(details.ErrorMessage); return details; } details.Authority = new Uri( @@ -143,7 +153,8 @@ public async Task ProbeForExpectedAuthentication(Uri endp if (!authenticateHeaderItems.TryGetValue(ResourceKey, out var res)) { - LogError($"Response header from {endpoint} is missing expected key/value for {ResourceKey}"); + details.ErrorMessage = $"Response header from {endpoint} is missing expected key/value for {ResourceKey}"; + LogError(details.ErrorMessage); return details; } details.Resource = new Uri(res); diff --git a/src/GeneralTools/DataverseClient/Client/ServiceClient.cs b/src/GeneralTools/DataverseClient/Client/ServiceClient.cs index b0200ec..ab180a8 100644 --- a/src/GeneralTools/DataverseClient/Client/ServiceClient.cs +++ b/src/GeneralTools/DataverseClient/Client/ServiceClient.cs @@ -1729,6 +1729,7 @@ public async Task ExecuteOrganizationRequestAsync(Organiza internal OrganizationResponse ExecuteOrganizationRequestImpl(OrganizationRequest req, string logMessageTag = "User Defined", bool useWebAPI = false, bool bypassPluginExecution = false) { + _logEntry.ResetLastError(); // Reset Last Error ValidateConnectionLive(); if (req != null) { @@ -1752,6 +1753,7 @@ internal OrganizationResponse ExecuteOrganizationRequestImpl(OrganizationRequest private async Task ExecuteOrganizationRequestAsyncImpl(OrganizationRequest req, CancellationToken cancellationToken, string logMessageTag = "User Defined", bool useWebAPI = false, bool bypassPluginExecution = false) { + _logEntry.ResetLastError(); // Reset Last Error ValidateConnectionLive(); cancellationToken.ThrowIfCancellationRequested(); if (req != null) diff --git a/src/GeneralTools/DataverseClient/Extensions/Microsoft.PowerPlatform.Dataverse.Client.AzAuth/AzAuth.cs b/src/GeneralTools/DataverseClient/Extensions/Microsoft.PowerPlatform.Dataverse.Client.AzAuth/AzAuth.cs index 72f3e17..ce0b8f7 100644 --- a/src/GeneralTools/DataverseClient/Extensions/Microsoft.PowerPlatform.Dataverse.Client.AzAuth/AzAuth.cs +++ b/src/GeneralTools/DataverseClient/Extensions/Microsoft.PowerPlatform.Dataverse.Client.AzAuth/AzAuth.cs @@ -1,6 +1,7 @@ using Azure.Core; using Azure.Identity; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.PowerPlatform.Dataverse.Client.Model; using System; using System.Collections.Generic; @@ -81,7 +82,7 @@ public AzAuth(bool autoResolveAuthorityAndTenant, DefaultAzureCredentialOptions { _credentialOptions = credentialOptions; _autoResolveAuthorityAndTenant = autoResolveAuthorityAndTenant; - _logger = logger; + _logger = logger ?? NullLogger.Instance; } /// diff --git a/src/GeneralTools/DataverseClient/Extensions/Microsoft.PowerPlatform.Dataverse.Client.AzAuth/AzPipelineFederatedIdentityAuth.cs b/src/GeneralTools/DataverseClient/Extensions/Microsoft.PowerPlatform.Dataverse.Client.AzAuth/AzPipelineFederatedIdentityAuth.cs index 69eaf0a..d509370 100644 --- a/src/GeneralTools/DataverseClient/Extensions/Microsoft.PowerPlatform.Dataverse.Client.AzAuth/AzPipelineFederatedIdentityAuth.cs +++ b/src/GeneralTools/DataverseClient/Extensions/Microsoft.PowerPlatform.Dataverse.Client.AzAuth/AzPipelineFederatedIdentityAuth.cs @@ -6,6 +6,7 @@ using Microsoft.PowerPlatform.Dataverse.Client.Model; using System.Diagnostics; using System.Threading.Tasks; +using Microsoft.Extensions.Logging.Abstractions; namespace Microsoft.PowerPlatform.Dataverse.Client { @@ -75,7 +76,7 @@ public AzPipelineFederatedIdentityAuth(string tenantId, string clientId, string _serviceConnectionId = serviceConnectionId; _systemAccessTokenEnvVarName = SystemAccessTokenEnvVarName; _autoResolveAuthorityAndTenant = autoResolveAuthorityAndTenant; - _logger = logger; + _logger = logger ?? NullLogger.Instance; } /// diff --git a/src/GeneralTools/DataverseClient/PowerShell/Microsoft.PowerPlatform.Dataverse.Client.PowerShell/BuildDrop.ps1 b/src/GeneralTools/DataverseClient/PowerShell/Microsoft.PowerPlatform.Dataverse.Client.PowerShell/BuildDrop.ps1 index 851b3ca..bab9ab8 100644 --- a/src/GeneralTools/DataverseClient/PowerShell/Microsoft.PowerPlatform.Dataverse.Client.PowerShell/BuildDrop.ps1 +++ b/src/GeneralTools/DataverseClient/PowerShell/Microsoft.PowerPlatform.Dataverse.Client.PowerShell/BuildDrop.ps1 @@ -60,7 +60,7 @@ if($RunFromVSBuild -eq $false) } else { - $BinsDirectory = [System.IO.Path]::Combine($BuildSourcesDirectory , "bin" , $BuildConfiguration, "DataverseClient" , "net6.0" ) + $BinsDirectory = [System.IO.Path]::Combine($BuildSourcesDirectory , "bin" , $BuildConfiguration, "DataverseClient" , "net8.0" ) } ## Copying PowerShell Module out only. Write-Host ">>> BINS path is $BinsDirectory" diff --git a/src/GeneralTools/DataverseClient/PowerShell/Microsoft.PowerPlatform.Dataverse.Client.PowerShell/Microsoft.PowerPlatform.Dataverse.Client.PowerShell.csproj b/src/GeneralTools/DataverseClient/PowerShell/Microsoft.PowerPlatform.Dataverse.Client.PowerShell/Microsoft.PowerPlatform.Dataverse.Client.PowerShell.csproj index 449aabe..20ca7d6 100644 --- a/src/GeneralTools/DataverseClient/PowerShell/Microsoft.PowerPlatform.Dataverse.Client.PowerShell/Microsoft.PowerPlatform.Dataverse.Client.PowerShell.csproj +++ b/src/GeneralTools/DataverseClient/PowerShell/Microsoft.PowerPlatform.Dataverse.Client.PowerShell/Microsoft.PowerPlatform.Dataverse.Client.PowerShell.csproj @@ -10,7 +10,7 @@ $(MSBuildProjectDirectory)\ true - net6.0 + net8.0 enable enable diff --git a/src/GeneralTools/DataverseClient/UnitTests/AzDevOps_ServiceConnection_Test/AzDevOps_ServiceConnection_Test.csproj b/src/GeneralTools/DataverseClient/UnitTests/AzDevOps_ServiceConnection_Test/AzDevOps_ServiceConnection_Test.csproj index 17a0140..ae76451 100644 --- a/src/GeneralTools/DataverseClient/UnitTests/AzDevOps_ServiceConnection_Test/AzDevOps_ServiceConnection_Test.csproj +++ b/src/GeneralTools/DataverseClient/UnitTests/AzDevOps_ServiceConnection_Test/AzDevOps_ServiceConnection_Test.csproj @@ -3,7 +3,7 @@ true Exe - net462;net6.0 + net462;net8.0 false DataverseClient-Tests false diff --git a/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/DataverseClient_Core_UnitTests.csproj b/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/DataverseClient_Core_UnitTests.csproj index 9a52dc9..2309849 100644 --- a/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/DataverseClient_Core_UnitTests.csproj +++ b/src/GeneralTools/DataverseClient/UnitTests/CdsClient_Core_Tests/DataverseClient_Core_UnitTests.csproj @@ -3,7 +3,7 @@ true - net462;net6.0 + net462;net8.0 true DataverseClient-Tests false diff --git a/src/GeneralTools/DataverseClient/UnitTests/LivePackageRunUnitTests/LivePackageRunUnitTests.csproj b/src/GeneralTools/DataverseClient/UnitTests/LivePackageRunUnitTests/LivePackageRunUnitTests.csproj index 2975f3e..5e469d8 100644 --- a/src/GeneralTools/DataverseClient/UnitTests/LivePackageRunUnitTests/LivePackageRunUnitTests.csproj +++ b/src/GeneralTools/DataverseClient/UnitTests/LivePackageRunUnitTests/LivePackageRunUnitTests.csproj @@ -4,7 +4,7 @@ true false - net462;net472;net48;net6.0 + net462;net472;net48;net8.0 true DataverseClient-Tests-Package false diff --git a/src/GeneralTools/DataverseClient/UnitTests/LivePackageTestsConsole/LivePackageTestsConsole.csproj b/src/GeneralTools/DataverseClient/UnitTests/LivePackageTestsConsole/LivePackageTestsConsole.csproj index a11f5a0..27bc212 100644 --- a/src/GeneralTools/DataverseClient/UnitTests/LivePackageTestsConsole/LivePackageTestsConsole.csproj +++ b/src/GeneralTools/DataverseClient/UnitTests/LivePackageTestsConsole/LivePackageTestsConsole.csproj @@ -2,7 +2,7 @@ Exe - net462;net6.0 + net462;net8.0 true DataverseClient-Tests-Package false diff --git a/src/GeneralTools/DataverseClient/UnitTests/LiveTestsConsole/LiveTestsConsole.csproj b/src/GeneralTools/DataverseClient/UnitTests/LiveTestsConsole/LiveTestsConsole.csproj index d7c7b2b..f279536 100644 --- a/src/GeneralTools/DataverseClient/UnitTests/LiveTestsConsole/LiveTestsConsole.csproj +++ b/src/GeneralTools/DataverseClient/UnitTests/LiveTestsConsole/LiveTestsConsole.csproj @@ -3,7 +3,7 @@ true Exe - net462;net6.0 + net462;net8.0 true DataverseClient-Tests false diff --git a/src/Packages.props b/src/Packages.props index 488719b..0f7ef12 100644 --- a/src/Packages.props +++ b/src/Packages.props @@ -21,7 +21,7 @@ 6.0.0 1.13.1 4.10.3 - 6.2.0 + 8.1.2 8.0.1 diff --git a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.AzAuth.nuspec b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.AzAuth.nuspec index 576651e..6e2b7f3 100644 --- a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.AzAuth.nuspec +++ b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.AzAuth.nuspec @@ -26,10 +26,6 @@ - - - - @@ -39,8 +35,6 @@ - - diff --git a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.Dynamics.nuspec b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.Dynamics.nuspec index d659037..fd3f387 100644 --- a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.Dynamics.nuspec +++ b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.Dynamics.nuspec @@ -23,11 +23,8 @@ - - - - + @@ -45,8 +42,6 @@ - - diff --git a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.ReleaseNotes.txt b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.ReleaseNotes.txt index 5d18244..11fc07a 100644 --- a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.ReleaseNotes.txt +++ b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.ReleaseNotes.txt @@ -7,6 +7,15 @@ Notice: Note: Only AD on FullFramework, OAuth, Certificate, ClientSecret Authentication types are supported at this time. ++CURRENTRELEASEID++ +Fix for Null ILogger passed to the AzAuth Client Creators causing a fault. Git: https://github.com/microsoft/PowerPlatform-DataverseServiceClient/issues/481 +Fix for Memory Leak in Retrieve Multiple. Git: https://github.com/microsoft/PowerPlatform-DataverseServiceClient/issues/463 +Fix for Memory bloat issue caused by not releasing lastErrorMessage property. +Updated Error messages verbosity when checking for authority from Dataverse during onboard auth phase. +Dependency changes: + System.ServiceModel.Http updated to 8.1.2 + REMOVED .net 6.0 Targets. .net 6.0 is no longer in support. + +1.2.3: RequestId on OrganizationRequest is not overridden by random Guid if present. RequestId from ClientRequestBuilder still takes precedence over OrganizationRequest.RequestId Dependency changes: Microsoft.Identity.Client updated to 4.66.1 diff --git a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.nuspec b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.nuspec index f571d41..de83dc5 100644 --- a/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.nuspec +++ b/src/nuspecs/Microsoft.PowerPlatform.Dataverse.Client.nuspec @@ -51,32 +51,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -124,13 +98,6 @@ - - - - - - -