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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion Bitai.Ldap.Helper.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 18
VisualStudioVersion = 18.6.11822.322 stable
VisualStudioVersion = 18.6.11822.322
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bitai.LDAPHelper.DTO", "src\Bitai.LDAPHelper.DTO\Bitai.LDAPHelper.DTO.csproj", "{2386A126-F237-43FD-9A7C-FDF6718ACAD7}"
EndProject
Expand All @@ -24,6 +24,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C4F50587-D86
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bitai.LDAPHelper.Tests.Mocks", "tests\Bitai.LDAPHelper.Tests.Mocks\Bitai.LDAPHelper.Tests.Mocks.csproj", "{39BD48F5-8B64-469F-B6D7-9BB4582AE5F6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bitai.LDAPHelper.LdapAdapters", "src\Bitai.LDAPHelper.LdapAdapters\Bitai.LDAPHelper.LdapAdapters.csproj", "{A5F5FA73-059E-411F-BBF1-A8AC4C8B65BC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -94,6 +96,18 @@ Global
{39BD48F5-8B64-469F-B6D7-9BB4582AE5F6}.Release|x64.Build.0 = Release|Any CPU
{39BD48F5-8B64-469F-B6D7-9BB4582AE5F6}.Release|x86.ActiveCfg = Release|Any CPU
{39BD48F5-8B64-469F-B6D7-9BB4582AE5F6}.Release|x86.Build.0 = Release|Any CPU
{A5F5FA73-059E-411F-BBF1-A8AC4C8B65BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A5F5FA73-059E-411F-BBF1-A8AC4C8B65BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5F5FA73-059E-411F-BBF1-A8AC4C8B65BC}.Debug|x64.ActiveCfg = Debug|Any CPU
{A5F5FA73-059E-411F-BBF1-A8AC4C8B65BC}.Debug|x64.Build.0 = Debug|Any CPU
{A5F5FA73-059E-411F-BBF1-A8AC4C8B65BC}.Debug|x86.ActiveCfg = Debug|Any CPU
{A5F5FA73-059E-411F-BBF1-A8AC4C8B65BC}.Debug|x86.Build.0 = Debug|Any CPU
{A5F5FA73-059E-411F-BBF1-A8AC4C8B65BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A5F5FA73-059E-411F-BBF1-A8AC4C8B65BC}.Release|Any CPU.Build.0 = Release|Any CPU
{A5F5FA73-059E-411F-BBF1-A8AC4C8B65BC}.Release|x64.ActiveCfg = Release|Any CPU
{A5F5FA73-059E-411F-BBF1-A8AC4C8B65BC}.Release|x64.Build.0 = Release|Any CPU
{A5F5FA73-059E-411F-BBF1-A8AC4C8B65BC}.Release|x86.ActiveCfg = Release|Any CPU
{A5F5FA73-059E-411F-BBF1-A8AC4C8B65BC}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -104,6 +118,7 @@ Global
{EF0E7C00-6116-46A7-BC21-6B30DE8361DD} = {D026C7BE-09AB-4BFD-B78E-1DF35734EBFD}
{2D343BE2-3906-4541-B9A5-CBB9A866BE54} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{39BD48F5-8B64-469F-B6D7-9BB4582AE5F6} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{A5F5FA73-059E-411F-BBF1-A8AC4C8B65BC} = {C4F50587-D862-43DF-AFE6-D2EEC0B7454D}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DB0C2252-0846-4C49-970A-C7C68C82A4F3}
Expand Down
2 changes: 2 additions & 0 deletions demo/Bitai.LDAPHelper.Demo/Bitai.LDAPHelper.Demo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.8" />
<PackageReference Include="Serilog" Version="4.3.1" />
<PackageReference Include="Serilog.Extensions.Logging" Version="10.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
<PackageReference Include="Spectre.Console" Version="0.55.2" />
</ItemGroup>
Expand Down
25 changes: 16 additions & 9 deletions demo/Bitai.LDAPHelper.Demo/Program.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using System;
using System;
using System.Threading.Tasks;
using Serilog;
using System.Linq;
using System.Collections.Generic;
using Bitai.LDAPHelper.Demo.Mocks.LdapAdapters;
using Bitai.LDAPHelper.DTO;
using Microsoft.Extensions.Configuration;
using Bitai.LDAPHelper.Demo.Mocks.LdapData;
using Bitai.LDAPHelper.LdapAdapters.Novell;
using Bitai.LDAPHelper.Tests.Mocks.LdapAdapters;
using Bitai.LDAPHelper.Tests.Mocks.LdapData;
using Microsoft.Extensions.Logging;

namespace Bitai.LDAPHelper.Demo;

Expand Down Expand Up @@ -116,14 +117,20 @@ public static async Task Main(string[] args)
if (implementation == ImplementationType.Mock)
{
Log.Information("Initializing Mock Implementation...");
_context.ConnectionFactory = new PersistentMockLdapConnectionFactoryAdapter();

_context.ConnectionFactory = new MockLdapPersistentConnectionFactoryAdapter();

// Create logger for MockLdapDataSeeder
using var loggerFactory = LoggerFactory.Create(builder => {
builder.ClearProviders();
builder.AddSerilog(Log.Logger);
});
var logger = loggerFactory.CreateLogger<MockLdapDataSeeder>();

// Seed mock data
var seeder = new MockDataSeeder(_context);
var seeder = new MockLdapDataSeeder(logger);
seeder.SeedAllData();

//seeder.ExportGroupMembershipDataHierarchyToConsole(true);
//Console.ReadKey();
seeder.PrintAllData();

// Set mock connection info (dummy values)
_context.SelectedLdapServer = "mock-server";
Expand Down Expand Up @@ -542,4 +549,4 @@ private static async Task AskToRunAgain()
await Main(new string[0]);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageId>Bitai.LDAPHelper.LdapAdapters</PackageId>
<Version>10.0.0</Version>
<Authors>Victor Bastidas (BITAI)</Authors>
<Company>BITAI</Company>
<Product>LDAP Services Wrappers</Product>
<Description>Library to wrap an LDAP Service functionality.</Description>
<Copyright>© 2026 BITAI. MIT License.</Copyright>
<PackageProjectUrl>https://github.com/bitai-cs/LDAPHelper</PackageProjectUrl>
<RepositoryUrl>https://github.com/bitai-cs/LDAPHelper.git</RepositoryUrl>
<PackageTags>ldap;authentication;authorization;directory;helper;oauth;openid;ad;security;identity</PackageTags>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>

<ItemGroup>
<None Update="LICENSE.md">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
<None Update="README.md">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>

</Project>
21 changes: 21 additions & 0 deletions src/Bitai.LDAPHelper.LdapAdapters/Enums.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace Bitai.LDAPHelper.LdapAdapters;

/// <summary>
/// LDAP modification operation types
/// </summary>
public enum LdapModificationType
{
Add = 0,
Delete = 1,
Replace = 2
}

/// <summary>
/// LDAP search scope values
/// </summary>
public enum LdapSearchScope
{
ScopeBase = 0,
ScopeOne = 1,
ScopeSub = 2
}
9 changes: 9 additions & 0 deletions src/Bitai.LDAPHelper.LdapAdapters/IConnectionInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Bitai.LDAPHelper.LdapAdapters;

public interface IConnectionInfo
{
short ConnectionTimeout { get; }
string Server { get; }
int ServerPort { get; }
bool UseSSL { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ public interface ILdapConnectionAdapter : IDisposable
void ServerCertificateValidationByPass();
Task ConnectAsync(string host, int port);
Task BindAsync(string userDN, string password);
Task<ILdapSearchQueueAdapter> SearchAsync(SearchLimits searchLimits, string searchFilter, string[] attributeNames, bool typesOnly);
Task<ILdapSearchQueueAdapter> SearchAsync(ISearchLimits searchLimits, string searchFilter, string[] attributeNames, bool typesOnly);
ILdapAttributeSetAdapter CreateAttributeSet();
Task AddEntryAsync(string distinguishedName, ILdapAttributeSetAdapter attributes);
ILdapModificationAdapter CreateModification(LdapModificationType type, string attributeName, object value);
Task ModifyEntryAsync(string distinguishedName, IEnumerable<ILdapModificationAdapter> modifications);
Task DeleteEntryAsync(string distinguishedName);
void Disconnect();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using System.Threading.Tasks;

namespace Bitai.LDAPHelper.LdapAdapters;

/// <summary>
Expand All @@ -8,8 +6,8 @@ namespace Bitai.LDAPHelper.LdapAdapters;
public interface ILdapConnectionFactoryAdapter
{
Task<ILdapConnectionAdapter> CreateConnectionAsync(
ConnectionInfo connectionInfo,
IConnectionInfo connectionInfo,
string userAccount,
string password,
bool bindRequired = true);
}
}
9 changes: 9 additions & 0 deletions src/Bitai.LDAPHelper.LdapAdapters/ISearchLimits.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Bitai.LDAPHelper.LdapAdapters;

public interface ISearchLimits
{
string BaseDN { get; set; }
LdapSearchScope LdapSearchScope { get; set; }
int MaxSearchResults { get; set; }
int MaxSearchTimeout { get; set; }
}
21 changes: 21 additions & 0 deletions src/Bitai.LDAPHelper.LdapAdapters/LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# MIT License

Copyright (c) 2026 BITAI

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
110 changes: 110 additions & 0 deletions src/Bitai.LDAPHelper.LdapAdapters/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Bitai.LDAPHelper.LdapAdapters

`Bitai.LDAPHelper.LdapAdapters` defines the LDAP adapter contracts used by the Bitai LDAP Helper libraries. It is a small abstraction layer that keeps the core helper logic independent from any specific LDAP client implementation, such as `Novell.Directory.Ldap.NETStandard`.

This package contains interfaces and enums only. It does not open LDAP connections by itself and does not include a concrete LDAP provider.

## Purpose

Use this project when you need to:

- Implement a concrete LDAP provider for `Bitai.LDAPHelper`.
- Test LDAP-dependent code without binding directly to a real directory server.
- Isolate application logic from vendor-specific LDAP client APIs.
- Standardize LDAP operations such as bind, search, add, modify, delete, and attribute access.

## Target Framework

- .NET 10.0
- Nullable reference types enabled
- Implicit global usings enabled

## Package Metadata

- Package ID: `Bitai.LDAPHelper.LdapAdapters`
- Version: `10.0.0`
- Repository: `https://github.com/bitai-cs/LDAPHelper`
- License: MIT

## Main Contracts

### Connection and Factory

- `ILdapConnectionFactoryAdapter` creates configured LDAP connections from `IConnectionInfo` and credentials.
- `ILdapConnectionAdapter` represents a connected LDAP session and exposes bind, search, add, modify, delete, disconnect, and dispose operations.
- `IConnectionInfo` describes LDAP server address, port, SSL usage, and timeout settings.

### Search

- `ISearchLimits` describes base DN, search scope, result limits, and timeout limits.
- `ILdapSearchQueueAdapter` abstracts queued LDAP search responses.
- `ILdapMessageAdapter` distinguishes search result entries from search completion messages.

### Entries and Attributes

- `ILdapEntryAdapter` exposes an LDAP entry distinguished name and its attribute set.
- `ILdapAttributeSetAdapter` creates and retrieves LDAP attributes by name.
- `ILdapAttributeAdapter` exposes attribute values as string, string array, byte array, or byte array collection.

### Modifications

- `ILdapModificationAdapter` describes an LDAP attribute modification.
- `LdapModificationType` supports add, delete, and replace operations.
- `LdapSearchScope` supports base, one-level, and subtree LDAP searches.

## Implementing an Adapter

A concrete provider typically implements `ILdapConnectionFactoryAdapter` and `ILdapConnectionAdapter`, then maps the Bitai contracts to the provider-specific LDAP client.

```csharp
using Bitai.LDAPHelper.LdapAdapters;

public sealed class CustomLdapConnectionFactoryAdapter : ILdapConnectionFactoryAdapter
{
public async Task<ILdapConnectionAdapter> CreateConnectionAsync(
IConnectionInfo connectionInfo,
string userAccount,
string password,
bool bindRequired = true)
{
var connection = new CustomLdapConnectionAdapter();
connection.ConnectionTimeout = connectionInfo.ConnectionTimeout;
connection.SecureSocketLayer = connectionInfo.UseSSL;

await connection.ConnectAsync(connectionInfo.Server, connectionInfo.ServerPort);

if (bindRequired)
{
await connection.BindAsync(userAccount, password);
}

return connection;
}
}
```

The adapter is then passed into higher-level `Bitai.LDAPHelper` services such as authentication, search, account management, and group membership validation.

## Design Notes

- The package intentionally contains no dependency on a specific LDAP SDK.
- Adapter implementations should preserve provider exceptions only when callers can handle them meaningfully; otherwise, translate them into domain-level exceptions used by the consuming library.
- `ILdapConnectionAdapter` implements `IDisposable`; concrete implementations should release network resources and provider-specific handles consistently.
- `ServerCertificateValidationByPass` exists for compatibility with provider adapters. Use it only in controlled development or test environments.

## Build

From the repository root:

```powershell
dotnet build src/Bitai.LDAPHelper.LdapAdapters/Bitai.LDAPHelper.LdapAdapters.csproj
```

## Related Projects

- `Bitai.LDAPHelper`: Core LDAP helper services that consume these contracts.
- `Bitai.LDAPHelper.Tests.Mocks`: In-memory mock implementations for tests and demos.

## License

This project is licensed under the MIT License. See [LICENSE.md](LICENSE.md).
7 changes: 4 additions & 3 deletions src/Bitai.LDAPHelper/Bitai.LDAPHelper.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
<Product>LDAP Services Wrappers</Product>
<Description>Library to wrap Novell.Directory.Ldap.NETStandard functionality to make LDAP common queries to search accounts and objects in a Directory Service.</Description>
<Copyright>© 2026 BITAI. All rights reserved.</Copyright>
<Version>10.0.0</Version>
<AssemblyVersion>10.0.0</AssemblyVersion>
<Version>10.1.0</Version>
<AssemblyVersion>10.1.0</AssemblyVersion>
<PackageIcon>hierarchy_32.png</PackageIcon>
<FileVersion>10.0.0</FileVersion>
<FileVersion>10.1.0</FileVersion>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageId>Bitai.LDAPHelper</PackageId>
<AssemblyName>Bitai.LDAPHelper</AssemblyName>
Expand Down Expand Up @@ -43,6 +43,7 @@

<ItemGroup>
<ProjectReference Include="..\Bitai.LDAPHelper.DTO\Bitai.LDAPHelper.DTO.csproj" />
<ProjectReference Include="..\Bitai.LDAPHelper.LdapAdapters\Bitai.LDAPHelper.LdapAdapters.csproj" />
</ItemGroup>


Expand Down
Loading
Loading