Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ buildd.err
buildd.log
buildd.prf
buildd.wrn
*.binlog
data/
objd/
public/lock
Expand Down
2 changes: 1 addition & 1 deletion src/Build.Common.StandardAndLegacy.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</PropertyGroup>

<PropertyGroup Condition="'$(TargetFrameworks)' == ''">
<TargetFrameworks Condition="'$(OutputType)' == 'Exe'">net5.0;net48;net462</TargetFrameworks>
<TargetFrameworks Condition="'$(OutputType)' == 'Exe'">net6.0;net48;net462</TargetFrameworks>
<TargetFrameworks Condition="'$(OutputType)' != 'Exe'">netstandard2.0;net48;net462</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
Expand Down
12 changes: 9 additions & 3 deletions src/Build.Shared.props
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
<Project>
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
</PropertyGroup>

<!-- msbuild properties shared for dotnetCore and .NET classic projects: -->
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<PackageVersion_AppInsights>2.9.1</PackageVersion_AppInsights>
<PackageVersion_AppInsights>2.10.0</PackageVersion_AppInsights>
<PackageVersion_Adal>3.19.8</PackageVersion_Adal>
<PackageVersion_MSAL>4.35.1</PackageVersion_MSAL>
<PackageVersion_CdsSdk>4.7.9489-v9.0-master</PackageVersion_CdsSdk>
<PackageVersion_CrmProxy>4.7.9409-v9.0-master</PackageVersion_CrmProxy>
<PackageVersion_CDSServerNuget>4.6.6061-weekly-2108.5</PackageVersion_CDSServerNuget>
<PackageVersion_CdsSdkProxy>4.7.6346-master</PackageVersion_CdsSdkProxy>
<PackageVersion_Newtonsoft>11.0.2</PackageVersion_Newtonsoft>
<PackageVersion_Newtonsoft>13.0.1</PackageVersion_Newtonsoft>
<PackageVersion_RestClientRuntime>2.3.20</PackageVersion_RestClientRuntime>
<PackageVersion_XrmSdk>9.0.2.42</PackageVersion_XrmSdk>
<PackageVersion_Dep_OutlookXrmSdk>9.0.2.34</PackageVersion_Dep_OutlookXrmSdk>
Expand All @@ -19,9 +23,11 @@
<PackageVersion_Microsoft_Extensions>3.1.8</PackageVersion_Microsoft_Extensions>

<!-- Test: -->
<PackageVersion_MicrosoftNETTestSdk>17.2.0</PackageVersion_MicrosoftNETTestSdk>
<PackageVersion_MSTest>2.2.10</PackageVersion_MSTest>
<PackageVersion_Moq>4.16.0</PackageVersion_Moq>
<PackageVersion_XUnit>2.4.1</PackageVersion_XUnit>
<PackageVersion_XUnitRunner>2.4.3</PackageVersion_XUnitRunner>
<PackageVersion_XUnitRunnerVS>2.4.5</PackageVersion_XUnitRunnerVS>
<PackageVersion_FluentAssertions>5.10.3</PackageVersion_FluentAssertions>

