@@ -337,11 +337,11 @@
-
+
-
-
+
+
@@ -354,8 +354,8 @@
-
-
+
+
@@ -421,11 +421,11 @@
|
-
-
+
+
-
-
+
+
@@ -438,8 +438,8 @@
-
-
+
+
@@ -453,9 +453,7 @@
-
-
-
+
@@ -492,18 +490,16 @@
-
-
+
+
-
-
-
-
+
+
-
-
-
+
+
+
@@ -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
|