diff --git a/demo/Bitai.LDAPHelper.Demo/Bitai.LDAPHelper.Demo.csproj b/demo/Bitai.LDAPHelper.Demo/Bitai.LDAPHelper.Demo.csproj
index 02be180..42c118b 100644
--- a/demo/Bitai.LDAPHelper.Demo/Bitai.LDAPHelper.Demo.csproj
+++ b/demo/Bitai.LDAPHelper.Demo/Bitai.LDAPHelper.Demo.csproj
@@ -10,9 +10,9 @@
© 2026 BITAI. All rights reserved.
Bitai.Bitai.LDAPHelper.Demo
hierarchy_32.png
- 10.0.1
- 10.0.1
- 10.0.1
+ 10.0.2
+ 10.0.2
+ 10.0.2
.NET 10 ready
ldap-ad-identity-auth-openid-oauth-security
diff --git a/demo/Bitai.LDAPHelper.Demo/DemoContext.cs b/demo/Bitai.LDAPHelper.Demo/DemoContext.cs
index a4717d1..f8d36c9 100644
--- a/demo/Bitai.LDAPHelper.Demo/DemoContext.cs
+++ b/demo/Bitai.LDAPHelper.Demo/DemoContext.cs
@@ -3,11 +3,29 @@
namespace Bitai.LDAPHelper.Demo;
+///
+/// Holds runtime context and resolved settings for demo execution.
+///
public class DemoContext
{
+ ///
+ /// Gets or sets which LDAP implementation to use.
+ ///
public ImplementationType Implementation { get; set; }
+
+ ///
+ /// Gets or sets the connection-factory implementation used by demos.
+ ///
public ILdapConnectionFactoryAdapter ConnectionFactory { get; set; }
+
+ ///
+ /// Gets or sets loaded demo configuration.
+ ///
public DemoSetup Configuration { get; set; }
+
+ ///
+ /// Gets or sets the request label used by demo operations.
+ ///
public string RequestLabel { get; set; } = "My Demo";
// Connection settings
@@ -19,6 +37,10 @@ public class DemoContext
public string SelectedDomainAccountPassword { get; set; }
public string SelectedBaseDN { get; set; }
+ ///
+ /// Builds a instance from selected demo settings.
+ ///
+ /// Connection settings.
public ConnectionInfo GetConnectionInfo()
{
return new ConnectionInfo(
@@ -28,6 +50,10 @@ public ConnectionInfo GetConnectionInfo()
SelectedConnectionTimeout);
}
+ ///
+ /// Builds a domain-account credential from selected demo settings.
+ ///
+ /// Domain-account credential.
public LDAPDomainAccountCredential GetDomainAccountCredential()
{
var parts = SelectedDomainAccountName.Split(new char[] { '\\' });
@@ -37,6 +63,10 @@ public LDAPDomainAccountCredential GetDomainAccountCredential()
SelectedDomainAccountPassword);
}
+ ///
+ /// Builds search limits from selected demo settings.
+ ///
+ /// Search-limit settings.
public SearchLimits GetSearchLimits()
{
return new SearchLimits(SelectedBaseDN)
@@ -46,6 +76,10 @@ public SearchLimits GetSearchLimits()
};
}
+ ///
+ /// Builds a full client configuration from selected demo settings.
+ ///
+ /// Client configuration for helper classes.
public ClientConfiguration GetClientConfiguration()
{
return new ClientConfiguration(
@@ -53,4 +87,4 @@ public ClientConfiguration GetClientConfiguration()
GetDomainAccountCredential(),
GetSearchLimits());
}
-}
\ No newline at end of file
+}
diff --git a/demo/Bitai.LDAPHelper.Demo/DemoSetup.cs b/demo/Bitai.LDAPHelper.Demo/DemoSetup.cs
index 2dcfe1b..61ea002 100644
--- a/demo/Bitai.LDAPHelper.Demo/DemoSetup.cs
+++ b/demo/Bitai.LDAPHelper.Demo/DemoSetup.cs
@@ -1,16 +1,36 @@
-namespace Bitai.LDAPHelper.Demo;
+namespace Bitai.LDAPHelper.Demo;
+///
+/// Selects the LDAP implementation used by demo scenarios.
+///
public enum ImplementationType {
Novell,
Mock
}
+///
+/// Represents configuration values used by demo scenarios.
+///
public class DemoSetup
{
+ ///
+ /// Gets or sets available LDAP server endpoints for selection.
+ ///
public Ldapserver[] LdapServers { get; set; }
+
+ ///
+ /// Gets or sets available Base DN values for selection.
+ ///
public Basedn[] BaseDNs { get; set; }
+
+ ///
+ /// Gets or sets default LDAP connection timeout in seconds.
+ ///
public short ConnectionTimeout { get; set; }
+ ///
+ /// Gets or sets the domain account used as operator account during demo execution.
+ ///
public string DomainUserAccountForRunTests { get; set; }
public bool Demo_AccountManager_CreateUserAccount_RunTest { get; set; }
@@ -57,12 +77,24 @@ public class DemoSetup
public string Demo_GroupMembershipValidator_CheckGroupmembership_Check_GroupName { get; set; }
}
+///
+/// Represents an LDAP server option in demo configuration.
+///
public class Ldapserver
{
+ ///
+ /// Gets or sets the LDAP server address.
+ ///
public string Address { get; set; }
}
+///
+/// Represents a Base DN option in demo configuration.
+///
public class Basedn
{
+ ///
+ /// Gets or sets the base distinguished name.
+ ///
public string DN { get; set; }
}
diff --git a/demo/Bitai.LDAPHelper.Demo/DemoSummary.cs b/demo/Bitai.LDAPHelper.Demo/DemoSummary.cs
index d983ec1..81d5de9 100644
--- a/demo/Bitai.LDAPHelper.Demo/DemoSummary.cs
+++ b/demo/Bitai.LDAPHelper.Demo/DemoSummary.cs
@@ -4,11 +4,20 @@
namespace Bitai.LDAPHelper.Demo;
+///
+/// Collects and prints summary information for executed demo scenarios.
+///
public class DemoSummary
{
private readonly Dictionary _demoResults = new Dictionary();
private readonly List _errors = new List();
+ ///
+ /// Records the result of one demo scenario.
+ ///
+ /// Scenario name.
+ /// Whether the scenario succeeded.
+ /// Optional error associated with failure.
public void RecordDemoResult(string demoName, bool success, Exception error = null)
{
_demoResults[demoName] = success;
@@ -18,6 +27,9 @@ public void RecordDemoResult(string demoName, bool success, Exception error = nu
}
}
+ ///
+ /// Prints an aggregated summary for all recorded demo results.
+ ///
public void PrintSummary()
{
Console.WriteLine();
@@ -60,4 +72,4 @@ public void PrintSummary()
Console.WriteLine("================================================");
}
-}
\ No newline at end of file
+}
diff --git a/src/Bitai.LDAPHelper.DTO/Bitai.LDAPHelper.DTO.csproj b/src/Bitai.LDAPHelper.DTO/Bitai.LDAPHelper.DTO.csproj
index a77f921..380d235 100644
--- a/src/Bitai.LDAPHelper.DTO/Bitai.LDAPHelper.DTO.csproj
+++ b/src/Bitai.LDAPHelper.DTO/Bitai.LDAPHelper.DTO.csproj
@@ -2,9 +2,9 @@
net10.0
- 10.0.0
- 10.0.0
- 10.0.0
+ 10.0.1
+ 10.0.1
+ 10.0.1
Bitai.LDAPHelper.DTO
true
Viko Bastidas (BITAI)
diff --git a/src/Bitai.LDAPHelper.DTO/Enums.cs b/src/Bitai.LDAPHelper.DTO/Enums.cs
index a782a51..d836b68 100644
--- a/src/Bitai.LDAPHelper.DTO/Enums.cs
+++ b/src/Bitai.LDAPHelper.DTO/Enums.cs
@@ -1,9 +1,12 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Text;
namespace Bitai.LDAPHelper.DTO
{
+ ///
+ /// LDAP entry attributes that can be loaded or filtered.
+ ///
public enum EntryAttribute
{
///
@@ -41,6 +44,9 @@ public enum EntryAttribute
userAccountControl
}
+ ///
+ /// Predefined attribute sets used by search operations.
+ ///
public enum RequiredEntryAttributes
{
Minimun,
diff --git a/src/Bitai.LDAPHelper.DTO/ISecureCloningCredential.cs b/src/Bitai.LDAPHelper.DTO/ISecureCloningCredential.cs
index 736ad20..b7f02de 100644
--- a/src/Bitai.LDAPHelper.DTO/ISecureCloningCredential.cs
+++ b/src/Bitai.LDAPHelper.DTO/ISecureCloningCredential.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -6,8 +6,16 @@
namespace Bitai.LDAPHelper.DTO
{
+ ///
+ /// Defines secure cloning behavior used to remove or mask sensitive credential values.
+ ///
+ /// Credential type returned by the secure clone operation.
internal interface ISecureCloningCredential
{
+ ///
+ /// Creates a secure clone suitable for logging or transport without exposing secrets.
+ ///
+ /// A cloned credential with sensitive data removed or masked.
T SecureClone();
}
}
diff --git a/src/Bitai.LDAPHelper.DTO/LDAPCreateMsADUserAccountResult.cs b/src/Bitai.LDAPHelper.DTO/LDAPCreateMsADUserAccountResult.cs
index 65426e2..045304f 100644
--- a/src/Bitai.LDAPHelper.DTO/LDAPCreateMsADUserAccountResult.cs
+++ b/src/Bitai.LDAPHelper.DTO/LDAPCreateMsADUserAccountResult.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -6,8 +6,14 @@
namespace Bitai.LDAPHelper.DTO
{
+ ///
+ /// Represents the result of an MS Active Directory user-account creation operation.
+ ///
public class LDAPCreateMsADUserAccountResult : LDAPOperationResult
{
+ ///
+ /// Gets or sets the created user account payload.
+ ///
public LDAPMsADUserAccount UserAccount { get; set; }
@@ -21,6 +27,13 @@ public LDAPCreateMsADUserAccountResult()
//Do not remove this constructor, it is required to deserialize data.
}
+ ///
+ /// Initializes a result for user-account creation.
+ ///
+ /// Created user account data.
+ /// Optional request label.
+ /// Operation message.
+ /// Whether the operation is marked successful.
public LDAPCreateMsADUserAccountResult(LDAPMsADUserAccount newUserAccount, string requestLabel = null, string operationMessage = "Operation completed", bool isSuccessfulOperation = true) : base(requestLabel, isSuccessfulOperation)
{
if (newUserAccount == null)
@@ -30,6 +43,12 @@ public LDAPCreateMsADUserAccountResult(LDAPMsADUserAccount newUserAccount, strin
OperationMessage = operationMessage;
}
+ ///
+ /// Initializes an unsuccessful creation result from an exception.
+ ///
+ /// Operation message.
+ /// Underlying error.
+ /// Optional request label.
public LDAPCreateMsADUserAccountResult(string operationMessage, Exception exception, string requestLabel = null) : base(operationMessage, exception, requestLabel)
{
}
diff --git a/src/Bitai.LDAPHelper.DTO/LDAPDisableUserAccountOperationResult.cs b/src/Bitai.LDAPHelper.DTO/LDAPDisableUserAccountOperationResult.cs
index fd1916c..c8caab6 100644
--- a/src/Bitai.LDAPHelper.DTO/LDAPDisableUserAccountOperationResult.cs
+++ b/src/Bitai.LDAPHelper.DTO/LDAPDisableUserAccountOperationResult.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -6,6 +6,9 @@
namespace Bitai.LDAPHelper.DTO
{
+ ///
+ /// Represents the result of a user-account disable operation.
+ ///
public class LDAPDisableUserAccountOperationResult : LDAPOperationResult
{
///
@@ -16,10 +19,21 @@ public LDAPDisableUserAccountOperationResult()
//Do not remove this constructor, it is required to deserialize data.
}
+ ///
+ /// Initializes a result for a disable operation.
+ ///
+ /// Optional request label.
+ /// Whether the operation is marked successful.
public LDAPDisableUserAccountOperationResult(string requestLabel = null, bool isSuccessfulOperation = true) : base(requestLabel, isSuccessfulOperation)
{
}
+ ///
+ /// Initializes an unsuccessful disable-operation result from an exception.
+ ///
+ /// Operation message.
+ /// Underlying error.
+ /// Optional request label.
public LDAPDisableUserAccountOperationResult(string operationMessage, Exception exception, string requestLabel = null) : base(operationMessage, exception, requestLabel)
{
}
diff --git a/src/Bitai.LDAPHelper.DTO/LDAPDistinguishedNameAuthenticationResult.cs b/src/Bitai.LDAPHelper.DTO/LDAPDistinguishedNameAuthenticationResult.cs
index 7299666..e96a45c 100644
--- a/src/Bitai.LDAPHelper.DTO/LDAPDistinguishedNameAuthenticationResult.cs
+++ b/src/Bitai.LDAPHelper.DTO/LDAPDistinguishedNameAuthenticationResult.cs
@@ -1,4 +1,4 @@
-using System.Net;
+using System.Net;
using System;
namespace Bitai.LDAPHelper.DTO;
@@ -9,6 +9,9 @@ namespace Bitai.LDAPHelper.DTO;
///
public class LDAPDistinguishedNameAuthenticationResult: LDAPOperationResult
{
+ ///
+ /// Gets or sets the credential associated with this authentication attempt.
+ ///
public LDAPDistinguishedNameCredential Credential { get; set; }
///
@@ -28,15 +31,29 @@ public LDAPDistinguishedNameAuthenticationResult()
//Do not remove this constructor, it is required to deserialize data.
}
+ ///
+ /// Initializes an authentication result.
+ ///
+ /// Credential associated with the authentication attempt.
+ /// Authentication status.
+ /// Optional request label.
+ /// Whether the operation is marked successful.
public LDAPDistinguishedNameAuthenticationResult(LDAPDistinguishedNameCredential credential, bool isAuthenticated = true, string requestLabel = null, bool isSuccessfulOperation = true) : base(requestLabel, isSuccessfulOperation)
{
Credential = credential;
IsAuthenticated = isAuthenticated;
}
+ ///
+ /// Initializes an unsuccessful authentication result from an exception.
+ ///
+ /// Credential associated with the authentication attempt.
+ /// Operation message.
+ /// Underlying error.
+ /// Optional request label.
public LDAPDistinguishedNameAuthenticationResult(LDAPDistinguishedNameCredential credential, string operationMessage, Exception exception, string requestLabel = null) : base(operationMessage, exception, requestLabel)
{
Credential = credential;
IsAuthenticated = false;
}
-}
\ No newline at end of file
+}
diff --git a/src/Bitai.LDAPHelper.DTO/LDAPDistinguishedNameCredential.cs b/src/Bitai.LDAPHelper.DTO/LDAPDistinguishedNameCredential.cs
index 3e60aeb..b09563e 100644
--- a/src/Bitai.LDAPHelper.DTO/LDAPDistinguishedNameCredential.cs
+++ b/src/Bitai.LDAPHelper.DTO/LDAPDistinguishedNameCredential.cs
@@ -6,10 +6,19 @@
namespace Bitai.LDAPHelper.DTO
{
+ ///
+ /// Represents credentials based on a distinguished name and password.
+ ///
public class LDAPDistinguishedNameCredential : ISecureCloningCredential
{
+ ///
+ /// Gets or sets the account distinguished name.
+ ///
public string DistinguishedName { get; set; }
+ ///
+ /// Gets or sets the account password.
+ ///
public string Password { get; set; }
@@ -41,6 +50,10 @@ public LDAPDistinguishedNameCredential(string distinguishedName, string password
+ ///
+ /// Creates a clone with password removed.
+ ///
+ /// A cloned credential with sensitive information sanitized.
public LDAPDistinguishedNameCredential SecureClone()
{
var clone = new LDAPDistinguishedNameCredential
diff --git a/src/Bitai.LDAPHelper.DTO/LDAPDomainAccountAuthenticationResult.cs b/src/Bitai.LDAPHelper.DTO/LDAPDomainAccountAuthenticationResult.cs
index 4c748f7..bb772c9 100644
--- a/src/Bitai.LDAPHelper.DTO/LDAPDomainAccountAuthenticationResult.cs
+++ b/src/Bitai.LDAPHelper.DTO/LDAPDomainAccountAuthenticationResult.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
namespace Bitai.LDAPHelper.DTO;
@@ -8,6 +8,9 @@ namespace Bitai.LDAPHelper.DTO;
///
public class LDAPDomainAccountAuthenticationResult: LDAPOperationResult
{
+ ///
+ /// Gets or sets the credential associated with this authentication attempt.
+ ///
public LDAPDomainAccountCredential Credential { get; set; }
///
@@ -27,15 +30,29 @@ public LDAPDomainAccountAuthenticationResult()
//Do not remove this constructor, it is required to deserialize data.
}
+ ///
+ /// Initializes an authentication result.
+ ///
+ /// Credential associated with the authentication attempt.
+ /// Authentication status.
+ /// Optional request label.
+ /// Whether the operation is marked successful.
public LDAPDomainAccountAuthenticationResult(LDAPDomainAccountCredential credential, bool isAuthenticated = true, string requestLabel = null, bool isSuccessfulOperation = true) :base(requestLabel, isSuccessfulOperation)
{
Credential = credential;
IsAuthenticated = isAuthenticated;
}
+ ///
+ /// Initializes an unsuccessful authentication result from an exception.
+ ///
+ /// Credential associated with the authentication attempt.
+ /// Operation message.
+ /// Underlying error.
+ /// Optional request label.
public LDAPDomainAccountAuthenticationResult(LDAPDomainAccountCredential credential, string operationMessage, Exception exception, string requestLabel = null) : base(operationMessage, exception, requestLabel)
{
Credential = credential;
IsAuthenticated = false;
}
-}
\ No newline at end of file
+}
diff --git a/src/Bitai.LDAPHelper.DTO/LDAPDomainAccountCredential.cs b/src/Bitai.LDAPHelper.DTO/LDAPDomainAccountCredential.cs
index a2626d3..6271f08 100644
--- a/src/Bitai.LDAPHelper.DTO/LDAPDomainAccountCredential.cs
+++ b/src/Bitai.LDAPHelper.DTO/LDAPDomainAccountCredential.cs
@@ -7,12 +7,30 @@
namespace Bitai.LDAPHelper.DTO
{
+ ///
+ /// Represents domain-account credentials in Domain\\Account format.
+ ///
public class LDAPDomainAccountCredential : ISecureCloningCredential
{
+ ///
+ /// Gets or sets the domain name.
+ ///
public string DomainName { get; set; }
+
+ ///
+ /// Gets or sets the account (user) name.
+ ///
public string AccountName { get; set; }
+
+ ///
+ /// Gets the composite domain-account name in Domain\\Account format.
+ ///
[IgnoreDataMember]
public string DomainAccountName { get => $"{DomainName}\\{AccountName}"; }
+
+ ///
+ /// Gets or sets the account password.
+ ///
public string DomainAccountPassword { get; set; }
@@ -48,6 +66,10 @@ public LDAPDomainAccountCredential(string domainName, string username, string do
+ ///
+ /// Creates a clone with password removed.
+ ///
+ /// A cloned credential with sensitive information sanitized.
public LDAPDomainAccountCredential SecureClone()
{
return new LDAPDomainAccountCredential {
diff --git a/src/Bitai.LDAPHelper.DTO/LDAPEntry.cs b/src/Bitai.LDAPHelper.DTO/LDAPEntry.cs
index 1297556..4e768b4 100644
--- a/src/Bitai.LDAPHelper.DTO/LDAPEntry.cs
+++ b/src/Bitai.LDAPHelper.DTO/LDAPEntry.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Text;
@@ -20,6 +20,9 @@ public LDAPEntry(string requestLabel = null)
}
#endregion
+ ///
+ /// Gets or sets an optional caller-defined label used to correlate requests and results.
+ ///
public string RequestLabel { get; set; }
///
@@ -37,14 +40,29 @@ public LDAPEntry(string requestLabel = null)
///
public string company { get; set; }
+ ///
+ /// Country full name.
+ ///
public string co { get; set; }
+ ///
+ /// Description.
+ ///
public string description { get; set; }
+ ///
+ /// Department name.
+ ///
public string department { get; set; }
+ ///
+ /// Display name.
+ ///
public string displayName { get; set; }
+ ///
+ /// Distinguished name.
+ ///
public string distinguishedName { get; set; }
///
@@ -52,50 +70,120 @@ public LDAPEntry(string requestLabel = null)
///
public string givenName { get; set; }
+ ///
+ /// Locality/city.
+ ///
public string l { get; set; }
+ ///
+ /// Last logon date/time.
+ ///
public DateTime? lastLogon { get; set; }
+ ///
+ /// Email address.
+ ///
public string mail { get; set; }
+ ///
+ /// Manager distinguished name.
+ ///
public string manager { get; set; }
+ ///
+ /// Members of this entry (for group entries).
+ ///
public string[] member { get; set; }
+ ///
+ /// Parent groups distinguished names.
+ ///
public string[] memberOf { get; set; }
+ ///
+ /// Parent entries expanded from .
+ ///
public IEnumerable memberOfEntries { get; set; }
+ ///
+ /// LDAP name attribute.
+ ///
public string name { get; set; }
+ ///
+ /// Object category.
+ ///
public string objectCategory { get; set; }
+ ///
+ /// Object classes.
+ ///
public string[] objectClass { get; set; }
+ ///
+ /// sAMAccountName.
+ ///
public string samAccountName { get; set; }
+ ///
+ /// sAMAccountType symbolic value.
+ ///
public string samAccountType { get; set; }
+ ///
+ /// Surname.
+ ///
public string sn { get; set; }
+ ///
+ /// Telephone number.
+ ///
public string telephoneNumber { get; set; }
+ ///
+ /// Job title.
+ ///
public string title { get; set; }
+ ///
+ /// User principal name.
+ ///
public string userPrincipalName { get; set; }
+ ///
+ /// Entry creation date/time.
+ ///
public DateTime? whenCreated { get; set; }
+ ///
+ /// Object GUID string.
+ ///
public string objectGuid { get; set; }
+ ///
+ /// Object GUID bytes.
+ ///
public byte[] objectGuidBytes { get; set; }
+ ///
+ /// Object SID string.
+ ///
public string objectSid { get; set; }
+ ///
+ /// Object SID bytes.
+ ///
public byte[] objectSidBytes { get; set; }
+ ///
+ /// Raw userAccountControl attribute value.
+ ///
public string? userAccountControl { get; set; }
+ ///
+ /// Recursively gets all parent entries from the hierarchy.
+ ///
+ /// A flattened sequence of parent entries.
public IEnumerable GetMemberOfEntriesRecursively()
{
var _list = new List();
@@ -114,6 +202,12 @@ public IEnumerable GetMemberOfEntriesRecursively()
#region IComparable Members
+ ///
+ /// Compares this entry with another by distinguished name.
+ ///
+ /// Entry to compare against.
+ /// Comparison result.
+ /// Thrown when is not an .
public int CompareTo(object obj)
{
if (obj is LDAPEntry)
diff --git a/src/Bitai.LDAPHelper.DTO/LDAPMsADUserAccount.cs b/src/Bitai.LDAPHelper.DTO/LDAPMsADUserAccount.cs
index 678d391..e53ab83 100644
--- a/src/Bitai.LDAPHelper.DTO/LDAPMsADUserAccount.cs
+++ b/src/Bitai.LDAPHelper.DTO/LDAPMsADUserAccount.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -57,18 +57,68 @@ public LDAPMsADUserAccount(string distinguishedNmaeOfContainer) : this()
+ ///
+ /// Gets or sets the distinguished name of the container where the user account should be created.
+ ///
public string DistinguishedNameOfContainer { get => distinguishedNameOfContainer; set => distinguishedNameOfContainer = value; }
+
+ ///
+ /// Gets or sets the user's given name.
+ ///
public string GivenName { get => givenName; set => givenName = value; }
+
+ ///
+ /// Gets or sets the user's surname.
+ ///
public string Sn { get => sn; set => sn = value; }
+
+ ///
+ /// Gets or sets the user common name (CN).
+ ///
public string Cn { get => cn; set => cn = value; }
+
+ ///
+ /// Gets or sets the LDAP name attribute.
+ ///
public string Name { get => name; set => name = value; }
+
+ ///
+ /// Gets or sets the display name.
+ ///
public string DisplayName { get => displayName; set => displayName = value; }
+
+ ///
+ /// Gets or sets the account description.
+ ///
public string Description { get => description; set => description = value; }
+
+ ///
+ /// Gets or sets the full distinguished name of the user account.
+ ///
public string DistinguishedName { get => distinguishedName; set => distinguishedName = value; }
+
+ ///
+ /// Gets or sets parent groups (distinguished names) this account belongs to.
+ ///
public string[] MemberOf { get => memberOf; set => memberOf = value; }
+
+ ///
+ /// Gets or sets LDAP object classes for this account.
+ ///
public string[] ObjectClass { get => objectClass; set => objectClass = value; }
+
+ ///
+ /// Gets or sets the sAMAccountName value.
+ ///
public string SAMAccountName { get => samAccountName; set => samAccountName = value; }
+
+ ///
+ /// Gets or sets the user principal name (UPN).
+ ///
public string UserPrincipalName { get => userPrincipalName; set => userPrincipalName = value; }
+ ///
+ /// Gets or sets user-account-control flags as a comma-separated list of names.
+ ///
public string UserAccountControl
{
get => userAccountControl;
@@ -100,14 +150,37 @@ public string UserAccountControl
}
}
}
+ ///
+ /// Gets or sets the department.
+ ///
public string Department { get => department; set => department = value; }
+
+ ///
+ /// Gets or sets the phone number.
+ ///
public string TelephoneNumber { get => telephoneNumber; set => telephoneNumber = value; }
+
+ ///
+ /// Gets or sets the email address.
+ ///
public string Mail { get => mail; set => mail = value; }
+
+ ///
+ /// Gets or sets the account password.
+ ///
public string Password { get => password; set => password = value; }
+
+ ///
+ /// Gets parsed account-control flags derived from .
+ ///
public UserAccountControlFlagsForMsAD? UserAccountControlFlags { get => userAccountControlFlags; }
+ ///
+ /// Creates a secure clone with password masked.
+ ///
+ /// A cloned account suitable for logging/transport.
public LDAPMsADUserAccount SecureClone()
{
return new LDAPMsADUserAccount
diff --git a/src/Bitai.LDAPHelper.DTO/LDAPPasswordUpdateResult.cs b/src/Bitai.LDAPHelper.DTO/LDAPPasswordUpdateResult.cs
index 9643172..049ae01 100644
--- a/src/Bitai.LDAPHelper.DTO/LDAPPasswordUpdateResult.cs
+++ b/src/Bitai.LDAPHelper.DTO/LDAPPasswordUpdateResult.cs
@@ -1,4 +1,4 @@
-using Microsoft.VisualBasic;
+using Microsoft.VisualBasic;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
@@ -6,22 +6,37 @@
namespace Bitai.LDAPHelper.DTO
{
+ ///
+ /// Represents the result of an LDAP password update operation.
+ ///
public class LDAPPasswordUpdateResult : LDAPOperationResult
{
///
- /// Defaulr constructor.
+ /// Default constructor.
///
public LDAPPasswordUpdateResult() {
//Do not remove this constructor, it is required to deserialize data.
}
+ ///
+ /// Initializes a password-update result.
+ ///
+ /// Optional request label.
+ /// Operation message.
+ /// Whether the operation is marked successful.
public LDAPPasswordUpdateResult(string requesttag = null, string operationMessage = "Operation completed.", bool isSuccessfulOperation = true) : base(requesttag, isSuccessfulOperation)
{
OperationMessage = operationMessage;
}
+ ///
+ /// Initializes an unsuccessful password-update result from an exception.
+ ///
+ /// Operation message.
+ /// Underlying error.
+ /// Optional request label.
public LDAPPasswordUpdateResult(string operationMessage, Exception ex, string requestLabel = null) : base(operationMessage, ex, requestLabel)
{
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Bitai.LDAPHelper.DTO/LDAPRemoveMsADUserAccountResult.cs b/src/Bitai.LDAPHelper.DTO/LDAPRemoveMsADUserAccountResult.cs
index 3d87df1..38b723a 100644
--- a/src/Bitai.LDAPHelper.DTO/LDAPRemoveMsADUserAccountResult.cs
+++ b/src/Bitai.LDAPHelper.DTO/LDAPRemoveMsADUserAccountResult.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -6,6 +6,9 @@
namespace Bitai.LDAPHelper.DTO
{
+ ///
+ /// Represents the result of an MS Active Directory user-account removal operation.
+ ///
public class LDAPRemoveMsADUserAccountResult : LDAPOperationResult
{
///
@@ -16,11 +19,23 @@ public LDAPRemoveMsADUserAccountResult()
//Do not remove this constructor, it is required to deserialize data.
}
+ ///
+ /// Initializes a remove-account operation result.
+ ///
+ /// Optional request label.
+ /// Operation message.
+ /// Whether the operation is marked successful.
public LDAPRemoveMsADUserAccountResult(string requestLabel = null, string operationMessage = "Operation completed", bool isSuccessfulOperation = true) : base(requestLabel, isSuccessfulOperation)
{
OperationMessage = operationMessage;
}
+ ///
+ /// Initializes an unsuccessful remove-account result from an exception.
+ ///
+ /// Operation message.
+ /// Underlying error.
+ /// Optional request label.
public LDAPRemoveMsADUserAccountResult(string operationMessage, Exception exception, string requestLabel = null) : base(operationMessage, exception, requestLabel)
{
}
diff --git a/src/Bitai.LDAPHelper.DTO/LDAPSearchResult.cs b/src/Bitai.LDAPHelper.DTO/LDAPSearchResult.cs
index ee1865d..5ce3d88 100644
--- a/src/Bitai.LDAPHelper.DTO/LDAPSearchResult.cs
+++ b/src/Bitai.LDAPHelper.DTO/LDAPSearchResult.cs
@@ -1,10 +1,13 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
namespace Bitai.LDAPHelper.DTO
{
+ ///
+ /// Represents the result of an LDAP search operation.
+ ///
public class LDAPSearchResult : LDAPOperationResult
{
///
@@ -16,13 +19,20 @@ public class LDAPSearchResult : LDAPOperationResult
///
- /// Defaulr constructor.
+ /// Default constructor.
///
public LDAPSearchResult()
{
//Do not remove this constructor, it is required to deserialize data.
}
+ ///
+ /// Initializes a successful or unsuccessful search result with entries.
+ ///
+ /// Optional request label.
+ /// Entries returned by the search.
+ /// Operation message.
+ /// Whether the operation is marked successful.
public LDAPSearchResult(string requestLabel = null, IEnumerable entries = null, string operationMessage = "Operation completed.", bool isSuccessfulOperation = true) : base(requestLabel, isSuccessfulOperation)
{
if (entries != null)
@@ -33,8 +43,14 @@ public LDAPSearchResult(string requestLabel = null, IEnumerable
+ /// Initializes an unsuccessful search result from an exception.
+ ///
+ /// Operation message.
+ /// Underlying error.
+ /// Optional request label.
public LDAPSearchResult(string operationMessage, Exception exception, string requestLabel = null) : base(operationMessage, exception, requestLabel)
{
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Bitai.LDAPHelper.LdapAdapters/Enums.cs b/src/Bitai.LDAPHelper.LdapAdapters/Enums.cs
index b4a98aa..69f71f5 100644
--- a/src/Bitai.LDAPHelper.LdapAdapters/Enums.cs
+++ b/src/Bitai.LDAPHelper.LdapAdapters/Enums.cs
@@ -5,8 +5,19 @@ namespace Bitai.LDAPHelper.LdapAdapters;
///
public enum LdapModificationType
{
+ ///
+ /// Adds an attribute value.
+ ///
Add = 0,
+
+ ///
+ /// Deletes an attribute value.
+ ///
Delete = 1,
+
+ ///
+ /// Replaces an attribute value.
+ ///
Replace = 2
}
@@ -15,7 +26,18 @@ public enum LdapModificationType
///
public enum LdapSearchScope
{
+ ///
+ /// Search only the base object.
+ ///
ScopeBase = 0,
+
+ ///
+ /// Search one level below the base object.
+ ///
ScopeOne = 1,
+
+ ///
+ /// Search the entire subtree below the base object.
+ ///
ScopeSub = 2
}
diff --git a/src/Bitai.LDAPHelper.LdapAdapters/IConnectionInfo.cs b/src/Bitai.LDAPHelper.LdapAdapters/IConnectionInfo.cs
index 6805831..cfceba1 100644
--- a/src/Bitai.LDAPHelper.LdapAdapters/IConnectionInfo.cs
+++ b/src/Bitai.LDAPHelper.LdapAdapters/IConnectionInfo.cs
@@ -1,9 +1,27 @@
namespace Bitai.LDAPHelper.LdapAdapters;
+///
+/// Defines LDAP server connection settings required to open an LDAP connection.
+///
public interface IConnectionInfo
{
+ ///
+ /// Gets the connection timeout in seconds.
+ ///
short ConnectionTimeout { get; }
+
+ ///
+ /// Gets the LDAP server host name or IP address.
+ ///
string Server { get; }
+
+ ///
+ /// Gets the LDAP server port.
+ ///
int ServerPort { get; }
+
+ ///
+ /// Gets a value indicating whether SSL must be used.
+ ///
bool UseSSL { get; }
}
diff --git a/src/Bitai.LDAPHelper.LdapAdapters/ILdapAttributeAdapter.cs b/src/Bitai.LDAPHelper.LdapAdapters/ILdapAttributeAdapter.cs
index e62a059..221721b 100644
--- a/src/Bitai.LDAPHelper.LdapAdapters/ILdapAttributeAdapter.cs
+++ b/src/Bitai.LDAPHelper.LdapAdapters/ILdapAttributeAdapter.cs
@@ -1,12 +1,27 @@
-namespace Bitai.LDAPHelper.LdapAdapters;
+namespace Bitai.LDAPHelper.LdapAdapters;
///
-/// Target interface for LDAP attribute operations
+/// Defines read access to LDAP attribute values in multiple representations.
///
public interface ILdapAttributeAdapter
{
+ ///
+ /// Gets the first binary value of the attribute.
+ ///
byte[] ByteValue { get; }
+
+ ///
+ /// Gets the first string value of the attribute.
+ ///
string StringValue { get; }
+
+ ///
+ /// Gets all string values of the attribute.
+ ///
string[] StringValueArray { get; }
- public byte[][] ByteValueArray { get; }
-}
\ No newline at end of file
+
+ ///
+ /// Gets all binary values of the attribute.
+ ///
+ byte[][] ByteValueArray { get; }
+}
diff --git a/src/Bitai.LDAPHelper.LdapAdapters/ILdapAttributeSetAdapter.cs b/src/Bitai.LDAPHelper.LdapAdapters/ILdapAttributeSetAdapter.cs
index 4b5c354..2180fc6 100644
--- a/src/Bitai.LDAPHelper.LdapAdapters/ILdapAttributeSetAdapter.cs
+++ b/src/Bitai.LDAPHelper.LdapAdapters/ILdapAttributeSetAdapter.cs
@@ -1,13 +1,42 @@
-namespace Bitai.LDAPHelper.LdapAdapters;
+namespace Bitai.LDAPHelper.LdapAdapters;
///
-/// Target interface for LDAP AttributeSet operations
+/// Defines operations for building and reading LDAP attribute sets.
///
public interface ILdapAttributeSetAdapter
{
+ ///
+ /// Adds a single string value to an attribute.
+ ///
+ /// Attribute name.
+ /// Attribute value.
void AddAttribute(string name, string value);
+
+ ///
+ /// Adds multiple string values to an attribute.
+ ///
+ /// Attribute name.
+ /// Attribute values.
void AddAttribute(string name, string[] values);
+
+ ///
+ /// Adds a binary value to an attribute.
+ ///
+ /// Attribute name.
+ /// Binary attribute value.
void AddAttribute(string name, byte[] value);
+
+ ///
+ /// Determines whether an attribute exists in the set.
+ ///
+ /// Attribute name to look up.
+ /// if found; otherwise .
bool ContainsKey(string attributeName);
+
+ ///
+ /// Gets an attribute by name.
+ ///
+ /// Attribute name.
+ /// The attribute adapter when found; otherwise .
ILdapAttributeAdapter GetAttribute(string attributeName);
-}
\ No newline at end of file
+}
diff --git a/src/Bitai.LDAPHelper.LdapAdapters/ILdapConnectionAdapter.cs b/src/Bitai.LDAPHelper.LdapAdapters/ILdapConnectionAdapter.cs
index 093bd97..ea0e4d0 100644
--- a/src/Bitai.LDAPHelper.LdapAdapters/ILdapConnectionAdapter.cs
+++ b/src/Bitai.LDAPHelper.LdapAdapters/ILdapConnectionAdapter.cs
@@ -5,22 +5,97 @@
namespace Bitai.LDAPHelper.LdapAdapters;
///
-/// Target interface for LDAP connection operations
+/// Defines the operations required to manage and use an LDAP connection.
///
public interface ILdapConnectionAdapter : IDisposable
{
+ ///
+ /// Gets or sets the connection timeout in milliseconds.
+ ///
int ConnectionTimeout { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether SSL is enabled.
+ ///
bool SecureSocketLayer { get; set; }
+
+ ///
+ /// Gets a value indicating whether the connection is authenticated (bound).
+ ///
bool IsBound { get; }
+ ///
+ /// Bypasses server certificate validation.
+ ///
+ /// Use only in controlled environments.
void ServerCertificateValidationByPass();
+
+ ///
+ /// Connects to the LDAP server.
+ ///
+ /// Server host name or IP address.
+ /// Server port.
+ /// A task that completes when the connection is established.
Task ConnectAsync(string host, int port);
+
+ ///
+ /// Authenticates the connection.
+ ///
+ /// User distinguished name or account identifier.
+ /// Account password.
+ /// A task that completes when bind finishes.
Task BindAsync(string userDN, string password);
+
+ ///
+ /// Executes an LDAP search.
+ ///
+ /// Search boundaries and limits.
+ /// LDAP filter expression.
+ /// Attributes to return.
+ /// Whether only attribute names should be returned.
+ /// A queue adapter with server responses.
Task SearchAsync(ISearchLimits searchLimits, string searchFilter, string[] attributeNames, bool typesOnly);
+
+ ///
+ /// Creates an empty attribute set for add/update operations.
+ ///
+ /// An attribute set adapter.
ILdapAttributeSetAdapter CreateAttributeSet();
+
+ ///
+ /// Adds an entry to the directory.
+ ///
+ /// Distinguished name for the new entry.
+ /// Attribute set for the new entry.
+ /// A task that completes when the entry is created.
Task AddEntryAsync(string distinguishedName, ILdapAttributeSetAdapter attributes);
+
+ ///
+ /// Creates a modification descriptor.
+ ///
+ /// Modification type.
+ /// Attribute name to modify.
+ /// New attribute value.
+ /// A modification adapter.
ILdapModificationAdapter CreateModification(LdapModificationType type, string attributeName, object value);
+
+ ///
+ /// Applies modifications to an existing entry.
+ ///
+ /// Target entry distinguished name.
+ /// Modifications to apply.
+ /// A task that completes when the update finishes.
Task ModifyEntryAsync(string distinguishedName, IEnumerable modifications);
+
+ ///
+ /// Deletes an entry from the directory.
+ ///
+ /// Target entry distinguished name.
+ /// A task that completes when deletion finishes.
Task DeleteEntryAsync(string distinguishedName);
+
+ ///
+ /// Disconnects the connection from the server.
+ ///
void Disconnect();
}
diff --git a/src/Bitai.LDAPHelper.LdapAdapters/ILdapConnectionFactoryAdapter.cs b/src/Bitai.LDAPHelper.LdapAdapters/ILdapConnectionFactoryAdapter.cs
index cd0ed38..f774df8 100644
--- a/src/Bitai.LDAPHelper.LdapAdapters/ILdapConnectionFactoryAdapter.cs
+++ b/src/Bitai.LDAPHelper.LdapAdapters/ILdapConnectionFactoryAdapter.cs
@@ -1,10 +1,20 @@
namespace Bitai.LDAPHelper.LdapAdapters;
///
-/// Factory interface for creating LDAP connections
+/// Defines a factory for creating initialized LDAP connections.
///
public interface ILdapConnectionFactoryAdapter
{
+ ///
+ /// Creates a new LDAP connection and optionally binds it with credentials.
+ ///
+ /// Server connection settings.
+ /// Account identifier used for bind.
+ /// Account password used for bind.
+ ///
+ /// to fail when bind cannot be completed; otherwise .
+ ///
+ /// A task with an initialized LDAP connection adapter.
Task CreateConnectionAsync(
IConnectionInfo connectionInfo,
string userAccount,
diff --git a/src/Bitai.LDAPHelper.LdapAdapters/ILdapEntryAdapter.cs b/src/Bitai.LDAPHelper.LdapAdapters/ILdapEntryAdapter.cs
index 1ca70a0..6a721c7 100644
--- a/src/Bitai.LDAPHelper.LdapAdapters/ILdapEntryAdapter.cs
+++ b/src/Bitai.LDAPHelper.LdapAdapters/ILdapEntryAdapter.cs
@@ -1,10 +1,18 @@
-namespace Bitai.LDAPHelper.LdapAdapters;
+namespace Bitai.LDAPHelper.LdapAdapters;
///
-/// Target interface for LDAP entry operations
+/// Defines read access to an LDAP entry and its attribute set.
///
public interface ILdapEntryAdapter
{
+ ///
+ /// Gets the distinguished name of the entry.
+ ///
string DistinguishedName { get; }
+
+ ///
+ /// Gets the attribute set associated with the entry.
+ ///
+ /// An attribute set adapter.
ILdapAttributeSetAdapter GetAttributeSet();
-}
\ No newline at end of file
+}
diff --git a/src/Bitai.LDAPHelper.LdapAdapters/ILdapMessageAdapter.cs b/src/Bitai.LDAPHelper.LdapAdapters/ILdapMessageAdapter.cs
index 2572d77..d801c69 100644
--- a/src/Bitai.LDAPHelper.LdapAdapters/ILdapMessageAdapter.cs
+++ b/src/Bitai.LDAPHelper.LdapAdapters/ILdapMessageAdapter.cs
@@ -1,11 +1,22 @@
-namespace Bitai.LDAPHelper.LdapAdapters;
+namespace Bitai.LDAPHelper.LdapAdapters;
///
-/// Target interface for LDAP message operations
+/// Defines accessors for LDAP protocol messages returned by search operations.
///
public interface ILdapMessageAdapter
{
+ ///
+ /// Gets the LDAP entry when the message represents a search result; otherwise .
+ ///
ILdapEntryAdapter Entry { get; }
+
+ ///
+ /// Gets a value indicating whether this message is a search-result message.
+ ///
bool IsSearchResult { get; }
+
+ ///
+ /// Gets a value indicating whether this message signals end-of-search.
+ ///
bool IsSearchDone { get; }
-}
\ No newline at end of file
+}
diff --git a/src/Bitai.LDAPHelper.LdapAdapters/ILdapModificationAdapter.cs b/src/Bitai.LDAPHelper.LdapAdapters/ILdapModificationAdapter.cs
index aab97a7..5abf8df 100644
--- a/src/Bitai.LDAPHelper.LdapAdapters/ILdapModificationAdapter.cs
+++ b/src/Bitai.LDAPHelper.LdapAdapters/ILdapModificationAdapter.cs
@@ -1,10 +1,17 @@
-namespace Bitai.LDAPHelper.LdapAdapters;
+namespace Bitai.LDAPHelper.LdapAdapters;
///
-/// Adapter for LDAP modification operations
+/// Defines access to a single LDAP modification operation.
///
public interface ILdapModificationAdapter
{
+ ///
+ /// Gets the modification operation type.
+ ///
LdapModificationType ModificationType { get; }
+
+ ///
+ /// Gets the attribute associated with the modification.
+ ///
ILdapAttributeAdapter Attribute { get; }
-}
\ No newline at end of file
+}
diff --git a/src/Bitai.LDAPHelper.LdapAdapters/ILdapSearchConstraintsAdapter.cs b/src/Bitai.LDAPHelper.LdapAdapters/ILdapSearchConstraintsAdapter.cs
index 403b1f2..22cdc4b 100644
--- a/src/Bitai.LDAPHelper.LdapAdapters/ILdapSearchConstraintsAdapter.cs
+++ b/src/Bitai.LDAPHelper.LdapAdapters/ILdapSearchConstraintsAdapter.cs
@@ -1,10 +1,17 @@
-namespace Bitai.LDAPHelper.LdapAdapters;
+namespace Bitai.LDAPHelper.LdapAdapters;
///
-/// Target interface for LDAP search constraints
+/// Defines LDAP server-side search constraints.
///
public interface ILdapSearchConstraintsAdapter
{
+ ///
+ /// Gets or sets the server-side time limit in seconds.
+ ///
int ServerTimeLimit { get; set; }
+
+ ///
+ /// Gets or sets the maximum number of entries returned by the server.
+ ///
int MaxResults { get; set; }
-}
\ No newline at end of file
+}
diff --git a/src/Bitai.LDAPHelper.LdapAdapters/ILdapSearchQueueAdapter.cs b/src/Bitai.LDAPHelper.LdapAdapters/ILdapSearchQueueAdapter.cs
index 7c01ac6..bc77109 100644
--- a/src/Bitai.LDAPHelper.LdapAdapters/ILdapSearchQueueAdapter.cs
+++ b/src/Bitai.LDAPHelper.LdapAdapters/ILdapSearchQueueAdapter.cs
@@ -1,9 +1,13 @@
-namespace Bitai.LDAPHelper.LdapAdapters;
+namespace Bitai.LDAPHelper.LdapAdapters;
///
-/// Target interface for LDAP search queue operations
+/// Defines access to queued LDAP search responses.
///
public interface ILdapSearchQueueAdapter
{
+ ///
+ /// Gets the next response from the queue.
+ ///
+ /// The next message adapter; or when no more responses are available.
ILdapMessageAdapter GetResponse();
-}
\ No newline at end of file
+}
diff --git a/src/Bitai.LDAPHelper.LdapAdapters/ISearchLimits.cs b/src/Bitai.LDAPHelper.LdapAdapters/ISearchLimits.cs
index 281c880..df33418 100644
--- a/src/Bitai.LDAPHelper.LdapAdapters/ISearchLimits.cs
+++ b/src/Bitai.LDAPHelper.LdapAdapters/ISearchLimits.cs
@@ -1,9 +1,27 @@
namespace Bitai.LDAPHelper.LdapAdapters;
+///
+/// Defines LDAP search boundaries and limits.
+///
public interface ISearchLimits
{
+ ///
+ /// Gets or sets the base distinguished name from which the search starts.
+ ///
string BaseDN { get; set; }
+
+ ///
+ /// Gets or sets the LDAP search scope.
+ ///
LdapSearchScope LdapSearchScope { get; set; }
+
+ ///
+ /// Gets or sets the maximum number of entries to return.
+ ///
int MaxSearchResults { get; set; }
+
+ ///
+ /// Gets or sets the maximum server processing time in seconds.
+ ///
int MaxSearchTimeout { get; set; }
}
diff --git a/src/Bitai.LDAPHelper/AccountManager.cs b/src/Bitai.LDAPHelper/AccountManager.cs
index e93511c..e14515a 100644
--- a/src/Bitai.LDAPHelper/AccountManager.cs
+++ b/src/Bitai.LDAPHelper/AccountManager.cs
@@ -10,21 +10,37 @@
namespace Bitai.LDAPHelper
{
+ ///
+ /// Provides account-management operations for LDAP/Active Directory entries.
+ ///
public class AccountManager : BaseHelper
{
#region Constructors
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Client configuration containing connection, credential, and search settings.
+ /// LDAP connection factory abstraction.
public AccountManager(ClientConfiguration clientConfiguration, ILdapConnectionFactoryAdapter connectionFactory)
: base(clientConfiguration, connectionFactory) {
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// LDAP server connection settings.
+ /// LDAP search limits.
+ /// Credential used for management operations.
+ /// LDAP connection factory abstraction.
public AccountManager(ConnectionInfo connectionInfo, SearchLimits searchLimits, DTO.LDAPDomainAccountCredential domainAccountCredential, ILdapConnectionFactoryAdapter connectionFactory)
: base(connectionInfo, searchLimits, domainAccountCredential, connectionFactory) {
}
#endregion
-
-
-
+ ///
+ /// Initializes the account distinguished name when it is missing.
+ ///
+ /// User-account model to normalize.
public void InitializeMissingMsADUserAccountDN(LDAPMsADUserAccount userAccount)
{
if (string.IsNullOrEmpty(userAccount.DistinguishedName))
@@ -36,7 +52,6 @@ public void InitializeMissingMsADUserAccountDN(LDAPMsADUserAccount userAccount)
/// https://www.rlmueller.net/Name_Attributes.htm
///
///
- /// DN of the container in which the username will be created.
/// Optional tag to mark the request and/or response.
/// A Task of
public async Task CreateUserAccountForMsAD(LDAPMsADUserAccount newUserAccount, string requestLabel = null)
@@ -173,10 +188,12 @@ public async Task CreateUserAccountForMsAD(LDAP
///
/// Set a password for a username in MS Active Directory service. This method will verify the authenticity of the username by its distinguished name before trying to set the password. If the username is not valid, the operation will not be attempted and an error will be returned.
///
- ///
+ /// Identifier attribute used to resolve the user account (sAMAccountName or distinguishedName).
+ /// Value of the identifier attribute.
+ /// New account password.
/// Optional tag to mark the request and/or response.
/// True if the MS AD user account will be tested to verify authentication with the new password. False if the password will simply be assigned and authentication will not be tested.
- ///
+ /// A task with the password-update operation result.
public async Task SetMsADUserAccountPassword(EntryAttribute identifierAttribute, string identifierValue, string password, string requestLabel = null, bool postUpdateTestAuthentication = true)
{
try
@@ -250,9 +267,10 @@ LDAPPasswordUpdateResult createSuccessfulResult(string label, string name) {
}
///
- /// Remove a username from MS Active Directory service. This method will verify the authenticity of the username by its distinguished name before trying to remove it. If the username is not valid, the operation will not be attempted and an error will be returned.
+ /// Disables a username in MS Active Directory. This method validates the target account first.
///
- /// Distinguished name of the username
+ /// Identifier attribute used to resolve the user account (sAMAccountName or distinguishedName).
+ /// Value of the identifier attribute.
/// Optional tag to mark the request and/or response.
///
public async Task DisableMsADUserAccount(EntryAttribute identifierAttribute, string identifierValue, string requestLabel)
@@ -304,7 +322,8 @@ public async Task DisableMsADUserAccount(
///
/// Remove a username in MS Active Directory service. This operation will permanently delete the username entry from the directory, so it should be used with caution.
///
- /// Distinguished name of the username
+ /// Identifier attribute used to resolve the user account (sAMAccountName or distinguishedName).
+ /// Value of the identifier attribute.
/// Optional tag to mark the request and/or response.
///
public async Task RemoveMsADUserAccount(EntryAttribute identifierAttribute, string identifierValue, string requestLabel = null)
diff --git a/src/Bitai.LDAPHelper/Authenticator.cs b/src/Bitai.LDAPHelper/Authenticator.cs
index 5264e08..7791b76 100644
--- a/src/Bitai.LDAPHelper/Authenticator.cs
+++ b/src/Bitai.LDAPHelper/Authenticator.cs
@@ -7,15 +7,33 @@
namespace Bitai.LDAPHelper
{
+ ///
+ /// Provides LDAP authentication workflows for domain-account and distinguished-name credentials.
+ ///
public class Authenticator : BaseHelper
{
#region Constructors
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// LDAP server connection settings.
+ /// LDAP connection factory abstraction.
public Authenticator(ConnectionInfo connectionInfo, ILdapConnectionFactoryAdapter connectionFactory) : base(connectionInfo, connectionFactory) {
}
#endregion
#region Public methods
+ ///
+ /// Authenticates a domain account and validates that exactly one matching LDAP user exists.
+ ///
+ /// Credential to authenticate.
+ /// Search limits used to locate the account before authentication.
+ /// Credential used to perform the validation search.
+ /// Optional label used to correlate request/response operations.
+ ///
+ /// A result object containing operation status, authentication status, and optional error details.
+ ///
public async Task AuthenticateAsync(LDAPDomainAccountCredential credential, SearchLimits searchLimits, LDAPDomainAccountCredential credentialForSearching, string requestLabel = null) {
LDAPDomainAccountAuthenticationResult authenticationResult;
@@ -78,10 +96,13 @@ public async Task AuthenticateAsync(LDAPD
}
///
- /// Authenticate on the LDAP Server
+ /// Authenticates a domain account directly against the LDAP server.
///
- /// to connect and authenticate on the LDAP Server.
- /// True or false, if authenticated or no.
+ /// Credential to authenticate.
+ /// Optional label used to correlate request/response operations.
+ ///
+ /// A result object containing operation status, authentication status, and optional error details.
+ ///
public async Task AuthenticateAsync(LDAPDomainAccountCredential credential, string requestLabel = null) {
try {
bool? authenticated;
@@ -106,6 +127,16 @@ public async Task AuthenticateAsync(LDAPD
}
}
+ ///
+ /// Authenticates a distinguished-name account and validates that exactly one matching LDAP user exists.
+ ///
+ /// Credential to authenticate.
+ /// Search limits used to locate the account before authentication.
+ /// Credential used to perform the validation search.
+ /// Optional label used to correlate request/response operations.
+ ///
+ /// A result object containing operation status, authentication status, and optional error details.
+ ///
public async Task AuthenticateAsync(LDAPDistinguishedNameCredential credential, SearchLimits searchLimits, LDAPDomainAccountCredential credentialForSearching, string requestLabel = null) {
LDAPDistinguishedNameAuthenticationResult authenticationResult;
@@ -165,6 +196,14 @@ public async Task AuthenticateAsync(L
}
}
+ ///
+ /// Authenticates a distinguished-name account directly against the LDAP server.
+ ///
+ /// Credential to authenticate.
+ /// Optional label used to correlate request/response operations.
+ ///
+ /// A result object containing operation status, authentication status, and optional error details.
+ ///
public async Task AuthenticateAsync(LDAPDistinguishedNameCredential credential, string requestLabel = null) {
try {
bool? authenticated;
diff --git a/src/Bitai.LDAPHelper/BaseHelper.cs b/src/Bitai.LDAPHelper/BaseHelper.cs
index 4374e62..d30d9c8 100644
--- a/src/Bitai.LDAPHelper/BaseHelper.cs
+++ b/src/Bitai.LDAPHelper/BaseHelper.cs
@@ -7,17 +7,40 @@
namespace Bitai.LDAPHelper
{
+ ///
+ /// Base class for LDAP helper services, providing shared connection and mapping utilities.
+ ///
public abstract partial class BaseHelper
{
#region Properties
+ ///
+ /// Gets or sets LDAP server connection settings.
+ ///
public ConnectionInfo ConnectionInfo { get; set; }
+
+ ///
+ /// Gets or sets the credential used for LDAP search/management operations.
+ ///
public DTO.LDAPDomainAccountCredential DomainAccountCredential { get; set; }
+
+ ///
+ /// Gets or sets default LDAP search limits.
+ ///
public SearchLimits SearchLimits { get; set; }
+
+ ///
+ /// Gets or sets the LDAP connection factory abstraction.
+ ///
protected ILdapConnectionFactoryAdapter ConnectionFactory { get; set; }
#endregion
#region Protected constructors
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Client configuration containing connection, credential, and search settings.
+ /// LDAP connection factory abstraction.
protected BaseHelper(ClientConfiguration clientConfiguration, ILdapConnectionFactoryAdapter connectionFactory)
{
ConnectionInfo = clientConfiguration.ServerSettings;
@@ -26,6 +49,13 @@ protected BaseHelper(ClientConfiguration clientConfiguration, ILdapConnectionFac
ConnectionFactory = connectionFactory;
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// LDAP server connection settings.
+ /// LDAP search limits.
+ /// Credential used by LDAP operations.
+ /// LDAP connection factory abstraction.
protected BaseHelper(ConnectionInfo connectionInfo, SearchLimits searchLimits, DTO.LDAPDomainAccountCredential domainAccountCredential, ILdapConnectionFactoryAdapter connectionFactory)
{
ConnectionInfo = connectionInfo;
@@ -36,9 +66,10 @@ protected BaseHelper(ConnectionInfo connectionInfo, SearchLimits searchLimits, D
}
///
- /// Constructor used by
+ /// Initializes a new instance of the class used by authentication-only services.
///
- ///
+ /// LDAP server connection settings.
+ /// LDAP connection factory abstraction.
protected BaseHelper(ConnectionInfo connectionInfo, ILdapConnectionFactoryAdapter connectionFactory)
{
ConnectionInfo = connectionInfo;
@@ -48,6 +79,11 @@ protected BaseHelper(ConnectionInfo connectionInfo, ILdapConnectionFactoryAdapte
#region Protected methods
+ ///
+ /// Converts a SAM account-type numeric code to a symbolic name.
+ ///
+ /// String representation of the SAM account type numeric value.
+ /// A symbolic account type name when known; otherwise the original value.
protected string GetSAMAccountTypeName(string index)
{
switch (index)
@@ -78,12 +114,12 @@ protected string GetSAMAccountTypeName(string index)
}
///
- /// Get
+ /// Creates and optionally binds an LDAP connection using domain-account credentials.
///
- /// to connect to the LDAP Server
- /// to connect to the LDAP Server
- /// If are required to be mandatorily authenticated on the LDAP Server
- /// Task of
+ /// LDAP server connection settings.
+ /// Domain-account credential used for bind.
+ /// Whether bind/authentication is required.
+ /// A task with an initialized LDAP connection adapter.
protected async Task GetLdapConnection(ConnectionInfo connectionInfo, DTO.LDAPDomainAccountCredential credential, bool bindRequired = true)
{
//return getLdapConnection(connectionInfo, credential.DomainAccountName, credential.DomainAccountPassword, bindRequired);
@@ -95,6 +131,13 @@ protected async Task GetLdapConnection(ConnectionInfo co
bindRequired);
}
+ ///
+ /// Creates and optionally binds an LDAP connection using distinguished-name credentials.
+ ///
+ /// LDAP server connection settings.
+ /// Distinguished-name credential used for bind.
+ /// Whether bind/authentication is required.
+ /// A task with an initialized LDAP connection adapter.
protected async Task GetLdapConnection(ConnectionInfo connectionInfo, DTO.LDAPDistinguishedNameCredential credential, bool bindRequired = true)
{
//return getLdapConnection(connectionInfo, credential.DistinguishedName, credential.Password, bindRequired);
@@ -106,6 +149,11 @@ protected async Task GetLdapConnection(ConnectionInfo co
bindRequired);
}
+ ///
+ /// Converts a binary SID value into its canonical string representation.
+ ///
+ /// Binary SID value.
+ /// Canonical SID string (for example, S-1-5-21-...).
protected string ConvertByteToStringSid(byte[] sidBytes)
{
short sSubAuthorityCount = 0;
@@ -153,6 +201,11 @@ protected string ConvertByteToStringSid(byte[] sidBytes)
return strSid.ToString();
}
+ ///
+ /// Resolves the LDAP attribute names to request based on a predefined attribute-set preset.
+ ///
+ /// Preset indicating which attributes should be loaded.
+ /// A sequence of attribute names to request in LDAP search operations.
protected IEnumerable GetRequiredAttributeNames(DTO.RequiredEntryAttributes requiredEntryAttributes)
{
switch (requiredEntryAttributes)
diff --git a/src/Bitai.LDAPHelper/Bitai.LDAPHelper.csproj b/src/Bitai.LDAPHelper/Bitai.LDAPHelper.csproj
index d579dac..69d74b1 100644
--- a/src/Bitai.LDAPHelper/Bitai.LDAPHelper.csproj
+++ b/src/Bitai.LDAPHelper/Bitai.LDAPHelper.csproj
@@ -7,9 +7,9 @@
LDAP Services Wrappers
Library to wrap Novell.Directory.Ldap.NETStandard functionality to make LDAP common queries to search accounts and objects in a Directory Service.
© 2026 BITAI. All rights reserved.
- 10.1.2
- 10.1.2
- 10.1.2
+ 10.1.3
+ 10.1.3
+ 10.1.3
hierarchy_32.png
true
Bitai.LDAPHelper
@@ -22,6 +22,7 @@
Bitai.LDAPHelper
.NET 10 ready
README.md
+ True
diff --git a/src/Bitai.LDAPHelper/ClientConfiguration.cs b/src/Bitai.LDAPHelper/ClientConfiguration.cs
index 187dec9..5c665f7 100644
--- a/src/Bitai.LDAPHelper/ClientConfiguration.cs
+++ b/src/Bitai.LDAPHelper/ClientConfiguration.cs
@@ -1,19 +1,22 @@
-namespace Bitai.LDAPHelper
+namespace Bitai.LDAPHelper
{
+ ///
+ /// Encapsulates LDAP client runtime configuration.
+ ///
public class ClientConfiguration
{
///
- ///
+ /// Gets or sets LDAP server connection settings.
///
public ConnectionInfo ServerSettings { get; set; }
///
- ///
+ /// Gets or sets the service account used for LDAP operations.
///
public DTO.LDAPDomainAccountCredential DomainAccountCredential { get; set; }
///
- ///
+ /// Gets or sets LDAP search limits.
///
public SearchLimits SearchLimits { get; set; }
@@ -21,7 +24,7 @@ public class ClientConfiguration
/// Constructor
///
///
- ///
+ /// Domain account credential used for bind/search operations.
///
public ClientConfiguration(ConnectionInfo serverSettings, DTO.LDAPDomainAccountCredential domainAccountCredentials, SearchLimits searchLimits)
{
diff --git a/src/Bitai.LDAPHelper/ConnectionInfo.cs b/src/Bitai.LDAPHelper/ConnectionInfo.cs
index 0c76ed1..b18e49a 100644
--- a/src/Bitai.LDAPHelper/ConnectionInfo.cs
+++ b/src/Bitai.LDAPHelper/ConnectionInfo.cs
@@ -2,8 +2,18 @@
namespace Bitai.LDAPHelper
{
+ ///
+ /// Represents LDAP server connection settings.
+ ///
public class ConnectionInfo : IConnectionInfo
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// LDAP server host name or IP address.
+ /// LDAP server port.
+ /// Whether SSL is enabled.
+ /// Connection timeout in seconds.
public ConnectionInfo(string server, int port, bool useSSL, short connectionTimeout)
{
Server = server;
@@ -12,10 +22,19 @@ public ConnectionInfo(string server, int port, bool useSSL, short connectionTime
ConnectionTimeout = connectionTimeout;
}
+ ///
+ /// Gets the LDAP server host name or IP address.
+ ///
public string Server { get; }
+ ///
+ /// Gets the LDAP server port.
+ ///
public int ServerPort { get; }
+ ///
+ /// Gets a value indicating whether SSL is enabled.
+ ///
public bool UseSSL { get; }
///
diff --git a/src/Bitai.LDAPHelper/DataValidationException.cs b/src/Bitai.LDAPHelper/DataValidationException.cs
index fa68444..01a0055 100644
--- a/src/Bitai.LDAPHelper/DataValidationException.cs
+++ b/src/Bitai.LDAPHelper/DataValidationException.cs
@@ -2,17 +2,32 @@
namespace Bitai.LDAPHelper
{
+ ///
+ /// Represents errors caused by invalid or inconsistent business data supplied to LDAP operations.
+ ///
[Serializable]
public class DataValidationException : Exception
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
public DataValidationException()
{
}
+ ///
+ /// Initializes a new instance of the class with a message.
+ ///
+ /// Validation error message.
public DataValidationException(string message) : base(message)
{
}
+ ///
+ /// Initializes a new instance of the class with a message and inner exception.
+ ///
+ /// Validation error message.
+ /// Underlying cause of this exception.
public DataValidationException(string message, Exception innerException) : base(message, innerException)
{
}
diff --git a/src/Bitai.LDAPHelper/EntryNotFoundException.cs b/src/Bitai.LDAPHelper/EntryNotFoundException.cs
index c86d2c9..e06e665 100644
--- a/src/Bitai.LDAPHelper/EntryNotFoundException.cs
+++ b/src/Bitai.LDAPHelper/EntryNotFoundException.cs
@@ -1,13 +1,25 @@
-using System;
+using System;
namespace Bitai.LDAPHelper
{
+ ///
+ /// Represents errors when a requested LDAP entry cannot be found.
+ ///
public class EntryNotFoundException : Exception
{
+ ///
+ /// Initializes a new instance of the class with a message.
+ ///
+ /// Error message.
public EntryNotFoundException(string message) : base(message)
{
}
+ ///
+ /// Initializes a new instance of the class with a message and inner exception.
+ ///
+ /// Error message.
+ /// Underlying cause of this exception.
public EntryNotFoundException(string message, Exception innerException) : base(message, innerException)
{
}
diff --git a/src/Bitai.LDAPHelper/Enums.cs b/src/Bitai.LDAPHelper/Enums.cs
index 7d135a1..689ca0c 100644
--- a/src/Bitai.LDAPHelper/Enums.cs
+++ b/src/Bitai.LDAPHelper/Enums.cs
@@ -5,9 +5,24 @@ namespace Bitai.LDAPHelper
///
public enum LdapServerDefaultPorts : int
{
+ ///
+ /// Default LDAP port.
+ ///
DefaultPort = 389,
+
+ ///
+ /// Default LDAP-over-SSL port.
+ ///
DefaultSslPort = 636,
+
+ ///
+ /// Default Global Catalog port.
+ ///
DefaultGlobalCatalogPort = 3268,
+
+ ///
+ /// Default Global Catalog SSL port.
+ ///
DefaultGlobalCatalogSslPort = 3269
}
}
diff --git a/src/Bitai.LDAPHelper/Extensions/IEnumerableLDAPEntryExtensions.cs b/src/Bitai.LDAPHelper/Extensions/IEnumerableLDAPEntryExtensions.cs
index 7a06ff4..8c939d7 100644
--- a/src/Bitai.LDAPHelper/Extensions/IEnumerableLDAPEntryExtensions.cs
+++ b/src/Bitai.LDAPHelper/Extensions/IEnumerableLDAPEntryExtensions.cs
@@ -1,10 +1,18 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
namespace Bitai.LDAPHelper.Extensions
{
+ ///
+ /// Provides extension methods for LDAP entry collections.
+ ///
public static class IEnumerableLDAPEntryExtensions
{
+ ///
+ /// Flattens all memberOfEntries hierarchies recursively for every entry in the sequence.
+ ///
+ /// Source LDAP entries.
+ /// A distinct flattened sequence of parent/group entries.
public static IEnumerable SelectAllMemberOfEntriesRecursively(this IEnumerable entries)
{
var partialList = new List();
diff --git a/src/Bitai.LDAPHelper/Extensions/StringExtensions.cs b/src/Bitai.LDAPHelper/Extensions/StringExtensions.cs
index 577e043..3ac02ee 100644
--- a/src/Bitai.LDAPHelper/Extensions/StringExtensions.cs
+++ b/src/Bitai.LDAPHelper/Extensions/StringExtensions.cs
@@ -1,25 +1,48 @@
-namespace Bitai.LDAPHelper.Extensions
+namespace Bitai.LDAPHelper.Extensions
{
+ ///
+ /// Provides LDAP-safe string escaping helpers.
+ ///
public static class StringExtensions
{
+ ///
+ /// Escapes parenthesis characters for LDAP filter usage.
+ ///
+ /// Input text.
+ /// Escaped text.
public static string ReplaceParenthesisCharsToScapedChars(this string input)
{
return input.Replace("(", "\\28").Replace(")", "\\29");
}
+ ///
+ /// Escapes asterisk characters for LDAP filter usage.
+ ///
+ /// Input text.
+ /// Escaped text.
public static string ReplaceAsteriskCharsToScapedChars(this string input)
{
return input.Replace("*", "\\2A");
}
+ ///
+ /// Escapes backslash characters for LDAP filter usage.
+ ///
+ /// Input text.
+ /// Escaped text.
public static string ReplaceBackslashCharsToScapedChars(this string input)
{
return input.Replace("\\", "\\5C");
}
+ ///
+ /// Escapes special LDAP filter characters (backslash, asterisk, parenthesis).
+ ///
+ /// Input text.
+ /// Escaped text.
public static string ReplaceSpecialCharsToScapedChars(this string input)
{
return ReplaceParenthesisCharsToScapedChars(ReplaceAsteriskCharsToScapedChars(ReplaceBackslashCharsToScapedChars(input)));
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Bitai.LDAPHelper/GroupMembershipValidator.cs b/src/Bitai.LDAPHelper/GroupMembershipValidator.cs
index ef9f5b8..2c3e222 100644
--- a/src/Bitai.LDAPHelper/GroupMembershipValidator.cs
+++ b/src/Bitai.LDAPHelper/GroupMembershipValidator.cs
@@ -1,17 +1,32 @@
-using System;
+using System;
using System.Linq;
using System.Threading.Tasks;
using Bitai.LDAPHelper.LdapAdapters;
namespace Bitai.LDAPHelper
{
+ ///
+ /// Validates group membership relationships for directory users.
+ ///
public class GroupMembershipValidator : BaseHelper
{
#region Constructors
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Client configuration containing connection, credential, and search settings.
+ /// LDAP connection factory abstraction.
public GroupMembershipValidator(ClientConfiguration clientConfiguration, ILdapConnectionFactoryAdapter connectionFactory)
: base(clientConfiguration, connectionFactory) {
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// LDAP server connection settings.
+ /// LDAP search limits.
+ /// Credential used to execute LDAP searches.
+ /// LDAP connection factory abstraction.
public GroupMembershipValidator(
ConnectionInfo connectionInfo,
SearchLimits searchLimits,
@@ -136,4 +151,4 @@ public async Task GetAllGroupMembershipsAsync(string sAMAccountName) {
return groups;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapAttributeAdapter.cs b/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapAttributeAdapter.cs
index 609f278..a034e47 100644
--- a/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapAttributeAdapter.cs
+++ b/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapAttributeAdapter.cs
@@ -1,23 +1,31 @@
-using Novell.Directory.Ldap;
+using Novell.Directory.Ldap;
namespace Bitai.LDAPHelper.LdapAdapters.Novell;
///
-/// Adapter for Novell.Directory.Ldap.LdapAttribute
+/// Adapter for .
///
public class NovellLdapAttributeAdapter : ILdapAttributeAdapter
{
private readonly LdapAttribute _attribute;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Wrapped Novell LDAP attribute.
public NovellLdapAttributeAdapter(LdapAttribute attribute) {
_attribute = attribute;
}
+ ///
public byte[] ByteValue => _attribute.ByteValue;
+ ///
public string StringValue => _attribute.StringValue;
+ ///
public string[] StringValueArray => _attribute.StringValueArray;
+ ///
public byte[][] ByteValueArray => _attribute.ByteValueArray;
-}
\ No newline at end of file
+}
diff --git a/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapConnectionFactoryAdapter.cs b/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapConnectionFactoryAdapter.cs
index 523406b..b0789a9 100644
--- a/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapConnectionFactoryAdapter.cs
+++ b/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapConnectionFactoryAdapter.cs
@@ -5,10 +5,11 @@
namespace Bitai.LDAPHelper.LdapAdapters.Novell;
///
-/// Factory for creating Novell LDAP connection adapters
+/// Factory for creating Novell LDAP connection adapters.
///
public class NovellLdapConnectionFactoryAdapter : ILdapConnectionFactoryAdapter
{
+ ///
public async Task CreateConnectionAsync(
IConnectionInfo connectionInfo,
string userAccount,
diff --git a/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapEntryAdapter.cs b/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapEntryAdapter.cs
index 10a6f6b..b35d185 100644
--- a/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapEntryAdapter.cs
+++ b/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapEntryAdapter.cs
@@ -1,21 +1,27 @@
-using Novell.Directory.Ldap;
+using Novell.Directory.Ldap;
namespace Bitai.LDAPHelper.LdapAdapters.Novell;
///
-/// Adapter for Novell.Directory.Ldap.LdapEntry
+/// Adapter for .
///
public class NovellLdapEntryAdapter : ILdapEntryAdapter
{
private readonly LdapEntry _entry;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Wrapped Novell LDAP entry.
public NovellLdapEntryAdapter(LdapEntry entry) {
_entry = entry;
}
+ ///
public string DistinguishedName => _entry.Dn;
+ ///
public ILdapAttributeSetAdapter GetAttributeSet() {
return new NovellLdapAttributeSetAdapter(_entry.GetAttributeSet());
}
-}
\ No newline at end of file
+}
diff --git a/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapMessageAdapter.cs b/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapMessageAdapter.cs
index 2283f79..e63d992 100644
--- a/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapMessageAdapter.cs
+++ b/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapMessageAdapter.cs
@@ -1,18 +1,23 @@
-using Novell.Directory.Ldap;
+using Novell.Directory.Ldap;
namespace Bitai.LDAPHelper.LdapAdapters.Novell;
///
-/// Adapter for Novell.Directory.Ldap.LdapMessage
+/// Adapter for .
///
public class NovellLdapMessageAdapter : ILdapMessageAdapter
{
private readonly LdapMessage _message;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Wrapped LDAP message.
public NovellLdapMessageAdapter(LdapMessage message) {
_message = message;
}
+ ///
public ILdapEntryAdapter Entry {
get {
if (_message is LdapSearchResult searchResult && searchResult.Entry != null)
@@ -21,12 +26,14 @@ public ILdapEntryAdapter Entry {
}
}
+ ///
public bool IsSearchResult => _message is LdapSearchResult;
+ ///
public bool IsSearchDone {
get {
throw new System.Exception();
//_message is LdapSearchResultDone;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapSearchQueueAdapter.cs b/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapSearchQueueAdapter.cs
index c5f4582..583a397 100644
--- a/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapSearchQueueAdapter.cs
+++ b/src/Bitai.LDAPHelper/LdapAdapters/Novell/NovellLdapSearchQueueAdapter.cs
@@ -3,16 +3,21 @@
namespace Bitai.LDAPHelper.LdapAdapters.Novell;
///
-/// Adapter for Novell.Directory.Ldap.LdapSearchQueue
+/// Adapter for .
///
public class NovellLdapSearchQueueAdapter : ILdapSearchQueueAdapter
{
private readonly LdapSearchQueue _searchQueue;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Wrapped search queue.
public NovellLdapSearchQueueAdapter(LdapSearchQueue searchQueue) {
_searchQueue = searchQueue;
}
+ ///
public ILdapMessageAdapter GetResponse() {
LdapMessage message = _searchQueue.GetResponse();
return message != null ? new NovellLdapMessageAdapter(message) : null;
diff --git a/src/Bitai.LDAPHelper/LdapOperationException.cs b/src/Bitai.LDAPHelper/LdapOperationException.cs
index 18d0af0..a89e1f2 100644
--- a/src/Bitai.LDAPHelper/LdapOperationException.cs
+++ b/src/Bitai.LDAPHelper/LdapOperationException.cs
@@ -2,12 +2,24 @@
namespace Bitai.LDAPHelper;
+///
+/// Represents generic LDAP operation failures in helper workflows.
+///
public class LdapOperationException : Exception
{
+ ///
+ /// Initializes a new instance of the class with a message.
+ ///
+ /// Error message.
public LdapOperationException(string message) : base(message)
{
}
+ ///
+ /// Initializes a new instance of the class with a message and inner exception.
+ ///
+ /// Error message.
+ /// Underlying cause of this exception.
public LdapOperationException(string message, Exception innerException) : base(message, innerException)
{
}
diff --git a/src/Bitai.LDAPHelper/QueryFilters/AttributeFilter.cs b/src/Bitai.LDAPHelper/QueryFilters/AttributeFilter.cs
index 4d84c5d..9dfb630 100644
--- a/src/Bitai.LDAPHelper/QueryFilters/AttributeFilter.cs
+++ b/src/Bitai.LDAPHelper/QueryFilters/AttributeFilter.cs
@@ -1,18 +1,41 @@
-using Bitai.LDAPHelper.DTO;
+using Bitai.LDAPHelper.DTO;
namespace Bitai.LDAPHelper.QueryFilters
{
+ ///
+ /// Represents a single LDAP attribute filter expression.
+ ///
public class AttributeFilter : ICombinableFilter
{
private string _generatedFilterText = null;
+ ///
+ /// Gets the target LDAP attribute.
+ ///
public EntryAttribute FilterAttribute { get; }
+
+ ///
+ /// Gets the filter value.
+ ///
public FilterValue FilterValue { get; }
+
+ ///
+ /// Gets a value indicating whether this filter is negated.
+ ///
public bool IsFilterNegated { get; }
+
+ ///
+ /// Gets a value indicating whether the LDAP text has already been generated.
+ ///
public bool Generated { get; private set; }
+ ///
+ /// Initializes a new non-negated attribute filter.
+ ///
+ /// Target LDAP attribute.
+ /// Value for the attribute comparison.
public AttributeFilter(DTO.EntryAttribute filterAttribute, FilterValue filterValue)
{
FilterAttribute = filterAttribute;
@@ -20,6 +43,12 @@ public AttributeFilter(DTO.EntryAttribute filterAttribute, FilterValue filterVal
IsFilterNegated = false;
}
+ ///
+ /// Initializes a new attribute filter.
+ ///
+ /// Whether the generated filter is negated.
+ /// Target LDAP attribute.
+ /// Value for the attribute comparison.
public AttributeFilter(bool isFilterNegated, DTO.EntryAttribute filterAttribute, FilterValue filterValue) : this(filterAttribute, filterValue)
{
FilterAttribute = filterAttribute;
@@ -28,6 +57,10 @@ public AttributeFilter(bool isFilterNegated, DTO.EntryAttribute filterAttribute,
}
+ ///
+ /// Generates the LDAP filter text for this instance.
+ ///
+ /// LDAP filter expression.
public override string ToString()
{
if (Generated)
@@ -46,6 +79,9 @@ public override string ToString()
return _generatedFilterText;
}
+ ///
+ /// Resets generated-state so the filter text is rebuilt on next call.
+ ///
public void Reset()
{
_generatedFilterText = null;
diff --git a/src/Bitai.LDAPHelper/QueryFilters/AttributeFilterCombiner.cs b/src/Bitai.LDAPHelper/QueryFilters/AttributeFilterCombiner.cs
index 965d77b..381027e 100644
--- a/src/Bitai.LDAPHelper/QueryFilters/AttributeFilterCombiner.cs
+++ b/src/Bitai.LDAPHelper/QueryFilters/AttributeFilterCombiner.cs
@@ -1,12 +1,19 @@
-using Bitai.LDAPHelper.DTO;
+using Bitai.LDAPHelper.DTO;
using System.Collections.Generic;
using System.Text;
namespace Bitai.LDAPHelper.QueryFilters
{
+ ///
+ /// Combines multiple LDAP filter components into a single LDAP expression.
+ ///
public class AttributeFilterCombiner : List, ICombinableFilter
{
#region Static methods
+ ///
+ /// Creates a filter combiner that targets user entries and excludes computers and groups.
+ ///
+ /// A composed LDAP filter combiner.
public static AttributeFilterCombiner CreateOnlyUsersFilterCombiner()
{
var noComputerFilter = new QueryFilters.AttributeFilter(true, EntryAttribute.objectClass, new QueryFilters.FilterValue("computer"));
@@ -18,6 +25,10 @@ public static AttributeFilterCombiner CreateOnlyUsersFilterCombiner()
return new QueryFilters.AttributeFilterCombiner(false, true, new List { noComputerFilter, noGroupFilter, userFilter });
}
+ ///
+ /// Creates a filter combiner that targets group entries and excludes users and computers.
+ ///
+ /// A composed LDAP filter combiner.
public static AttributeFilterCombiner CreateOnlyGroupsFilterCombiner()
{
var noComputerFilter = new QueryFilters.AttributeFilter(true, EntryAttribute.objectClass, new QueryFilters.FilterValue("computer"));
@@ -34,29 +45,58 @@ public static AttributeFilterCombiner CreateOnlyGroupsFilterCombiner()
private string _generatedFilterText = null;
+ ///
+ /// Gets or sets a value indicating whether the combined expression is negated.
+ ///
public bool IsCombinerNegated { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether filters are combined conjunctively (AND) or disjunctively (OR).
+ ///
public bool ConjunctiveFilters { get; set; }
+
+ ///
+ /// Gets a value indicating whether the LDAP text has already been generated.
+ ///
public bool Generated { get; private set; }
+ ///
+ /// Initializes a new non-negated conjunctive combiner.
+ ///
public AttributeFilterCombiner() : base()
{
IsCombinerNegated = false;
ConjunctiveFilters = true;
}
+ ///
+ /// Initializes a new combiner.
+ ///
+ /// Whether the full expression is negated.
+ /// for AND-combination; for OR-combination.
public AttributeFilterCombiner(bool isCombinerNegated, bool conjunctiveFilters) : this()
{
IsCombinerNegated = isCombinerNegated;
ConjunctiveFilters = conjunctiveFilters;
}
+ ///
+ /// Initializes a new combiner with initial filter components.
+ ///
+ /// Whether the full expression is negated.
+ /// for AND-combination; for OR-combination.
+ /// Initial filter components.
public AttributeFilterCombiner(bool isCombinerNegated, bool conjunctiveFilters, IEnumerable filters) : this(isCombinerNegated, conjunctiveFilters)
{
AddRange(filters);
}
+ ///
+ /// Generates LDAP filter text for all contained filter components.
+ ///
+ /// LDAP filter expression.
public override string ToString()
{
if (Generated)
@@ -99,6 +139,9 @@ public override string ToString()
}
}
+ ///
+ /// Resets generated-state so filter text is rebuilt on next call.
+ ///
public void Reset()
{
_generatedFilterText = null;
diff --git a/src/Bitai.LDAPHelper/QueryFilters/FilterValue.cs b/src/Bitai.LDAPHelper/QueryFilters/FilterValue.cs
index 9e2a575..60a23e1 100644
--- a/src/Bitai.LDAPHelper/QueryFilters/FilterValue.cs
+++ b/src/Bitai.LDAPHelper/QueryFilters/FilterValue.cs
@@ -1,12 +1,23 @@
-using System;
+using System;
namespace Bitai.LDAPHelper.QueryFilters
{
+ ///
+ /// Represents a validated LDAP filter value.
+ ///
public class FilterValue
{
+ ///
+ /// Gets the raw value used in LDAP filters.
+ ///
public string Value { get; }
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Filter value.
+ /// Thrown when is null, empty, or whitespace.
public FilterValue(string value)
{
if (string.IsNullOrEmpty(value) || string.IsNullOrWhiteSpace(value))
@@ -16,6 +27,10 @@ public FilterValue(string value)
}
+ ///
+ /// Returns the filter value text.
+ ///
+ /// The raw filter value.
public override string ToString()
{
return Value;
diff --git a/src/Bitai.LDAPHelper/QueryFilters/ICombinableFilter.cs b/src/Bitai.LDAPHelper/QueryFilters/ICombinableFilter.cs
index 91c8e8a..48e23f9 100644
--- a/src/Bitai.LDAPHelper/QueryFilters/ICombinableFilter.cs
+++ b/src/Bitai.LDAPHelper/QueryFilters/ICombinableFilter.cs
@@ -1,11 +1,24 @@
-namespace Bitai.LDAPHelper.QueryFilters
+namespace Bitai.LDAPHelper.QueryFilters
{
+ ///
+ /// Defines a filter component that can generate LDAP filter text and be combined with others.
+ ///
public interface ICombinableFilter
{
+ ///
+ /// Gets a value indicating whether the filter text has already been generated.
+ ///
bool Generated { get; }
+ ///
+ /// Resets generated-state so filter text is rebuilt on next call.
+ ///
void Reset();
+ ///
+ /// Generates LDAP filter text.
+ ///
+ /// LDAP filter expression.
string ToString();
}
-}
\ No newline at end of file
+}
diff --git a/src/Bitai.LDAPHelper/SearchLimits.cs b/src/Bitai.LDAPHelper/SearchLimits.cs
index a16bcf7..f91f121 100644
--- a/src/Bitai.LDAPHelper/SearchLimits.cs
+++ b/src/Bitai.LDAPHelper/SearchLimits.cs
@@ -2,6 +2,9 @@
namespace Bitai.LDAPHelper
{
+ ///
+ /// Represents LDAP search boundaries and server limits.
+ ///
public class SearchLimits : ISearchLimits
{
///
@@ -28,6 +31,10 @@ public class SearchLimits : ISearchLimits
///
public int MaxSearchTimeout { get; set; } = 60;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Base distinguished name to use for searches.
public SearchLimits(string baseDN)
{
this.BaseDN = baseDN;
diff --git a/src/Bitai.LDAPHelper/Searcher.cs b/src/Bitai.LDAPHelper/Searcher.cs
index 107c590..cc3e7f3 100644
--- a/src/Bitai.LDAPHelper/Searcher.cs
+++ b/src/Bitai.LDAPHelper/Searcher.cs
@@ -8,13 +8,28 @@
namespace Bitai.LDAPHelper
{
+ ///
+ /// Performs LDAP search operations and maps results into DTO models.
+ ///
public class Searcher : BaseHelper
{
#region Constructor
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Client configuration containing connection, credential, and search settings.
+ /// LDAP connection factory abstraction.
public Searcher(ClientConfiguration clientConfiguration, ILdapConnectionFactoryAdapter connectionFactory) : base(clientConfiguration, connectionFactory)
{
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// LDAP server connection settings.
+ /// LDAP search limits.
+ /// Credential used to execute LDAP searches.
+ /// LDAP connection factory abstraction.
public Searcher(ConnectionInfo connectionInfo, SearchLimits searchLimits, DTO.LDAPDomainAccountCredential domainAccountCredential, ILdapConnectionFactoryAdapter connectionFactory) : base(connectionInfo, searchLimits, domainAccountCredential, connectionFactory)
{
}
@@ -27,7 +42,7 @@ public Searcher(ConnectionInfo connectionInfo, SearchLimits searchLimits, DTO.LD
///
/// Searches for entries matching the provided LDAP filter and loads the requested attributes.
///
- ///
+ ///
/// A combinable LDAP filter that identifies the entries to search for. This filter will be converted
/// to its string representation and used directly in the LDAP search operation.
///
diff --git a/tests/Bitai.LDAPHelper.Tests.Mocks/Bitai.LDAPHelper.Tests.Mocks.csproj b/tests/Bitai.LDAPHelper.Tests.Mocks/Bitai.LDAPHelper.Tests.Mocks.csproj
index 504b7be..dde4a93 100644
--- a/tests/Bitai.LDAPHelper.Tests.Mocks/Bitai.LDAPHelper.Tests.Mocks.csproj
+++ b/tests/Bitai.LDAPHelper.Tests.Mocks/Bitai.LDAPHelper.Tests.Mocks.csproj
@@ -4,9 +4,9 @@
net10.0
enable
enable
- 10.1.0
- 10.1.0
- 10.1.0
+ 10.1.1
+ 10.1.1
+ 10.1.1
Viko Bastidas (BITAI)
© 2026 BITAI. MIT License.
https://github.com/bitai-cs/LDAPHelper.git
diff --git a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapAttributeSetAdapter.cs b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapAttributeSetAdapter.cs
index 04432a4..10112e4 100644
--- a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapAttributeSetAdapter.cs
+++ b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapAttributeSetAdapter.cs
@@ -1,7 +1,10 @@
-using Bitai.LDAPHelper.LdapAdapters;
+using Bitai.LDAPHelper.LdapAdapters;
namespace Bitai.LDAPHelper.Tests.Mocks.LdapAdapters;
+///
+/// In-memory mock implementation of for tests.
+///
public class MockLdapAttributeSetAdapter : ILdapAttributeSetAdapter
{
private Dictionary _attributeDictionary = new();
@@ -110,4 +113,4 @@ public bool VerifyAttributeByteValue(string attributeName, byte[] expectedValue)
return true;
}
-}
\ No newline at end of file
+}
diff --git a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapConnectionAdapter.cs b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapConnectionAdapter.cs
index c57cf7f..3d7d1ff 100644
--- a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapConnectionAdapter.cs
+++ b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapConnectionAdapter.cs
@@ -3,6 +3,9 @@
namespace Bitai.LDAPHelper.Tests.Mocks.LdapAdapters;
+///
+/// In-memory mock LDAP connection used by tests to simulate bind/search/add/modify/delete operations.
+///
public class MockLdapConnectionAdapter : ILdapConnectionAdapter
{
private bool _disposed = false;
diff --git a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapConnectionFactoryAdapter.cs b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapConnectionFactoryAdapter.cs
index dd8ed70..bde94af 100644
--- a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapConnectionFactoryAdapter.cs
+++ b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapConnectionFactoryAdapter.cs
@@ -2,6 +2,9 @@
namespace Bitai.LDAPHelper.Tests.Mocks.LdapAdapters;
+///
+/// Mock implementation of that returns a provided mock connection.
+///
public class MockLdapConnectionFactoryAdapter : ILdapConnectionFactoryAdapter
{
private readonly MockLdapConnectionAdapter _connection;
diff --git a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapEntryAdapter.cs b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapEntryAdapter.cs
index 3517098..efd0529 100644
--- a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapEntryAdapter.cs
+++ b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapEntryAdapter.cs
@@ -1,7 +1,10 @@
-using Bitai.LDAPHelper.LdapAdapters;
+using Bitai.LDAPHelper.LdapAdapters;
namespace Bitai.LDAPHelper.Tests.Mocks.LdapAdapters;
+///
+/// In-memory mock LDAP entry used by test scenarios.
+///
public class MockLdapEntryAdapter : ILdapEntryAdapter
{
private readonly MockLdapAttributeSetAdapter _attributeSet;
@@ -47,4 +50,4 @@ public void AddAttribute(string name, object value) {
public ILdapAttributeSetAdapter GetAttributeSet() {
return _attributeSet;
}
-}
\ No newline at end of file
+}
diff --git a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapMessageAdapter.cs b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapMessageAdapter.cs
index eeed997..477ccd1 100644
--- a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapMessageAdapter.cs
+++ b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapMessageAdapter.cs
@@ -1,7 +1,10 @@
-using Bitai.LDAPHelper.LdapAdapters;
+using Bitai.LDAPHelper.LdapAdapters;
namespace Bitai.LDAPHelper.Tests.Mocks.LdapAdapters;
+///
+/// In-memory mock LDAP message wrapper used in search queue responses.
+///
public class MockLdapMessageAdapter : ILdapMessageAdapter
{
public MockLdapMessageAdapter(ILdapEntryAdapter entry) {
@@ -13,4 +16,4 @@ public MockLdapMessageAdapter(ILdapEntryAdapter entry) {
public ILdapEntryAdapter Entry { get; }
public bool IsSearchResult { get; set; }
public bool IsSearchDone { get; set; }
-}
\ No newline at end of file
+}
diff --git a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapModificationAdapter.cs b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapModificationAdapter.cs
index 0d3b908..83e683a 100644
--- a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapModificationAdapter.cs
+++ b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapModificationAdapter.cs
@@ -1,7 +1,10 @@
-using Bitai.LDAPHelper.LdapAdapters;
+using Bitai.LDAPHelper.LdapAdapters;
namespace Bitai.LDAPHelper.Tests.Mocks.LdapAdapters;
+///
+/// In-memory mock implementation of .
+///
public class MockLdapModificationAdapter : ILdapModificationAdapter
{
public MockLdapModificationAdapter(LdapModificationType type, string attributeName, object value) {
@@ -16,10 +19,13 @@ public MockLdapModificationAdapter(LdapModificationType type, string attributeNa
public ILdapAttributeAdapter Attribute => new MockLdapAttributeAdapter(AttributeName, Value);
}
+///
+/// Simple DTO used to capture applied modifications in mock connection state.
+///
public class MockModification
{
public string DistinguishedName { get; set; }
public LdapModificationType ModificationType { get; set; }
public string AttributeName { get; set; }
public object Value { get; set; }
-}
\ No newline at end of file
+}
diff --git a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapPersistentConnectionAdapter.cs b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapPersistentConnectionAdapter.cs
index a3cb143..629ebe7 100644
--- a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapPersistentConnectionAdapter.cs
+++ b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapPersistentConnectionAdapter.cs
@@ -4,6 +4,9 @@
namespace Bitai.LDAPHelper.Tests.Mocks.LdapAdapters;
+///
+/// Persistent mock connection backed by a shared in-memory LDAP data store.
+///
public class MockLdapPersistentConnectionAdapter : MockLdapConnectionAdapter
{
private readonly MockLdapDataStore _dataStore;
diff --git a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapPersistentConnectionFactoryAdapter.cs b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapPersistentConnectionFactoryAdapter.cs
index c724fef..fc5a363 100644
--- a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapPersistentConnectionFactoryAdapter.cs
+++ b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapPersistentConnectionFactoryAdapter.cs
@@ -2,6 +2,9 @@
namespace Bitai.LDAPHelper.Tests.Mocks.LdapAdapters;
+///
+/// Factory for creating persistent mock LDAP connections backed by shared in-memory data.
+///
public class MockLdapPersistentConnectionFactoryAdapter : ILdapConnectionFactoryAdapter
{
private readonly MockLdapPersistentConnectionAdapter _connection;
diff --git a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapSearchQueueAdapter.cs b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapSearchQueueAdapter.cs
index 77ea046..1c80be4 100644
--- a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapSearchQueueAdapter.cs
+++ b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapAdapters/MockLdapSearchQueueAdapter.cs
@@ -1,7 +1,10 @@
-using Bitai.LDAPHelper.LdapAdapters;
+using Bitai.LDAPHelper.LdapAdapters;
namespace Bitai.LDAPHelper.Tests.Mocks.LdapAdapters;
+///
+/// In-memory mock implementation of .
+///
public class MockLdapSearchQueueAdapter : ILdapSearchQueueAdapter
{
private Queue _messages = new();
@@ -13,4 +16,4 @@ public void AddSearchResult(ILdapMessageAdapter message) {
public ILdapMessageAdapter GetResponse() {
return _messages.Count > 0 ? _messages.Dequeue() : null;
}
-}
\ No newline at end of file
+}
diff --git a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapData/MockLdapDataSeeder.cs b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapData/MockLdapDataSeeder.cs
index 1941c40..f19c763 100644
--- a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapData/MockLdapDataSeeder.cs
+++ b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapData/MockLdapDataSeeder.cs
@@ -3,6 +3,9 @@
namespace Bitai.LDAPHelper.Tests.Mocks.LdapData;
+///
+/// Seeds deterministic mock LDAP data for integration-style tests and demos.
+///
public class MockLdapDataSeeder
{
private readonly MockLdapDataStore _dataStore;
diff --git a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapData/MockLdapDataStore.cs b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapData/MockLdapDataStore.cs
index 2b4c8b6..300abf0 100644
--- a/tests/Bitai.LDAPHelper.Tests.Mocks/LdapData/MockLdapDataStore.cs
+++ b/tests/Bitai.LDAPHelper.Tests.Mocks/LdapData/MockLdapDataStore.cs
@@ -2,6 +2,9 @@
namespace Bitai.LDAPHelper.Tests.Mocks.LdapData;
+///
+/// Thread-safe in-memory LDAP entry store used by persistent mock adapters.
+///
public class MockLdapDataStore
{
private static readonly Lazy _instance = new Lazy(() => new MockLdapDataStore());
diff --git a/tests/Bitai.LDAPHelper.Tests/AccountManagerAdapterTests.cs b/tests/Bitai.LDAPHelper.Tests/AccountManagerAdapterTests.cs
index 442faca..883d331 100644
--- a/tests/Bitai.LDAPHelper.Tests/AccountManagerAdapterTests.cs
+++ b/tests/Bitai.LDAPHelper.Tests/AccountManagerAdapterTests.cs
@@ -3,6 +3,9 @@
namespace Bitai.LDAPHelper.Tests
{
+ ///
+ /// Integration-style unit tests for using mock LDAP adapters.
+ ///
public class AccountManagerAdapterTests: BaseTests
{
[Fact]
diff --git a/tests/Bitai.LDAPHelper.Tests/AuthenticatorAdapterTests.cs b/tests/Bitai.LDAPHelper.Tests/AuthenticatorAdapterTests.cs
index b030d1d..e46fe8e 100644
--- a/tests/Bitai.LDAPHelper.Tests/AuthenticatorAdapterTests.cs
+++ b/tests/Bitai.LDAPHelper.Tests/AuthenticatorAdapterTests.cs
@@ -1,8 +1,11 @@
-using Bitai.LDAPHelper.DTO;
+using Bitai.LDAPHelper.DTO;
using Bitai.LDAPHelper.Tests.Mocks.LdapAdapters;
namespace Bitai.LDAPHelper.Tests
{
+ ///
+ /// Integration-style unit tests for using mock LDAP adapters.
+ ///
public class AuthenticatorAdapterTests : BaseTests
{
[Fact]
@@ -239,4 +242,4 @@ public async Task AuthenticateDN_WithVerification_ReturnsFailed() {
Assert.True(string.IsNullOrEmpty(result.ErrorType));
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/Bitai.LDAPHelper.Tests/BaseTests.cs b/tests/Bitai.LDAPHelper.Tests/BaseTests.cs
index 8a61553..3f5a69e 100644
--- a/tests/Bitai.LDAPHelper.Tests/BaseTests.cs
+++ b/tests/Bitai.LDAPHelper.Tests/BaseTests.cs
@@ -1,7 +1,10 @@
-using Bitai.LDAPHelper.Tests.Mocks.LdapAdapters;
+using Bitai.LDAPHelper.Tests.Mocks.LdapAdapters;
namespace Bitai.LDAPHelper.Tests
{
+ ///
+ /// Shared test-fixture helpers for LDAP helper test suites.
+ ///
public class BaseTests
{
public MockLdapEntryAdapter CreateMockUserEntry(string firstName, string lastName, SearchLimits? searchLimits, out QueryFilters.AttributeFilter searchFilterSAMAccountName, out QueryFilters.AttributeFilter searchFilterDistinguishedName, string[] memberOfDistinguishedNames = null, string groupName = null, string groupContainerName = null) {
diff --git a/tests/Bitai.LDAPHelper.Tests/Bitai.LDAPHelper.Tests.csproj b/tests/Bitai.LDAPHelper.Tests/Bitai.LDAPHelper.Tests.csproj
index 982a7f5..8f42981 100644
--- a/tests/Bitai.LDAPHelper.Tests/Bitai.LDAPHelper.Tests.csproj
+++ b/tests/Bitai.LDAPHelper.Tests/Bitai.LDAPHelper.Tests.csproj
@@ -7,9 +7,9 @@
false
true
- 10.1.2
- 10.1.2
- 10.1.2
+ 10.1.3
+ 10.1.3
+ 10.1.3
5981b6a0-6b9e-439d-8324-a0ef8bfd0f11
diff --git a/tests/Bitai.LDAPHelper.Tests/GroupMembershipValidatorTests.cs b/tests/Bitai.LDAPHelper.Tests/GroupMembershipValidatorTests.cs
index daad1f7..63ab04e 100644
--- a/tests/Bitai.LDAPHelper.Tests/GroupMembershipValidatorTests.cs
+++ b/tests/Bitai.LDAPHelper.Tests/GroupMembershipValidatorTests.cs
@@ -3,6 +3,9 @@
namespace Bitai.LDAPHelper.Tests
{
+ ///
+ /// Unit tests for using mock LDAP adapters.
+ ///
public class GroupMembershipValidatorTests : BaseTests
{
private readonly ConnectionInfo _validConnectionInfo;
diff --git a/tests/Bitai.LDAPHelper.Tests/SearcherAdapterTests.cs b/tests/Bitai.LDAPHelper.Tests/SearcherAdapterTests.cs
index a924af9..a467d3a 100644
--- a/tests/Bitai.LDAPHelper.Tests/SearcherAdapterTests.cs
+++ b/tests/Bitai.LDAPHelper.Tests/SearcherAdapterTests.cs
@@ -3,6 +3,9 @@
namespace Bitai.LDAPHelper.Tests
{
+ ///
+ /// Integration-style unit tests for using mock LDAP adapters.
+ ///
public class SearcherAdapterTests : BaseTests
{
[Fact]