<!-- Assembly attributes are set by cake build. We need to disable autogeneration by msbuild -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Auth
{
internal class MSALHttpRetryHandlerHelper : DelegatingHandler
{
private readonly int MaxRetryCount = ClientServiceProviders.Instance.GetService<IOptions<ConfigurationOptions>>().Value.MsalRetryCount;
private readonly int MaxRetryCount = ClientServiceProviders.Instance.GetService<IOptions<ConfigurationOptions>>().Value.MSALRetryCount;

/// <summary>
/// Handel Failure and retry
Expand Down
40 changes: 19 additions & 21 deletions src/GeneralTools/DataverseClient/Client/ConnectionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1320,20 +1320,20 @@ private async Task<IOrganizationService> InitServiceAsync()
return null;
}

// Do a WHO AM I request to make sure the connection is good.
if (!UseExternalConnection)
{
Guid guIntialTrackingID = Guid.NewGuid();
logEntry.Log(string.Format("Beginning Validation of Dataverse Connection. RequestID: {0}", guIntialTrackingID.ToString()));
dtQueryTimer.Restart();
user = await GetWhoAmIDetails(dvService, guIntialTrackingID).ConfigureAwait(false);
dtQueryTimer.Stop();
logEntry.Log(string.Format(CultureInfo.InvariantCulture, "Validation of Dataverse Connection Complete, total duration: {0}", dtQueryTimer.Elapsed.ToString()));
}
else
{
logEntry.Log("External Dataverse Connection Provided, Skipping Validation");
}
//// Do a WHO AM I request to make sure the connection is good.
//if (!UseExternalConnection)
//{
// Guid guIntialTrackingID = Guid.NewGuid();
// logEntry.Log(string.Format("Beginning Validation of Dataverse Connection. RequestID: {0}", guIntialTrackingID.ToString()));
// dtQueryTimer.Restart();
// user = await GetWhoAmIDetails(dvService, guIntialTrackingID).ConfigureAwait(false);
// dtQueryTimer.Stop();
// logEntry.Log(string.Format(CultureInfo.InvariantCulture, "Validation of Dataverse Connection Complete, total duration: {0}", dtQueryTimer.Elapsed.ToString()));
//}
//else
//{
// logEntry.Log("External Dataverse Connection Provided, Skipping Validation");
//}

return (IOrganizationService)dvService;

Expand Down Expand Up @@ -1528,11 +1528,11 @@ private async Task RefreshInstanceDetails(IOrganizationService dvService, Uri ur

var request = new RetrieveCurrentOrganizationRequest() { AccessType = 0, RequestId = trackingID };
RetrieveCurrentOrganizationResponse resp;
logEntry.Log(string.Format(CultureInfo.InvariantCulture, "Execute Command - RetrieveCurrentOrganizationRequest : RequestId={0}", dtQueryTimer.Elapsed.ToString()));
logEntry.Log(string.Format(CultureInfo.InvariantCulture, "Execute Command - RetrieveCurrentOrganizationRequest : RequestId={0}", trackingID));
if (_configuration.Value.UseWebApiLoginFlow)
{
OrganizationResponse orgResp = await Command_WebAPIProcess_ExecuteAsync(
request, null, false, null, Guid.Empty, false, _configuration.Value.MaxRetryCount, _configuration.Value.RetryPauseTime, new CancellationToken(), uriOfInstance).ConfigureAwait(false);
request, null, false, null, Guid.Empty, false, _configuration.Value.MaxRetryCount, _configuration.Value.RetryPauseTime, new CancellationToken(), uriOfInstance, true).ConfigureAwait(false);
try
{
resp = (RetrieveCurrentOrganizationResponse)orgResp;
Expand Down Expand Up @@ -1643,7 +1643,7 @@ internal async Task<WhoAmIResponse> GetWhoAmIDetails(IOrganizationService dvServ
if (_configuration.Value.UseWebApiLoginFlow)
{
resp = (WhoAmIResponse)(await Command_WebAPIProcess_ExecuteAsync(
req, null, false, null, Guid.Empty, false, _configuration.Value.MaxRetryCount, _configuration.Value.RetryPauseTime, new CancellationToken()).ConfigureAwait(false));
req, null, false, null, Guid.Empty, false, _configuration.Value.MaxRetryCount, _configuration.Value.RetryPauseTime, new CancellationToken(), inLoginFlow:true).ConfigureAwait(false));
}
else
{
Expand Down Expand Up @@ -1738,11 +1738,11 @@ internal void SetClonedProperties(ServiceClient sourceClient)
#region WebAPI Interface Utilities

internal async Task<OrganizationResponse> Command_WebAPIProcess_ExecuteAsync(OrganizationRequest req, string logMessageTag, bool bypassPluginExecution,
MetadataUtility metadataUtlity, Guid callerId, bool disableConnectionLocking, int maxRetryCount, TimeSpan retryPauseTime, CancellationToken cancellationToken, Uri uriOfInstance = null)
MetadataUtility metadataUtlity, Guid callerId, bool disableConnectionLocking, int maxRetryCount, TimeSpan retryPauseTime, CancellationToken cancellationToken, Uri uriOfInstance = null, bool inLoginFlow = false)
{
cancellationToken.ThrowIfCancellationRequested();

if (!Utilities.IsRequestValidForTranslationToWebAPI(req)) // THIS WILL GET REMOVED AT SOME POINT, TEMP FOR TRANSTION //TODO:REMOVE ON COMPELTE
if (!Utilities.IsRequestValidForTranslationToWebAPI(req , inLoginFlow)) // THIS WILL GET REMOVED AT SOME POINT, TEMP FOR TRANSTION //TODO:REMOVE ON COMPELTE
{
logEntry.Log("Execute Organization Request failed, WebAPI is only supported for limited type of messages at this time.", TraceEventType.Error);
return null;
Expand Down Expand Up @@ -1927,7 +1927,6 @@ internal async Task<OrganizationResponse> Command_WebAPIProcess_ExecuteAsync(Org
{
postUri = $"{postUri}?{addedQueryParams}";
}

// Execute request
var sResp = await Command_WebExecuteAsync(postUri, bodyOfRequest, methodToExecute, headers, "application/json", logMessageTag, callerId, disableConnectionLocking, maxRetryCount, retryPauseTime, uriOfInstance, cancellationToken: cancellationToken).ConfigureAwait(false);
if (sResp != null && sResp.IsSuccessStatusCode)
Expand Down Expand Up @@ -1962,7 +1961,6 @@ internal async Task<OrganizationResponse> Command_WebAPIProcess_ExecuteAsync(Org
else
{
var json = await sResp.Content.ReadAsStringAsync().ConfigureAwait(false);

if (_knownTypesFactory.TryCreate($"{req.RequestName}Response", out var response, json))
{
OrganizationResponse resp = (OrganizationResponse)response;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ internal sealed class DataverseTraceLogger : TraceLoggerBase
// Internal connection of exceptions since last clear.
private List<Exception> _ActiveExceptionsList;

private ILogger _logger;
internal ILogger _logger;

#region Properties
/// <summary>
Expand Down Expand Up @@ -318,9 +318,9 @@ public void LogFailure(OrganizationRequest req, Guid requestTrackingId, Guid? se

internal string GetFormatedRequestSessionIdString( Guid requestId, Guid? sessionId )
{
return string.Format("RequestID={0} {1}",
return string.Format("RequestID={0}{1}",
requestId.ToString(),
sessionId.HasValue && sessionId.Value != Guid.Empty ? $": SessionID={sessionId.Value.ToString()} : " : "");
sessionId.HasValue && sessionId.Value != Guid.Empty ? $" : SessionID={sessionId.Value.ToString()} : " : "");
}

/// <summary>
Expand Down
8 changes: 7 additions & 1 deletion src/GeneralTools/DataverseClient/Client/ServiceClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ internal WhoAmIResponse SystemUser
return _connectionSvc.CurrentUser;
else
{
WhoAmIResponse resp = _connectionSvc.GetWhoAmIDetails(this).ConfigureAwait(false).GetAwaiter().GetResult();
WhoAmIResponse resp = Task.Run(async () => await _connectionSvc.GetWhoAmIDetails(this).ConfigureAwait(false)).Result;
_connectionSvc.CurrentUser = resp;
return resp;
}
Expand Down Expand Up @@ -1056,6 +1056,11 @@ internal void ConnectToService(string connectionString, ILogger logger = null)
MakeSecureString(password), domainname, string.Empty, string.Empty, useSsl, parsedConnStr.UseUniqueConnectionInstance, null, instanceUrl: parsedConnStr.SkipDiscovery ? parsedConnStr.ServiceUri : null, externalLogger: logger);

break;
case AuthenticationType.ExternalTokenManagement:
CreateServiceConnection(null, parsedConnStr.AuthenticationType, string.Empty, string.Empty, string.Empty, null,
string.Empty, null, string.Empty, string.Empty, string.Empty, true, parsedConnStr.UseUniqueConnectionInstance, null,
string.Empty, null, PromptBehavior.Never, null, string.Empty, StoreName.My, null, parsedConnStr.ServiceUri, externalLogger: logger);
break;
}
}

Expand Down Expand Up @@ -1369,6 +1374,7 @@ public ServiceClient Clone(System.Reflection.Assembly strongTypeAsm, ILogger log
{
// Get Current Access Token.
// This will get the current access token
if (logger == null) logger = _logEntry._logger;
proxy.HeaderToken = this.CurrentAccessToken;
var SvcClient = new ServiceClient(proxy, true, _connectionSvc.AuthenticationTypeInUse, _connectionSvc?.OrganizationVersion, logger: logger);
SvcClient._connectionSvc.SetClonedProperties(this);
Expand Down
8 changes: 6 additions & 2 deletions src/GeneralTools/DataverseClient/Client/Utils/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -264,11 +264,15 @@ public static bool IsValidOnlineHost(Uri hostUri)
/// This is a temp method to support the staged transition to the webAPI and will be removed or reintegrated with the overall pipeline at some point in the future.
/// </summary>
/// <param name="req"></param>
/// <param name="inLoginFlow"></param>
/// <returns></returns>
internal static bool IsRequestValidForTranslationToWebAPI(OrganizationRequest req)
internal static bool IsRequestValidForTranslationToWebAPI(OrganizationRequest req, bool inLoginFlow = false)
{
bool useWebApi = ClientServiceProviders.Instance.GetService<IOptions<ConfigurationOptions>>().Value.UseWebApi;
bool useWebApiForLogin = ClientServiceProviders.Instance.GetService<IOptions<ConfigurationOptions>>().Value.UseWebApiLoginFlow;
bool useWebApiForLogin = false;
if (inLoginFlow)
useWebApiForLogin = ClientServiceProviders.Instance.GetService<IOptions<ConfigurationOptions>>().Value.UseWebApiLoginFlow;

switch (req.RequestName.ToLowerInvariant())
{
case "create":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
<Import Project="..\..\..\..\Build.Common.core.props" />

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="5.10.3" />
<PackageReference Include="FluentAssertions" Version="$(PackageVersion_FluentAssertions)" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.8" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.8" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.8" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(PackageVersion_MicrosoftNETTestSdk)" />
<PackageReference Include="Moq" Version="$(PackageVersion_Moq)" />
<PackageReference Include="xunit" Version="$(PackageVersion_XUnit)" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(PackageVersion_XUnit)" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(PackageVersion_XUnitRunnerVS)" />
<PackageReference Include="coverlet.collector" Version="1.0.1" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,50 @@ public void ConnectUsingServiceIdentity_ClientSecret_Consetup()
ValidateConnection(client);
}

[SkippableConnectionTest]
[Trait("Category", "Live Connect Required")]
public void ConnectUsingServiceIdentity_ClientSecret_ExternalAuth_CtorV1()
{
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
var Conn_Url = System.Environment.GetEnvironmentVariable("XUNITCONNTESTURI");

// Connection params.
var client = new ServiceClient(new Uri(Conn_Url), testSupport.GetS2SAccessTokenForRequest , true, Ilogger);
Assert.True(client.IsReady, "Failed to Create Connection via Constructor");

// Validate connection
ValidateConnection(client , usingExternalAuth:true);
}

[SkippableConnectionTest]
[Trait("Category", "Live Connect Required")]
public void ConnectUsingServiceIdentity_ClientSecret_ExternalAuth_Consetup()
{
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;

ConnectionOptions connectionOptions = new ConnectionOptions()
{
AccessTokenProviderFunctionAsync = testSupport.GetS2SAccessTokenForRequest,
ServiceUri = new Uri(System.Environment.GetEnvironmentVariable("XUNITCONNTESTURI")),
Logger = Ilogger
};

// Connection params.
var client = new ServiceClient(connectionOptions, deferConnection: true);
Assert.NotNull(client);
Assert.False(client.IsReady, "Client is showing True on Deferred Connection.");
Assert.True(client.Connect(), "Connection was not activated");
Assert.True(client.IsReady, "Failed to Create Connection via Constructor");

// Validate connection
ValidateConnection(client , usingExternalAuth:true);

// test clone
var clientClone = client.Clone();
ValidateConnection(clientClone, usingExternalAuth: true);
}


/// <summary>
/// This Tests connection for UID/PW via connection string - direct connect.
/// </summary>
Expand Down Expand Up @@ -977,9 +1021,10 @@ public void ConnectUsingUserIdentity_UIDPW_ConSetup()

#region connectionValidationHelper

private void ValidateConnection(ServiceClient client)
private void ValidateConnection(ServiceClient client , bool usingExternalAuth = false)
{
client._connectionSvc.AuthContext.Should().NotBeNull();
if (!usingExternalAuth)
client._connectionSvc.AuthContext.Should().NotBeNull();

// Validate it
var rslt = client.Execute(new WhoAmIRequest());
Expand Down
Loading