Added LDAP migrations, made CreateObject async, moved LdapOptions to Models, fixed user password not hashed on user creation

This commit is contained in:
2025-10-03 16:31:08 +02:00
parent 45b1a44ebe
commit 1f356a807f
7 changed files with 220 additions and 23 deletions

View File

@@ -4,15 +4,16 @@ using Berufsschule_HAM.Models;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Text.Json;
namespace Berufsschule_HAM.Services;
public partial class LdapService : IDisposable
{
private readonly LdapOptions _opts;
private readonly LdapConfig _opts;
private readonly LdapConnection _conn;
private ILogger _logger;
public LdapService(IOptions<LdapOptions> options, ILogger<LdapService> logger)
public LdapService(IOptions<LdapConfig> options, ILogger<LdapService> logger)
{
_opts = options.Value;
_conn = new LdapConnection { SecureSocketLayer = _opts.UseSsl };
@@ -39,9 +40,11 @@ public partial class LdapService : IDisposable
await _conn.BindAsync(_opts.BindDn, _opts.BindPassword);
}
private string AssetsBaseDn => string.IsNullOrEmpty(_opts.AssetsOu) ? _opts.BaseDn : $"{_opts.AssetsOu},{_opts.BaseDn}";
private string LocationsBaseDn => string.IsNullOrEmpty(_opts.LocationsOu) ? _opts.BaseDn : $"{_opts.LocationsOu},{_opts.BaseDn}";
private string UsersBaseDn => string.IsNullOrEmpty(_opts.UsersOu) ? _opts.BaseDn : $"{_opts.UsersOu},{_opts.BaseDn}";
public string AssetsBaseDn => string.IsNullOrEmpty(_opts.AssetsOu) ? _opts.BaseDn : $"{_opts.AssetsOu},{_opts.BaseDn}";
public string LocationsBaseDn => string.IsNullOrEmpty(_opts.LocationsOu) ? _opts.BaseDn : $"{_opts.LocationsOu},{_opts.BaseDn}";
public string UsersBaseDn => string.IsNullOrEmpty(_opts.UsersOu) ? _opts.BaseDn : $"{_opts.UsersOu},{_opts.BaseDn}";
public string GroupsBaseDn => string.IsNullOrEmpty(_opts.GroupsOu) ? _opts.BaseDn : $"{_opts.GroupsOu},{_opts.BaseDn}";
public string MigrationsBaseDn => string.IsNullOrEmpty(_opts.MigrationsOu) ? _opts.BaseDn : $"{_opts.MigrationsOu},{_opts.BaseDn}";
public async Task<IEnumerable<Dictionary<string, string>>> ListLocationsAsync()
{
@@ -53,6 +56,41 @@ public partial class LdapService : IDisposable
return await ListObjectBy(UsersBaseDn, "", ["cn", "sn", "title", "uid", "jpegPhoto", "userPassword", "description"]);
}
public async Task<MigrationModel> GetMigrationVersionAsync()
{
Dictionary<string, string> objects;
try
{
objects = (await ListObjectBy(_opts.BaseDn, _opts.MigrationsOu, ["description"])).First();
}
catch (Exception)
{
objects = [];
}
return new MigrationModel(objects);
}
public async Task<bool> UpdateMigrationVersionAsync(MigrationModel migrationModel)
{
await ConnectAndBind();
try
{
string dn = MigrationsBaseDn; //PrependRDN($"", MigrationsBaseDn);
string targetText = JsonSerializer.Serialize(migrationModel);
_logger.LogInformation("Setting the LDAP migration description to {targetText} for {dn}", [targetText, dn]);
var modification = new LdapModification(
LdapModification.Replace,
new LdapAttribute("description", targetText)
);
await _conn.ModifyAsync(dn, modification);
}
catch (Exception)
{
return false;
}
return true;
}
public async Task<IEnumerable<UserModel>> ListUsersAsync(string[] attributes)
{
List<UserModel> returnValue = [];
@@ -85,20 +123,20 @@ public partial class LdapService : IDisposable
return await ListObjectBy(AssetsBaseDn, "(objectClass=device)", ["CN", "description", "l", "owner", "serialNumber"]);
}
public void CreateUser(string uid, LdapAttributeSet attributeSet)
public async Task CreateUser(string uid, LdapAttributeSet attributeSet)
{
string dn = PrependRDN($"uid={uid}", UsersBaseDn);
CreateObject(dn, attributeSet);
await CreateObject(dn, attributeSet);
}
public void CreateAsset(LdapAttributeSet attributeSet)
public async Task CreateAsset(LdapAttributeSet attributeSet)
{
CreateObject(AssetsBaseDn, attributeSet);
await CreateObject(AssetsBaseDn, attributeSet);
}
public void CreateLocation(LdapAttributeSet attributeSet)
public async Task CreateLocation(LdapAttributeSet attributeSet)
{
CreateObject(LocationsBaseDn, attributeSet);
await CreateObject(LocationsBaseDn, attributeSet);
}
public async Task<UserAuthenticationResult> AuthenticateUser(string username, string password)
@@ -201,13 +239,12 @@ public partial class LdapService : IDisposable
}
}
public async void DeleteObjectByDn(string dn)
{
await _conn.DeleteAsync(dn);
}
public async void CreateObject(string dn, LdapAttributeSet attributeSet)
public async Task CreateObject(string dn, LdapAttributeSet attributeSet)
{
await ConnectAndBind();
LdapEntry ldapEntry = new(dn, attributeSet);