Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
169b9e4
add/get xrm language packs cmdlets
majakubowski Aug 19, 2018
4d1bac0
minor fixes
majakubowski Aug 19, 2018
992a321
the file rename for consists with the class name
majakubowski Aug 19, 2018
698597a
Merge branch 'master' into langpacks
majakubowski Aug 30, 2018
92df864
Add-XrmLanguagePack async version added
majakubowski Sep 3, 2018
7b82bb9
Merge branch 'langpacks' of https://github.com/majakubowski/xrm-ci-fr…
majakubowski Sep 3, 2018
1f539fa
my test method removed
majakubowski Sep 3, 2018
45bc216
Merge branch 'master' into langpacks
WaelHamze Sep 26, 2018
4f47a19
remove workflow & reset workflow cmdlets
majakubowski Jan 14, 2019
e667ea5
merge
majakubowski Jan 14, 2019
20cf525
Merge branch 'pr/1' into langpacks
majakubowski Jan 14, 2019
79c655d
leaving BPFs during processes deletion
majakubowski Jan 15, 2019
e38385a
refactoring and comments
majakubowski Jan 23, 2019
10cbe47
refactoring and comments
majakubowski Jan 23, 2019
57cef35
null reference exception
majakubowski Jan 24, 2019
4eebbd4
merge
majakubowski Feb 10, 2019
81bd10d
post-merge fixes
majakubowski Feb 10, 2019
ca7d2fa
altering dashboards by name does't work - corrected
majakubowski Mar 4, 2019
ae640ab
Merge branch 'pr/3' into langpacks
majakubowski Mar 4, 2019
9a2c216
including actions in Set-XrmWorkflowState
majakubowski Mar 12, 2019
6b13e2e
fix for connection using oauth / OrganizationWebProxyClient
majakubowski Mar 27, 2019
a7fe817
Merge pull request #4 from WaelHamze/master
majakubowski Mar 27, 2019
2b896c0
setting timeout directly on CrmServiceClient to support both client (…
majakubowski Mar 29, 2019
34c62cf
Merge branch 'langpacks' of https://github.com/majakubowski/xrm-ci-fr…
majakubowski Mar 29, 2019
2962f4c
support for connection strings with client credentials
majakubowski Apr 3, 2019
3a4eec8
unneeded references
majakubowski Apr 3, 2019
901a85c
Merge branch 'pr/5' into langpacks
majakubowski Apr 3, 2019
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.Xrm.Tooling.Connector;

namespace Xrm.Framework.CI.Common
{

public class OAuthClientCredentialsHook : IOverrideAuthHookWrapper
{
private readonly ConcurrentDictionary<Uri, AuthenticationParameters> authenticationParameters =
new ConcurrentDictionary<Uri, AuthenticationParameters>();

private readonly Dictionary<string, AuthenticationResult> authenticationResults =
new Dictionary<string, AuthenticationResult>();

private readonly string clientSecret;
private readonly string clientId;

public OAuthClientCredentialsHook(string clientId, string clientSecret)
{
this.clientId = clientId;
this.clientSecret = clientSecret;
}

public string GetAuthToken(Uri connectedUri)
{
if (!authenticationResults.ContainsKey(connectedUri.Host) ||
authenticationResults[connectedUri.Host].ExpiresOn < DateTime.UtcNow.AddSeconds(30))
{
var parameters = authenticationParameters.GetOrAdd(GetWebApiUri(connectedUri), GetAuthenticationParameters);
authenticationResults[connectedUri.Host] = GetAccessToken(parameters);
}

return authenticationResults[connectedUri.Host].AccessToken;
}

private AuthenticationResult GetAccessToken(AuthenticationParameters authParameters)
{
var authContext = new AuthenticationContext(authParameters.Authority, false);
return authContext.AcquireTokenAsync(authParameters.Resource, new ClientCredential(clientId, clientSecret)).Result;
}

private Uri GetWebApiUri(Uri uri) =>
new Uri(uri.GetLeftPart(UriPartial.Authority) + "/api/data/v9.1/");

private AuthenticationParameters GetAuthenticationParameters(Uri webApiUri) =>
AuthenticationParameters.CreateFromResourceUrlAsync(webApiUri).Result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using Microsoft.Xrm.Tooling.Connector;
using System;

namespace Xrm.Framework.CI.Common
{
internal class ParsedConnectionString
{
public InternalAuthenticationType AuthType { get; private set; }
public bool RequireNewInstance { get; private set; }
public string ClientSecret { get; private set; }
public string ClientId { get; private set; }
public Uri Server { get; private set; }

public ParsedConnectionString(string connectionString)
{
RequireNewInstance = GetRequireNewInstance(connectionString);
ClientSecret = GetClientSecret(connectionString);
ClientId = GetClientId(connectionString);
AuthType = GetAuthType(connectionString);
var server = GetServerString(connectionString);

if (!Uri.IsWellFormedUriString(server, UriKind.Absolute))
{
throw new ArgumentException(nameof(Server));
}

Server = new Uri(server);

if (AuthType != InternalAuthenticationType.S2S)
{
return;
}

if (string.IsNullOrWhiteSpace(ClientId))
{
throw new ArgumentException(nameof(ClientId));
}

if (string.IsNullOrWhiteSpace(ClientSecret))
{
throw new ArgumentException(nameof(ClientSecret));
}
}

private static InternalAuthenticationType GetAuthType(string connectionString) =>
Enum.TryParse(connectionString
.ToDictionary()
.FirstNotNullOrEmpty(nameof(AuthType)), true, out InternalAuthenticationType result) ? result : InternalAuthenticationType.AD;

private static string GetClientId(string connectionString) =>
connectionString
.ToDictionary()
.FirstNotNullOrEmpty(nameof(ClientId));

private static string GetClientSecret(string connectionString) =>
connectionString
.ToDictionary()
.FirstNotNullOrEmpty(nameof(ClientSecret));

private static bool GetRequireNewInstance(string connectionString) =>
bool.TryParse(connectionString
.ToDictionary()
.FirstNotNullOrEmpty(nameof(RequireNewInstance)), out bool result) && result;

private static string GetServerString(string connectionString) =>
connectionString
.ToDictionary()
.FirstNotNullOrEmpty("ServiceUri", "Service Uri", "Url", nameof(Server));

private static Uri GetServer(string connectionString) =>
new Uri(GetServerString(connectionString));
}

internal enum InternalAuthenticationType
{
InvalidConnection = -1,
AD = 0,
Live = 1,
IFD = 2,
Claims = 3,
Office365 = 4,
OAuth = 5,
Certificate = 6,
ExternalTokenManagement = 99, // 0x00000063
S2S
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,13 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AsyncOperationManager.cs" />
<Compile Include="ParsedConnectionString.cs" />
<Compile Include="Data\ConfigDataManager.cs" />
<Compile Include="Entities\Entities.cs" />
<Compile Include="Entities\OptionSets.cs" />
<Compile Include="ImportJobManager.cs" />
<Compile Include="Logging\ILogger.cs" />
<Compile Include="OAuthClientCredentialsHook.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SolutionManagement\SolutionComponentsManager.cs" />
<Compile Include="Workflows\WorkflowFixer.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Tooling.Connector;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

using Xrm.Framework.CI.Common.Logging;

namespace Xrm.Framework.CI.Common
Expand Down Expand Up @@ -69,13 +65,26 @@ private void SetSecurityProtocol()

private IOrganizationService ConnectToCRM(string connectionString, int timeout)
{
CrmServiceClient.MaxConnectionTimeout = TimeSpan.FromMinutes(timeout == 0 ? DefaultTime : timeout);
var parsedConnectionString = new ParsedConnectionString(connectionString);
Logger.LogVerbose("ConnectionString info - AuthType = {0}, Server = {1}", parsedConnectionString.AuthType, parsedConnectionString.Server);
if (parsedConnectionString.AuthType == InternalAuthenticationType.S2S)
{
CrmServiceClient.AuthOverrideHook = new OAuthClientCredentialsHook(parsedConnectionString.ClientId, parsedConnectionString.ClientSecret);
}

CrmServiceClient.MaxConnectionTimeout = TimeSpan.FromMinutes(timeout == 0 ? DefaultTime : timeout);
CrmServiceClient serviceClient = null;
for (int i = 1; i <= ConnectRetryCount; i++)
{
Logger.LogVerbose("Connecting to CRM [attempt {0}]", i);
serviceClient = new CrmServiceClient(connectionString);
if (parsedConnectionString.AuthType == InternalAuthenticationType.S2S)
{
serviceClient = new CrmServiceClient(parsedConnectionString.Server, parsedConnectionString.RequireNewInstance);
}
else
{
serviceClient = new CrmServiceClient(connectionString);
}

if (serviceClient != null && serviceClient.IsReady)
{
Expand Down