diff --git a/.github/workflows/verify-prs-and-commits.yml b/.github/workflows/build.yml similarity index 77% rename from .github/workflows/verify-prs-and-commits.yml rename to .github/workflows/build.yml index 6a223cd..65c9365 100644 --- a/.github/workflows/verify-prs-and-commits.yml +++ b/.github/workflows/build.yml @@ -1,11 +1,13 @@ -name: Verify PRs and commits +name: Build code on: workflow_dispatch: push: - branches: [ "master", "dev" ] + branches: + - master + - 'releases/**' pull_request: - branches: [ "master", "dev" ] + branches: [ "master", "releases/**" ] jobs: call-build: diff --git a/.github/workflows/publish-production-release.yml b/.github/workflows/publish-production-release.yml index ad6e85c..b3b9914 100644 --- a/.github/workflows/publish-production-release.yml +++ b/.github/workflows/publish-production-release.yml @@ -2,7 +2,7 @@ name: Publish production release on: workflow_dispatch jobs: call-workflow-publish-nightly-release: - uses: Yvand/AzureCP/.github/workflows/reusable-build-publish-release.yml@master + uses: Yvand/EntraCP/.github/workflows/reusable-build-publish-release.yml@master with: project-name: ${{ vars.PROJECT_NAME }} version-major-minor: ${{ vars.VERSION_MAJOR_MINOR }} diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 4d3225d..ac71b5e 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -16,7 +16,7 @@ on: jobs: call-workflow-prepare-dtl-env: - uses: Yvand/AzureCP/.github/workflows/reusable-prepare-dtl-env.yml@master + uses: Yvand/EntraCP/.github/workflows/reusable-prepare-dtl-env.yml@master with: project-name: ${{ vars.PROJECT_NAME }} sharepoint-versions: ${{ inputs.sharepoint_versions }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ef6d10..d59ffcf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,17 @@ # Change log for LDAPCP +## Unreleased + +* Fix error when creating the configuration, due to case-sensitive test in the claim types - https://github.com/Yvand/LDAPCP/issues/204 +* Fix the error when loading the global configuration page, if the group claim type set in the LDAPCP configuration does not exist in the trust - https://github.com/Yvand/LDAPCP/issues/203 +* Add the property MaxSearchResultsCount, to override the SharePoint limit of the maximum number of objects that the LDAP server returns - https://github.com/Yvand/LDAPCP/issues/209 +* Correctly initialize LDAP-specific properties with their actual value, instead of the default value of the type - https://github.com/Yvand/LDAPCP/pull/212 +* Fix an NullReferenceException in a very rare scenario where ClaimsPrincipal.Identity is null +* Add helper methods to get/delete a directory connection in the configuration + ## LDAPCP Second Edition v17.0.20240226.2 - Published in February 26, 2024 -* Initial release of LDAPCP Second Edition, a complete rewrite of current project +* Ignore case when comparing claim types, to avoid errors when creating the configuration - https://github.com/Yvand/LDAPCP/pull/205 ## LDAPCP v16.0.20230824.1 enhancements & bug-fixes - Published in August 24, 2023 diff --git a/Yvand.LDAPCPSE/Properties/AssemblyInfo.cs b/Yvand.LDAPCPSE/Properties/AssemblyInfo.cs index be1e2a0..fa75685 100644 --- a/Yvand.LDAPCPSE/Properties/AssemblyInfo.cs +++ b/Yvand.LDAPCPSE/Properties/AssemblyInfo.cs @@ -7,11 +7,11 @@ // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("LDAPCP")] -[assembly: AssemblyDescription("")] +[assembly: AssemblyDescription("A claims provider to connect SharePoint Subscription / 2019 / 2016 with Active Directory and LDAP directories in federated authentication")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("GitHub.com/Yvand - Yvan Duhamel")] +[assembly: AssemblyCompany("Yvan Duhamel - GitHub.com/Yvand")] [assembly: AssemblyProduct("LDAPCP")] -[assembly: AssemblyCopyright("Copyright © 2019, Yvan Duhamel, All rights reserved")] +[assembly: AssemblyCopyright("Copyright © 2024, Yvan Duhamel, All rights reserved")] [assembly: AssemblyTrademark("LDAPCP")] [assembly: AssemblyCulture("")] diff --git a/Yvand.LDAPCPSE/TEMPLATE/ADMIN/LDAPCPSE/GlobalSettings.ascx b/Yvand.LDAPCPSE/TEMPLATE/ADMIN/LDAPCPSE/GlobalSettings.ascx index 6449b96..3cc9e74 100644 --- a/Yvand.LDAPCPSE/TEMPLATE/ADMIN/LDAPCPSE/GlobalSettings.ascx +++ b/Yvand.LDAPCPSE/TEMPLATE/ADMIN/LDAPCPSE/GlobalSettings.ascx @@ -249,37 +249,37 @@ - - + + - - + + - + - - + + - + - + - - + +
- + - +
@@ -337,11 +337,11 @@

- + - - + +

@@ -354,8 +354,8 @@

-
- +
+
- - + + - - + +

@@ -438,8 +438,8 @@

-
- +
+

@@ -453,9 +453,7 @@
  • - - - +
  • @@ -492,18 +490,16 @@ - - + + - - - -
    + +
    - -
    - + +
    +
  • - + - +

    -
    +
    - + - + - - - + + +
    - +
    - +
    -
    - +
    +
    + +
    + - +
    - + - - + + - + - - + + - + - - + + - - + +
    @@ -421,11 +421,11 @@
    @@ -525,58 +521,61 @@
    diff --git a/Yvand.LDAPCPSE/TEMPLATE/ADMIN/LDAPCPSE/GlobalSettings.ascx.cs b/Yvand.LDAPCPSE/TEMPLATE/ADMIN/LDAPCPSE/GlobalSettings.ascx.cs index 25c16b1..132e35d 100644 --- a/Yvand.LDAPCPSE/TEMPLATE/ADMIN/LDAPCPSE/GlobalSettings.ascx.cs +++ b/Yvand.LDAPCPSE/TEMPLATE/ADMIN/LDAPCPSE/GlobalSettings.ascx.cs @@ -18,6 +18,7 @@ public partial class GlobalSettingsUserControl : LDAPCPSEUserControl public new string UserIdentifierEncodedValuePrefix = String.Empty; // This must be a member to be accessible from marup code, it cannot be a property public new string GroupIdentifierEncodedValuePrefix = String.Empty; // This must be a member to be accessible from marup code, it cannot be a property + readonly string NoValueSelected = "None"; readonly string TextConnectionSuccessful = "Connection successful."; readonly string TextSummaryPersistedObjectInformation = "Found configuration '{0}' v{1} (Persisted Object ID: '{2}')"; readonly string TextSharePointDomain = "Connect to SharePoint domain"; @@ -50,9 +51,9 @@ protected void Initialize() LabelMessage.Text = String.Format(TextSummaryPersistedObjectInformation, Configuration.Name, Configuration.Version, Configuration.Id); UserIdentifierEncodedValuePrefix = base.UserIdentifierEncodedValuePrefix; GroupIdentifierEncodedValuePrefix = base.GroupIdentifierEncodedValuePrefix; - PopulateConnectionsGrid(); if (!this.IsPostBack) { + PopulateConnectionsGrid(); PopulateCblAuthenticationTypes(); PopulateFields(); InitializeAugmentation(); @@ -149,6 +150,8 @@ private void PopulateFields() this.TxtUserIdAdditionalLdapFilter.Text = Settings.ClaimTypes.UserIdentifierConfig.DirectoryObjectAdditionalFilter; // Group identifier settings + this.DdlGroupClaimType.Items.Add(NoValueSelected); + this.DdlGroupClaimType.Items[0].Selected = true; var possibleGroupClaimTypes = Utils.GetNonWellKnownUserClaimTypesFromTrust(base.ClaimsProviderName); foreach (string possibleGroupClaimType in possibleGroupClaimTypes) { @@ -229,23 +232,34 @@ protected bool UpdateConfiguration(bool commitChanges) Settings.ClaimTypes.SetAdditionalLdapFilterForEntity(this.TxtUserIdAdditionalLdapFilter.Text, DirectoryObjectType.User); // Group identifier settings - ClaimTypeConfig groupIdConfig = Settings.ClaimTypes.GroupIdentifierConfig; - bool newGroupConfigObject = false; - if (groupIdConfig == null) + if (!String.Equals(this.DdlGroupClaimType.SelectedValue, NoValueSelected, StringComparison.OrdinalIgnoreCase)) { - groupIdConfig = new ClaimTypeConfig { DirectoryObjectType = DirectoryObjectType.Group }; - newGroupConfigObject = true; + ClaimTypeConfig groupIdConfig = Settings.ClaimTypes.GroupIdentifierConfig; + bool newGroupConfigObject = false; + if (groupIdConfig == null) + { + groupIdConfig = new ClaimTypeConfig { DirectoryObjectType = DirectoryObjectType.Group }; + newGroupConfigObject = true; + } + groupIdConfig.ClaimType = this.DdlGroupClaimType.SelectedValue; + groupIdConfig.DirectoryObjectClass = this.TxtGroupLdapClass.Text; + groupIdConfig.DirectoryObjectAttribute = this.TxtGroupLdapAttribute.Text; + groupIdConfig.DirectoryObjectAttributeForDisplayText = this.TxtGroupDisplayTextAttribute.Text; + groupIdConfig.ClaimValueLeadingToken = this.TxtGroupLeadingToken.Text; + Settings.ClaimTypes.SetSearchAttributesForEntity(this.TxtGroupAdditionalLdapAttributes.Text, groupIdConfig.DirectoryObjectClass, DirectoryObjectType.Group); + Settings.ClaimTypes.SetAdditionalLdapFilterForEntity(this.TxtGroupAdditionalLdapFilter.Text, DirectoryObjectType.Group); + if (newGroupConfigObject) + { + Settings.ClaimTypes.Add(groupIdConfig); + } } - groupIdConfig.ClaimType = this.DdlGroupClaimType.SelectedValue; - groupIdConfig.DirectoryObjectClass = this.TxtGroupLdapClass.Text; - groupIdConfig.DirectoryObjectAttribute = this.TxtGroupLdapAttribute.Text; - groupIdConfig.DirectoryObjectAttributeForDisplayText = this.TxtGroupDisplayTextAttribute.Text; - groupIdConfig.ClaimValueLeadingToken = this.TxtGroupLeadingToken.Text; - Settings.ClaimTypes.SetSearchAttributesForEntity(this.TxtGroupAdditionalLdapAttributes.Text, groupIdConfig.DirectoryObjectClass, DirectoryObjectType.Group); - Settings.ClaimTypes.SetAdditionalLdapFilterForEntity(this.TxtGroupAdditionalLdapFilter.Text, DirectoryObjectType.Group); - if (newGroupConfigObject) + else { - Settings.ClaimTypes.Add(groupIdConfig); + ClaimTypeConfig groupIdConfig = Settings.ClaimTypes.GroupIdentifierConfig; + if (groupIdConfig != null) + { + Settings.ClaimTypes.Remove(groupIdConfig); + } } // Augmentation settings @@ -387,6 +401,19 @@ void AddTenantConnection() this.TxtLdapUsername.Text = String.Empty; this.TxtLdapPassword.Text = String.Empty; } + + protected void grdLDAPConnections_RowDataBound(object sender, GridViewRowEventArgs e) + { + // Ask user for confirmation when cliking on button Delete - https://stackoverflow.com/questions/9026884/asp-net-gridview-delete-row-only-on-confirmation + if (e.Row.RowType == DataControlRowType.DataRow) + { + Button deleteButton = (Button)e.Row.Cells[3].Controls[0]; + if (deleteButton != null && String.Equals(deleteButton.Text, "Delete", StringComparison.OrdinalIgnoreCase)) + { + deleteButton.OnClientClick = "if(!confirm('Are you sure you want to delete this directory?')) return;"; + } + } + } } public class PropertyCollectionBinder diff --git a/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/Administration/LDAPCPSEUserControl.cs b/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/Administration/LDAPCPSEUserControl.cs index 65c3b05..5df1147 100644 --- a/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/Administration/LDAPCPSEUserControl.cs +++ b/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/Administration/LDAPCPSEUserControl.cs @@ -3,6 +3,7 @@ using Microsoft.SharePoint.Administration.Claims; using Microsoft.SharePoint.Utilities; using System; +using System.Linq; using System.Security.Claims; using System.Web.UI; using Yvand.LdapClaimsProvider.Configuration; @@ -107,11 +108,14 @@ protected string GroupIdentifierEncodedValuePrefix { SPClaimProviderManager claimMgr = SPClaimProviderManager.Local; ClaimTypeConfig idConfig = Settings.ClaimTypes.GroupIdentifierConfig; - if (idConfig == null) + string accountPrefix = String.Empty; + // https://github.com/Yvand/LDAPCP/issues/203 group claim type may not exist in the trust + if (!String.IsNullOrWhiteSpace(idConfig?.ClaimType) && + SPTrust.ClaimTypeInformation.Count(x => String.Equals(x.MappedClaimType, idConfig.ClaimType, StringComparison.OrdinalIgnoreCase)) > 0) { - return String.Empty; + accountPrefix = claimMgr.EncodeClaim(new SPClaim(idConfig.ClaimType, String.Empty, ClaimValueTypes.String, SPOriginalIssuers.Format(SPOriginalIssuerType.TrustedProvider, SPTrust.Name))); } - return claimMgr.EncodeClaim(new SPClaim(idConfig.ClaimType, String.Empty, ClaimValueTypes.String, SPOriginalIssuers.Format(SPOriginalIssuerType.TrustedProvider, SPTrust.Name))); + return accountPrefix; } } diff --git a/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/Configuration/ClaimTypeConfig.cs b/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/Configuration/ClaimTypeConfig.cs index 2353e75..01f3ec2 100644 --- a/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/Configuration/ClaimTypeConfig.cs +++ b/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/Configuration/ClaimTypeConfig.cs @@ -745,7 +745,7 @@ public void SetSearchAttributesForEntity(string newSearchAttributesCsv, string l { Add(newSearchAttributeConfig); } - catch (InvalidOperationException ex) + catch (InvalidOperationException ex) { // A InvalidOperationException is thrown if the LDAP attribute already exists as metadata Logger.LogException(String.Empty, $"while trying to set the LDAP attribute {newAttribute} for entity type {entityType} as a search attribute", TraceCategory.Core, ex); @@ -770,11 +770,14 @@ public void SetSearchAttributesForEntity(string newSearchAttributesCsv, string l public void SetAdditionalLdapFilterForEntity(string newAdditionalLdapFilter, DirectoryObjectType entityType) { ClaimTypeConfig mainConfig = GetIdentifierConfiguration(entityType); - mainConfig.DirectoryObjectAdditionalFilter = newAdditionalLdapFilter; - IEnumerable additionalConfigurations = GetAdditionalConfigurationsForEntity(entityType); - foreach (ClaimTypeConfig additionalConfiguration in additionalConfigurations) + if (mainConfig != null) { - additionalConfiguration.DirectoryObjectAdditionalFilter = newAdditionalLdapFilter; + mainConfig.DirectoryObjectAdditionalFilter = newAdditionalLdapFilter; + IEnumerable additionalConfigurations = GetAdditionalConfigurationsForEntity(entityType); + foreach (ClaimTypeConfig additionalConfiguration in additionalConfigurations) + { + additionalConfiguration.DirectoryObjectAdditionalFilter = newAdditionalLdapFilter; + } } } } diff --git a/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/Configuration/ClaimsProviderConstants.cs b/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/Configuration/ClaimsProviderConstants.cs index 7eeb25b..060b0af 100644 --- a/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/Configuration/ClaimsProviderConstants.cs +++ b/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/Configuration/ClaimsProviderConstants.cs @@ -321,7 +321,8 @@ public OperationContext(ClaimsProviderSettings settings, OperationType currentRe this.IncomingEntity = incomingEntity; this.UriContext = context; this.HierarchyNodeID = hierarchyNodeID; - this.MaxCount = maxCount; + this.MaxCount = settings.MaxSearchResultsCount == -1 || currentRequestType != OperationType.Search ? maxCount : settings.MaxSearchResultsCount; + // settings.LdapConnections must be cloned locally to ensure its properties ($select / $filter) won't be updated by multiple threads this.LdapConnections = new List(settings.LdapConnections.Count); @@ -350,7 +351,7 @@ public OperationContext(ClaimsProviderSettings settings, OperationType currentRe if (httpctx != null) { WIF4_5.ClaimsPrincipal cp = httpctx.User as WIF4_5.ClaimsPrincipal; - if (cp != null) + if (cp != null && cp.Identity != null) { if (SPClaimProviderManager.IsEncodedClaim(cp.Identity.Name)) { diff --git a/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/Configuration/LDAPProviderConfiguration.cs b/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/Configuration/LDAPProviderConfiguration.cs index 9c80646..eaeb353 100644 --- a/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/Configuration/LDAPProviderConfiguration.cs +++ b/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/Configuration/LDAPProviderConfiguration.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.DirectoryServices.Protocols; using System.Linq; using Yvand.LdapClaimsProvider.Logging; @@ -23,40 +24,45 @@ public interface ILdapProviderSettings ClaimTypeConfigCollection ClaimTypes { get; } /// - /// Gets or sets whether to skip the requests to LDAP and consider any input as valid. + /// Gets whether to skip the requests to LDAP and consider any input as valid. /// This can be useful to keep people picker working even if connectivity with the directory is lost. /// bool AlwaysResolveUserInput { get; } /// - /// Gets or sets whether to return only results that match exactly the user input (case-insensitive). + /// Gets whether to return only results that match exactly the user input (case-insensitive). /// bool FilterExactMatchOnly { get; } /// - /// Gets or sets whether to return the trusted groups that the user is a member of. + /// Gets whether to return the groups the user is a member of. /// bool EnableAugmentation { get; } /// - /// Gets or sets a string that will appear as a prefix of the text of each result, in the people picker. + /// Gets the string that will appear as a prefix of the text of each result, in the people picker. /// string EntityDisplayTextPrefix { get; } /// - /// Gets or sets the timeout in seconds before an operation to LDAP directory is canceled. + /// Gets the timeout in seconds, before an operation to LDAP directory is canceled. /// int Timeout { get; } /// - /// This property is not used by LDAPCP and is available to developers for their own needs + /// Gets this property, not used by LDAPCP and available to developers for their own needs /// string CustomData { get; } + + /// + /// Gets how many results maximum can be returned to the people picker during a search operation + /// + int MaxSearchResultsCount { get; } #endregion - #region LDAP specific settings + #region LDAP-specific settings /// - /// Gets the list of Azure tenants to use to get entities + /// Gets the list of LDAP directories /// List LdapConnections { get; } bool FilterEnabledUsersOnly { get; } @@ -76,6 +82,7 @@ public class LdapProviderSettings : ILdapProviderSettings public string EntityDisplayTextPrefix { get; set; } public int Timeout { get; set; } = ClaimsProviderConstants.DEFAULT_TIMEOUT; public string CustomData { get; set; } + public int MaxSearchResultsCount { get; set; } = -1; #endregion #region LDAP specific settings @@ -141,7 +148,7 @@ public static ClaimTypeConfigCollection ReturnDefaultClaimTypesConfig(string cla //// Not adding those as additional attributes to avoid having too many LDAP attributes to search users in the LDAP filter - var nonIdentityClaimTypes = ClaimsProviderConstants.GetDefaultSettingsPerUserClaimType().Where(x => x.Key != spTrust.IdentityClaimTypeInformation.MappedClaimType); + var nonIdentityClaimTypes = ClaimsProviderConstants.GetDefaultSettingsPerUserClaimType().Where(x => !String.Equals(x.Key, spTrust.IdentityClaimTypeInformation.MappedClaimType, StringComparison.OrdinalIgnoreCase)); foreach (var nonIdentityClaimType in nonIdentityClaimTypes) { ctConfig = nonIdentityClaimType.Value; @@ -177,8 +184,9 @@ public static ClaimTypeConfigCollection ReturnDefaultClaimTypesConfig(string cla public class LdapProviderConfiguration : SPPersistedObject, ILdapProviderSettings { public string LocalAssemblyVersion => ClaimsProviderConstants.ClaimsProviderVersion; + /// - /// Gets the settings, based on the configuration stored in this persisted object + /// Gets or sets the version of the settings /// public ILdapProviderSettings Settings { @@ -195,6 +203,9 @@ public ILdapProviderSettings Settings #region "Base settings implemented from IEntraIDEntityProviderSettings" + /// + /// Gets or sets the claim types and their mapping with a DirectoryObject property + /// public ClaimTypeConfigCollection ClaimTypes { get @@ -215,22 +226,32 @@ private set private Collection _ClaimTypesCollection; private ClaimTypeConfigCollection _ClaimTypes; + /// + /// Gets or sets whether to skip the requests to LDAP and consider any input as valid. + /// This can be useful to keep people picker working even if connectivity with the directory is lost. + /// public bool AlwaysResolveUserInput { get => _AlwaysResolveUserInput; private set => _AlwaysResolveUserInput = value; } [Persisted] - private bool _AlwaysResolveUserInput; + private bool _AlwaysResolveUserInput = false; + /// + /// Gets or sets whether to return only results that match exactly the user input (case-insensitive). + /// public bool FilterExactMatchOnly { get => _FilterExactMatchOnly; private set => _FilterExactMatchOnly = value; } [Persisted] - private bool _FilterExactMatchOnly; + private bool _FilterExactMatchOnly = false; + /// + /// Gets or sets whether to return the groups the user is a member of. + /// public bool EnableAugmentation { get => _EnableAugmentation; @@ -239,6 +260,9 @@ public bool EnableAugmentation [Persisted] private bool _EnableAugmentation = true; + /// + /// Gets or sets the string that will appear as a prefix of the text of each result, in the people picker. + /// public string EntityDisplayTextPrefix { get => _EntityDisplayTextPrefix; @@ -247,6 +271,9 @@ public string EntityDisplayTextPrefix [Persisted] private string _EntityDisplayTextPrefix; + /// + /// Gets or sets the timeout in seconds, before an operation to LDAP directory is canceled. + /// public int Timeout { get @@ -258,6 +285,9 @@ public int Timeout [Persisted] private int _Timeout = ClaimsProviderConstants.DEFAULT_TIMEOUT; + /// + /// Gets or sets this property, not used by LDAPCP and available to developers for their own needs + /// public string CustomData { get => _CustomData; @@ -265,10 +295,27 @@ public string CustomData } [Persisted] private string _CustomData; + + /// + /// Gets or sets how many results maximum can be returned to the people picker during a search operation + /// + public int MaxSearchResultsCount + { + get + { + return _MaxSearchResultsCount; + } + private set => _MaxSearchResultsCount = value; + } + [Persisted] + private int _MaxSearchResultsCount = -1; #endregion - #region "EntraID settings implemented from IEntraIDEntityProviderSettings" + #region "LDAP-specific settings implemented from IEntraIDEntityProviderSettings" + /// + /// Gets or sets the list of LDAP directories + /// public List LdapConnections { get => _LdapServers; @@ -283,7 +330,7 @@ public bool FilterEnabledUsersOnly private set => _FilterEnabledUsersOnly = value; } [Persisted] - private bool _FilterEnabledUsersOnly; + private bool _FilterEnabledUsersOnly = true; public bool FilterSecurityGroupsOnly { @@ -291,7 +338,7 @@ public bool FilterSecurityGroupsOnly private set => _FilterSecurityGroupsOnly = value; } [Persisted] - private bool _FilterSecurityGroupsOnly; + private bool _FilterSecurityGroupsOnly = true; public bool AddWildcardAsPrefixOfInput { @@ -299,7 +346,7 @@ public bool AddWildcardAsPrefixOfInput private set => _AddWildcardAsPrefixOfInput = value; } [Persisted] - private bool _AddWildcardAsPrefixOfInput; + private bool _AddWildcardAsPrefixOfInput = false; #endregion #region "Other properties" @@ -364,14 +411,52 @@ protected virtual ILdapProviderSettings GenerateSettingsFromCurrentConfiguration EntityDisplayTextPrefix = this.EntityDisplayTextPrefix, FilterExactMatchOnly = this.FilterExactMatchOnly, Timeout = this.Timeout, + MaxSearchResultsCount = this.MaxSearchResultsCount, + Version = this.Version, // Properties specific to type IEntraSettings LdapConnections = this.LdapConnections, + FilterEnabledUsersOnly = this.FilterEnabledUsersOnly, + FilterSecurityGroupsOnly = this.FilterSecurityGroupsOnly, + AddWildcardAsPrefixOfInput = this.AddWildcardAsPrefixOfInput, }; return (ILdapProviderSettings)entityProviderSettings; } + /// + /// Gets the directory configuration + /// + /// Directory path + /// + /// + public DirectoryConnection GetLdapConnection(string directoryConnectionPath) + { + if (String.IsNullOrWhiteSpace(directoryConnectionPath)) + { + throw new ArgumentNullException(nameof(directoryConnectionPath)); + } + return this.LdapConnections.FirstOrDefault(x => x.LdapPath.Equals(directoryConnectionPath, StringComparison.OrdinalIgnoreCase)); + } + + /// + /// Deletes the directory configuration + /// + /// Directory path + /// + /// + public bool DeleteLdapConnection(string directoryConnectionPath) + { + if (String.IsNullOrWhiteSpace(directoryConnectionPath)) + { + throw new ArgumentNullException(nameof(directoryConnectionPath)); + } + + DirectoryConnection directory = GetLdapConnection(directoryConnectionPath); + if (directory == null) { return false; } + return this.LdapConnections.Remove(directory); + } + /// /// If it is valid, commits the current settings to the SharePoint settings database /// @@ -449,6 +534,11 @@ public virtual void ValidateConfiguration() } } } + + if (MaxSearchResultsCount < -1) + { + throw new InvalidOperationException($"The configuration is invalid because the value of property {nameof(MaxSearchResultsCount)} is < -1"); + } } /// @@ -498,8 +588,12 @@ public virtual void ApplySettings(ILdapProviderSettings settings, bool commitIfV this.EntityDisplayTextPrefix = settings.EntityDisplayTextPrefix; this.Timeout = settings.Timeout; this.CustomData = settings.CustomData; + this.MaxSearchResultsCount = settings.MaxSearchResultsCount; this.LdapConnections = settings.LdapConnections; + this.FilterEnabledUsersOnly = settings.FilterEnabledUsersOnly; + this.FilterSecurityGroupsOnly = settings.FilterSecurityGroupsOnly; + this.AddWildcardAsPrefixOfInput = settings.AddWildcardAsPrefixOfInput; if (commitIfValid) { diff --git a/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/LdapEntityProvider.cs b/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/LdapEntityProvider.cs index 64b1d58..2cda0bf 100644 --- a/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/LdapEntityProvider.cs +++ b/Yvand.LDAPCPSE/Yvand.LdapClaimsProvider/LdapEntityProvider.cs @@ -502,7 +502,7 @@ protected List QueryLDAPServers(OperationContext curre using (DirectorySearcher ds = new DirectorySearcher(ldapFilter)) { ds.SearchRoot = directory; - ds.SizeLimit = currentContext.MaxCount; + ds.SizeLimit = currentContext.MaxCount; // Property SizeLimit is ignored if it is set to 0 (tested), and ArgumentException an exception is < 0 - https://learn.microsoft.com/en-us/dotnet/api/system.directoryservices.directorysearcher.sizelimit?view=netframework-4.8.1 ds.ClientTimeout = new TimeSpan(0, 0, this.Settings.Timeout); // Set the timeout in seconds ds.PropertiesToLoad.Add("objectclass"); ds.PropertiesToLoad.Add("nETBIOSName"); diff --git a/azure-pipelines/ci-apply-dtl-artifacts.yml b/azure-pipelines/ci-apply-dtl-artifacts.yml deleted file mode 100644 index bbfb89e..0000000 --- a/azure-pipelines/ci-apply-dtl-artifacts.yml +++ /dev/null @@ -1,131 +0,0 @@ -resources: -- repo: self - -jobs: -- job: ApplyArtifactsSP2013 - condition: eq(variables['Deployment.ProvisionSharePoint2013'], true) - displayName: Apply artifacts on SP2013 - timeoutInMinutes: 30 - variables: - jobSharePointVersion: 2013 - pool: - vmImage: 'windows-2019' - steps: - - checkout: none #skip checking out the default repository resource - - task: automagically.DownloadFile.DownloadFile.DownloadFile@1 - displayName: 'Download apply-dtl-artifact.ps1' - inputs: - FileUrl: 'https://raw.githubusercontent.com/Yvand/AzureRM-Templates/master/DevTestLabs-Artifacts/manage-artifacts/apply-dtl-artifact.ps1' - DestinationFolder: '$(System.DefaultWorkingDirectory)\scripts' - - - task: AzurePowerShell@3 - displayName: 'Create and register a VSTS agent in DevOps agent pools by applying artifact "Azure Pipelines Agent"' - inputs: - azureSubscription: '$(DevTestLabs.AzureConnectionName)' - ScriptPath: '$(System.DefaultWorkingDirectory)\scripts\apply-dtl-artifact.ps1' - ScriptArguments: '-DevTestLabName "$(DevTestLabs.LabName)" -VirtualMachineName "SP$(jobSharePointVersion)" -RepositoryName "Yvand/AzureRM-Templates" -ArtifactName "windows-vsts-build-agent" -param_vstsAccount "$(DevOps.OrganizationName)" -param_vstsPassword "$(DevOps.AccessToken)" -param_poolName "$(system.teamProject)-Tests-$(jobSharePointVersion)" -param_windowsLogonAccount "$(Deployment.DomainName)\$(Deployment.AdminUserName)" -param_windowsLogonPassword "$(Deployment.AdminPassword)" -param_agentName "SP$(jobSharePointVersion)" -param_agentNameSuffix "-$(Build.BuildNumber)" -param_RunAsAutoLogon false -param_driveLetter C -param_workDirectory ""' - preferredAzurePowerShellVersion: 5.1.1 - - - task: AzurePowerShell@3 - displayName: 'Apply artifact "Download Azure Pipelines Artifact and Run Script"' - inputs: - azureSubscription: '$(DevTestLabs.AzureConnectionName)' - ScriptPath: '$(System.DefaultWorkingDirectory)\scripts\apply-dtl-artifact.ps1' - ScriptArguments: -DevTestLabName '$(DevTestLabs.LabName)' -VirtualMachineName 'SP$(jobSharePointVersion)' -RepositoryName 'Yvand/AzureRM-Templates' -ArtifactName 'windows-vsts-download-and-run-script' -param_vstsProjectUri 'https://dev.azure.com/$(DevOps.OrganizationName)/$(system.teamProject)' -param_buildDefinitionName '$(DevOps.BuildArtifactsPipelineName)' -param_personalAccessToken $(DevOps.AccessToken) -param_pathToScript 'drop_$(Tests.BuildConfiguration)\$(Deployment.ConfigureServerFolderName)\ConfigureLab.ps1' -param_scriptArguments "-pathToPackage '..\$(system.teamProject)\bin\$(Tests.BuildConfiguration)\$(system.teamProject).wsp' -claimsProviderName '$(system.teamProject)' -spTrustName '$(Deployment.DomainFQDN)' -adminUserName '$(Deployment.DomainName)\$(Deployment.AdminUserName)' -adminPassword '$(Deployment.AdminPassword)'" - preferredAzurePowerShellVersion: 5.1.1 - -- job: ApplyArtifactsSP2016 - condition: eq(variables['Deployment.ProvisionSharePoint2016'], true) - displayName: Apply artifacts on SP2016 - timeoutInMinutes: 30 - variables: - jobSharePointVersion: 2016 - pool: - vmImage: 'windows-2019' - steps: - - checkout: none #skip checking out the default repository resource - - task: automagically.DownloadFile.DownloadFile.DownloadFile@1 - displayName: 'Download apply-dtl-artifact.ps1' - inputs: - FileUrl: 'https://raw.githubusercontent.com/Yvand/AzureRM-Templates/master/DevTestLabs-Artifacts/manage-artifacts/apply-dtl-artifact.ps1' - DestinationFolder: '$(System.DefaultWorkingDirectory)\scripts' - - - task: AzurePowerShell@3 - displayName: 'Create and register a VSTS agent in DevOps agent pools by applying artifact "Azure Pipelines Agent"' - inputs: - azureSubscription: '$(DevTestLabs.AzureConnectionName)' - ScriptPath: '$(System.DefaultWorkingDirectory)\scripts\apply-dtl-artifact.ps1' - ScriptArguments: '-DevTestLabName "$(DevTestLabs.LabName)" -VirtualMachineName "SP$(jobSharePointVersion)" -RepositoryName "Yvand/AzureRM-Templates" -ArtifactName "windows-vsts-build-agent" -param_vstsAccount "$(DevOps.OrganizationName)" -param_vstsPassword "$(DevOps.AccessToken)" -param_poolName "$(system.teamProject)-Tests-$(jobSharePointVersion)" -param_windowsLogonAccount "$(Deployment.DomainName)\$(Deployment.AdminUserName)" -param_windowsLogonPassword "$(Deployment.AdminPassword)" -param_agentName "SP$(jobSharePointVersion)" -param_agentNameSuffix "-$(Build.BuildNumber)" -param_RunAsAutoLogon false -param_driveLetter C -param_workDirectory ""' - preferredAzurePowerShellVersion: 5.1.1 - - - task: AzurePowerShell@3 - displayName: 'Apply artifact "Download Azure Pipelines Artifact and Run Script"' - inputs: - azureSubscription: '$(DevTestLabs.AzureConnectionName)' - ScriptPath: '$(System.DefaultWorkingDirectory)\scripts\apply-dtl-artifact.ps1' - ScriptArguments: -DevTestLabName '$(DevTestLabs.LabName)' -VirtualMachineName 'SP$(jobSharePointVersion)' -RepositoryName 'Yvand/AzureRM-Templates' -ArtifactName 'windows-vsts-download-and-run-script' -param_vstsProjectUri 'https://dev.azure.com/$(DevOps.OrganizationName)/$(system.teamProject)' -param_buildDefinitionName '$(DevOps.BuildArtifactsPipelineName)' -param_personalAccessToken $(DevOps.AccessToken) -param_pathToScript 'drop_$(Tests.BuildConfiguration)\$(Deployment.ConfigureServerFolderName)\ConfigureLab.ps1' -param_scriptArguments "-pathToPackage '..\$(system.teamProject)\bin\$(Tests.BuildConfiguration)\$(system.teamProject).wsp' -claimsProviderName '$(system.teamProject)' -spTrustName '$(Deployment.DomainFQDN)' -adminUserName '$(Deployment.DomainName)\$(Deployment.AdminUserName)' -adminPassword '$(Deployment.AdminPassword)'" - preferredAzurePowerShellVersion: 5.1.1 - -- job: ApplyArtifactsSP2019 - condition: eq(variables['Deployment.ProvisionSharePoint2019'], true) - displayName: Apply artifacts on SP2019 - timeoutInMinutes: 30 - variables: - jobSharePointVersion: 2019 - pool: - vmImage: 'windows-2019' - steps: - - checkout: none #skip checking out the default repository resource - - task: automagically.DownloadFile.DownloadFile.DownloadFile@1 - displayName: 'Download apply-dtl-artifact.ps1' - inputs: - FileUrl: 'https://raw.githubusercontent.com/Yvand/AzureRM-Templates/master/DevTestLabs-Artifacts/manage-artifacts/apply-dtl-artifact.ps1' - DestinationFolder: '$(System.DefaultWorkingDirectory)\scripts' - - - task: AzurePowerShell@3 - displayName: 'Create and register a VSTS agent in DevOps agent pools by applying artifact "Azure Pipelines Agent"' - inputs: - azureSubscription: '$(DevTestLabs.AzureConnectionName)' - ScriptPath: '$(System.DefaultWorkingDirectory)\scripts\apply-dtl-artifact.ps1' - ScriptArguments: '-DevTestLabName "$(DevTestLabs.LabName)" -VirtualMachineName "SP$(jobSharePointVersion)" -RepositoryName "Yvand/AzureRM-Templates" -ArtifactName "windows-vsts-build-agent" -param_vstsAccount "$(DevOps.OrganizationName)" -param_vstsPassword "$(DevOps.AccessToken)" -param_poolName "$(system.teamProject)-Tests-$(jobSharePointVersion)" -param_windowsLogonAccount "$(Deployment.DomainName)\$(Deployment.AdminUserName)" -param_windowsLogonPassword "$(Deployment.AdminPassword)" -param_agentName "SP$(jobSharePointVersion)" -param_agentNameSuffix "-$(Build.BuildNumber)" -param_RunAsAutoLogon false -param_driveLetter C -param_workDirectory ""' - preferredAzurePowerShellVersion: 5.1.1 - - - task: AzurePowerShell@3 - displayName: 'Apply artifact "Download Azure Pipelines Artifact and Run Script"' - inputs: - azureSubscription: '$(DevTestLabs.AzureConnectionName)' - ScriptPath: '$(System.DefaultWorkingDirectory)\scripts\apply-dtl-artifact.ps1' - ScriptArguments: -DevTestLabName '$(DevTestLabs.LabName)' -VirtualMachineName 'SP$(jobSharePointVersion)' -RepositoryName 'Yvand/AzureRM-Templates' -ArtifactName 'windows-vsts-download-and-run-script' -param_vstsProjectUri 'https://dev.azure.com/$(DevOps.OrganizationName)/$(system.teamProject)' -param_buildDefinitionName '$(DevOps.BuildArtifactsPipelineName)' -param_personalAccessToken $(DevOps.AccessToken) -param_pathToScript 'drop_$(Tests.BuildConfiguration)\$(Deployment.ConfigureServerFolderName)\ConfigureLab.ps1' -param_scriptArguments "-pathToPackage '..\$(system.teamProject)\bin\$(Tests.BuildConfiguration)\$(system.teamProject).wsp' -claimsProviderName '$(system.teamProject)' -spTrustName '$(Deployment.DomainFQDN)' -adminUserName '$(Deployment.DomainName)\$(Deployment.AdminUserName)' -adminPassword '$(Deployment.AdminPassword)'" - preferredAzurePowerShellVersion: 5.1.1 - -- job: ApplyArtifactsSPSubscription - condition: eq(variables['Deployment.ProvisionSharePointSubscription'], true) - displayName: Apply artifacts on SPSubscription - timeoutInMinutes: 30 - variables: - jobSharePointVersion: Subscription - pool: - vmImage: 'windows-latest' - steps: - - checkout: none #skip checking out the default repository resource - - task: automagically.DownloadFile.DownloadFile.DownloadFile@1 - displayName: 'Download apply-dtl-artifact.ps1' - inputs: - FileUrl: 'https://raw.githubusercontent.com/Yvand/AzureRM-Templates/master/DevTestLabs-Artifacts/manage-artifacts/apply-dtl-artifact.ps1' - DestinationFolder: '$(System.DefaultWorkingDirectory)\scripts' - - - task: AzurePowerShell@3 - displayName: 'Create and register a VSTS agent in DevOps agent pools by applying artifact "Azure Pipelines Agent"' - inputs: - azureSubscription: '$(DevTestLabs.AzureConnectionName)' - ScriptPath: '$(System.DefaultWorkingDirectory)\scripts\apply-dtl-artifact.ps1' - ScriptArguments: '-DevTestLabName "$(DevTestLabs.LabName)" -VirtualMachineName "SP$(jobSharePointVersion)" -RepositoryName "Yvand/AzureRM-Templates" -ArtifactName "windows-vsts-build-agent" -param_vstsAccount "$(DevOps.OrganizationName)" -param_vstsPassword "$(DevOps.AccessToken)" -param_poolName "$(system.teamProject)-Tests-$(jobSharePointVersion)" -param_windowsLogonAccount "$(Deployment.DomainName)\$(Deployment.AdminUserName)" -param_windowsLogonPassword "$(Deployment.AdminPassword)" -param_agentName "SP$(jobSharePointVersion)" -param_agentNameSuffix "-$(Build.BuildNumber)" -param_RunAsAutoLogon false -param_driveLetter C -param_workDirectory ""' - preferredAzurePowerShellVersion: 5.1.1 - - - task: AzurePowerShell@3 - displayName: 'Apply artifact "Download Azure Pipelines Artifact and Run Script"' - inputs: - azureSubscription: '$(DevTestLabs.AzureConnectionName)' - ScriptPath: '$(System.DefaultWorkingDirectory)\scripts\apply-dtl-artifact.ps1' - ScriptArguments: -DevTestLabName '$(DevTestLabs.LabName)' -VirtualMachineName 'SP$(jobSharePointVersion)' -RepositoryName 'Yvand/AzureRM-Templates' -ArtifactName 'windows-vsts-download-and-run-script' -param_vstsProjectUri 'https://dev.azure.com/$(DevOps.OrganizationName)/$(system.teamProject)' -param_buildDefinitionName '$(DevOps.BuildArtifactsPipelineName)' -param_personalAccessToken $(DevOps.AccessToken) -param_pathToScript 'drop_$(Tests.BuildConfiguration)\$(Deployment.ConfigureServerFolderName)\ConfigureLab.ps1' -param_scriptArguments "-pathToPackage '..\$(system.teamProject)\bin\$(Tests.BuildConfiguration)\$(system.teamProject).wsp' -claimsProviderName '$(system.teamProject)' -spTrustName '$(Deployment.DomainFQDN)' -adminUserName '$(Deployment.DomainName)\$(Deployment.AdminUserName)' -adminPassword '$(Deployment.AdminPassword)'" - preferredAzurePowerShellVersion: 5.1.1 \ No newline at end of file diff --git a/azure-pipelines/ci-compile.yml b/azure-pipelines/ci-compile.yml deleted file mode 100644 index 9b5ffd9..0000000 --- a/azure-pipelines/ci-compile.yml +++ /dev/null @@ -1,121 +0,0 @@ -name: $(BuildVersion).$(date:yyyyMMdd).$(Build.BuildId) -resources: -- repo: self - -variables: - SolutionFileName: '$(system.teamProject).sln' - -jobs: -- job: Compile - strategy: - maxParallel: 2 - matrix: - debugJob: - configuration: debug - releaseJob: - configuration: release - displayName: Compile - pool: - vmImage: 'windows-2019' - demands: - - msbuild - - visualstudio - - azureps - steps: - - task: DownloadSecureFile@1 - displayName: 'Download signing key' - inputs: - secureFile: '$(SigningKeySecureFileID)' - - - powershell: | - # Set variables - $azureStorageBaseDirectory = "Resources\$(system.teamProject)" - $projectLocalPath = "$(System.DefaultWorkingDirectory)\$(system.teamProject)" - $devTestLabsLocalPath = "$(Build.ArtifactStagingDirectory)\$(Tests.DataFolderName)" - - # Create now folder that will contain later scripts to configure local test server - #if ((Test-Path -Path "$(Build.ArtifactStagingDirectory)\$(Deployment.ConfigureServerFolderName)" -PathType Container) -eq $false) { - #New-Item -ItemType Directory -Path "$(Build.ArtifactStagingDirectory)\$(Deployment.ConfigureServerFolderName)" - #} - - Write-Output ("Copy signing key from $(DownloadSecureFile.secureFilePath) to $projectLocalPath") - Copy-Item "$(DownloadSecureFile.secureFilePath)" -Destination "$projectLocalPath" - - Write-Output ("Copy Microsoft.SharePoint.dll from Azure storage account") - $azureContext = New-AzureStorageContext $(AzureStorageAccountName) $(AzureStorageAccountKey) - $azureShare = Get-AzureStorageShare $(AzureStorageShareName) -Context $azureContext - Get-AzureStorageFileContent -Share $azureShare -Path "$azureStorageBaseDirectory\SharePoint 2013\Microsoft.SharePoint.dll" "$projectLocalPath\Microsoft.SharePoint.dll" - Write-Output ("Add Microsoft.SharePoint.dll to the GAC") - [System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") - $publish = New-Object System.EnterpriseServices.Internal.Publish - $publish.GacInstall("$projectLocalPath\Microsoft.SharePoint.dll") - - Write-Output ("Copy integration tests data from the Azure storage account") - # Create the destination directory - if ((Test-Path -Path $devTestLabsLocalPath -PathType Container) -eq $false) { - New-Item -ItemType Directory -Path $devTestLabsLocalPath - } - $azurePath = Join-Path -Path $azureStorageBaseDirectory -ChildPath "$(Tests.DataFolderName)" - Get-AzureStorageFile -ShareName $(AzureStorageShareName) -Context $azureContext -Path $azurePath | Get-AzureStorageFile | ?{$_.GetType().Name -eq "CloudFile"} | Get-AzureStorageFileContent -Destination $devTestLabsLocalPath - - displayName: 'Import resources' - - - task: automagically.DownloadFile.DownloadFile.DownloadFile@1 - displayName: 'Download ConfigureLab.ps1' - inputs: - FileUrl: 'https://raw.githubusercontent.com/Yvand/AzureRM-Templates/master/DevTestLabs-Artifacts/manage-artifacts/ConfigureLab.ps1' - DestinationFolder: '$(Build.ArtifactStagingDirectory)\$(Deployment.ConfigureServerFolderName)' - - - task: automagically.DownloadFile.DownloadFile.DownloadFile@1 - displayName: 'Download ConfigureLab.psm1' - inputs: - FileUrl: 'https://raw.githubusercontent.com/Yvand/AzureRM-Templates/master/DevTestLabs-Artifacts/manage-artifacts/ConfigureLab.psm1' - DestinationFolder: '$(Build.ArtifactStagingDirectory)\$(Deployment.ConfigureServerFolderName)' - - - task: NuGetToolInstaller@0 - displayName: 'Use NuGet 4.4.1' - inputs: - versionSpec: 4.4.1 - - - task: NuGetCommand@2 - displayName: 'NuGet restore' - inputs: - restoreSolution: '$(SolutionFileName)' - - - task: bleddynrichards.Assembly-Info-Task.Assembly-Info-Task.Assembly-Info-NetFramework@2 - displayName: 'Set $(system.teamProject) assemblies manifest' - inputs: - FileNames: '**\AssemblyInfo.cs' - Title: $(system.teamProject) - Product: $(system.teamProject) - Description: '$(ProductDescription)' - Company: GitHub.com/Yvand - Copyright: 'Copyright © $(date:YYYY) Yvan Duhamel, All rights reserved' - Trademark: '$(system.teamProject)' - VersionNumber: 1.0.0.0 - FileVersionNumber: '$(Build.BuildNumber)' - InformationalVersion: '$(Build.BuildNumber)' - - - task: VSBuild@1 - displayName: 'Build $(system.teamProject) solution' - inputs: - solution: '$(SolutionFileName)' - msbuildArgs: '/p:IsPackaging=true' - platform: '$(BuildPlatform)' - configuration: '$(configuration)' - msbuildArchitecture: x64 - - - task: CopyFiles@2 - displayName: 'Copy binaries to artifacts' - inputs: - SourceFolder: '$(Build.SourcesDirectory)' - Contents: | - $(system.teamProject)/bin/$(configuration)/?($(system.teamProject).*) - $(system.teamProject).Tests/bin/$(configuration)/?(*.dll) - TargetFolder: '$(Build.ArtifactStagingDirectory)' - - - task: PublishBuildArtifacts@1 - displayName: 'Publish Artifact: drop' - inputs: - pathtoPublish: '$(Build.ArtifactStagingDirectory)' - artifactName: 'drop_$(configuration)' diff --git a/azure-pipelines/ci-create-dtl-environment.yml b/azure-pipelines/ci-create-dtl-environment.yml deleted file mode 100644 index 658ef1e..0000000 --- a/azure-pipelines/ci-create-dtl-environment.yml +++ /dev/null @@ -1,21 +0,0 @@ -resources: -- repo: self - -jobs: -- job: CreateTestEnvironment - displayName: Create test environment - timeoutInMinutes: 90 - pool: - vmImage: 'windows-latest' - steps: - - checkout: none #skip checking out the default repository resource - - task: ms-azuredevtestlabs.tasks.azure-dtl-task-createEnvironment.AzureDevTestLabsCreateEnvironment@3 - displayName: 'Create Azure DevTest Labs Environment' - inputs: - azureSubscription: '$(DevTestLabs.AzureConnectionName)' - LabId: '/subscriptions/$(DevTestLabs.AzureSubscriptionId)/resourceGroups/$(DevTestLabs.LabName)/providers/Microsoft.DevTestLab/labs/$(DevTestLabs.LabName)' - RepositoryId: '/subscriptions/$(DevTestLabs.AzureSubscriptionId)/resourcegroups/$(DevTestLabs.LabName)/providers/microsoft.devtestlab/labs/$(DevTestLabs.LabName)/artifactsources/$(DevTestLabs.RepoID)' - TemplateId: '/subscriptions/$(DevTestLabs.AzureSubscriptionId)/resourceGroups/$(DevTestLabs.LabName)/providers/Microsoft.DevTestLab/labs/$(DevTestLabs.LabName)/artifactSources/$(DevTestLabs.RepoID)/armTemplates/$(DevTestLabs.ARMTemplateName)' - EnvironmentName: 'Tests-$(system.teamProject)' - ParameterOverrides: "-provisionSharePoint2013 $(Deployment.ProvisionSharePoint2013) -provisionSharePoint2016 $(Deployment.ProvisionSharePoint2016) -provisionSharePoint2019 $(Deployment.ProvisionSharePoint2019) -provisionSharePointSubscription $(Deployment.ProvisionSharePointSubscription) -adminUserName '$(Deployment.AdminUserName)' -adminPassword '$(Deployment.AdminPassword)' -serviceAccountsPassword '$(Deployment.ServiceAccountsPassword)' -addPublicIPAddressToEachVM true -configureADFS true -addAzureBastion true -enableHybridBenefitServerLicenses true -enableAutomaticUpdates false" - timeoutInMinutes: 90