From a34534eb626b65e5754a030c0225a27edd0cf673 Mon Sep 17 00:00:00 2001 From: anomny Date: Sat, 4 Oct 2025 10:38:19 +0200 Subject: [PATCH 1/5] Fix build errors --- src/Controllers/GroupsController.cs | 25 ++++++++++++------------- src/Controllers/UsersController.cs | 21 ++++++++++----------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/Controllers/GroupsController.cs b/src/Controllers/GroupsController.cs index 2debc38..0ca257c 100644 --- a/src/Controllers/GroupsController.cs +++ b/src/Controllers/GroupsController.cs @@ -66,19 +66,18 @@ public class GroupsController : Controller { description ??= JsonSerializer.Serialize(new GroupPermissions() {Permissions = []}); - LdapAttributeSet attributeSet = - [ - new LdapAttribute("objectClass", "posixGroup"), - new LdapAttribute("objectClass", "top"), - new LdapAttribute("cn", cn), - new LdapAttribute("gidNumber", gidNumber), - new LdapAttribute("description", - JsonSerializer.Serialize( - new GroupPermissions() - { - Permissions = [.. permissions] - })), - ]; + var attributeSet = new LdapAttributeSet(); + attributeSet.Add(new LdapAttribute("objectClass", "posixGroup")); + attributeSet.Add(new LdapAttribute("objectClass", "top")); + attributeSet.Add(new LdapAttribute("cn", cn)); + attributeSet.Add(new LdapAttribute("gidNumber", gidNumber)); + attributeSet.Add(new LdapAttribute( + "description", + JsonSerializer.Serialize(new GroupPermissions() + { + Permissions = [.. permissions] + }))); + await _ldap.CreateGroup(cn, attributeSet); return true; } diff --git a/src/Controllers/UsersController.cs b/src/Controllers/UsersController.cs index 5430b89..4251149 100644 --- a/src/Controllers/UsersController.cs +++ b/src/Controllers/UsersController.cs @@ -74,17 +74,16 @@ public class UsersController : Controller byte[] hashedPassword = SHA256.HashData(passwordBytes); userPassword = "{SHA256}" + Convert.ToBase64String(hashedPassword); } - LdapAttributeSet attributeSet = - [ - new LdapAttribute("objectClass", "inetOrgPerson"), - new LdapAttribute("cn", cn), - new LdapAttribute("sn", sn), - new LdapAttribute("title", title), - new LdapAttribute("uid", uid), - new LdapAttribute("jpegPhoto", jpegPhoto), - new LdapAttribute("description", description), - new LdapAttribute("userPassword", userPassword) - ]; + + LdapAttributeSet attributeSet = new LdapAttributeSet(); + attributeSet.Add(new LdapAttribute("objectClass", "inetOrgPerson")); + attributeSet.Add(new LdapAttribute("cn", cn)); + attributeSet.Add(new LdapAttribute("sn", sn)); + attributeSet.Add(new LdapAttribute("title", title)); + attributeSet.Add(new LdapAttribute("uid", uid)); + attributeSet.Add(new LdapAttribute("jpegPhoto", jpegPhoto)); + attributeSet.Add(new LdapAttribute("description", description)); + attributeSet.Add(new LdapAttribute("userPassword", userPassword)); await _ldap.CreateUser(uid, attributeSet); return true; } From ef3be7cb41dc751e17cdd04a7a9d62c639a68b52 Mon Sep 17 00:00:00 2001 From: anomny Date: Sat, 4 Oct 2025 14:37:10 +0200 Subject: [PATCH 2/5] CRUD - Assets create --- src/Controllers/AssetsController.cs | 50 ++++++++++++++++++++++++++ src/Models/AssetsCreateRequestModel.cs | 11 ++++++ src/Services/LdapService.cs | 14 +++++--- 3 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 src/Models/AssetsCreateRequestModel.cs diff --git a/src/Controllers/AssetsController.cs b/src/Controllers/AssetsController.cs index 5e8b44f..f273111 100644 --- a/src/Controllers/AssetsController.cs +++ b/src/Controllers/AssetsController.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Mvc; using Berufsschule_HAM.Models; using Berufsschule_HAM.Services; using System.Text.Json; +using Novell.Directory.Ldap; [Route("[controller]")] public class AssetsController : Controller @@ -22,6 +23,55 @@ public class AssetsController : Controller return list; } + [HttpPost("Create")] + public async Task Create(AssetsCreateRequestModel assetModel) + { + if (assetModel is null) + { + _logger.LogError("Unable to create an asset because the AssetModel is null."); + return false; + } + + try + { + var ownerDn = $"uid={assetModel.Owner},ou=people,dc=example,dc=com"; + + var attributeSet = new LdapAttributeSet(); + attributeSet.Add(new LdapAttribute("objectClass", new[] { + "top", + "device", + "extensibleObject" + })); + attributeSet.Add(new LdapAttribute("cn", assetModel.Cn)); + attributeSet.Add(new LdapAttribute("serialNumber", assetModel.SerialNumber)); + attributeSet.Add(new LdapAttribute("l", assetModel.Location)); + attributeSet.Add(new LdapAttribute("owner", ownerDn)); + attributeSet.Add(new LdapAttribute("name", assetModel.Name)); + attributeSet.Add(new LdapAttribute( + "description", + JsonSerializer.Serialize(new AssetDescription() + { + Type = assetModel.Description.Type, + Purchase = new AssetPurchase + { + PurchasedAt = assetModel.Description.Purchase.PurchasedAt, + PurchaseDate = assetModel.Description.Purchase.PurchaseDate, + PurchaseValue = assetModel.Description.Purchase.PurchaseValue + } + }) + )); + + await _ldap.CreateAsset(attributeSet); + + return true; + } + catch (Exception e) + { + _logger.LogError("Unable to create an asset because the Exception: " + e.Message); + return false; + } + } + [HttpGet("Delete")] public async Task Delete(string cn) { diff --git a/src/Models/AssetsCreateRequestModel.cs b/src/Models/AssetsCreateRequestModel.cs new file mode 100644 index 0000000..fff5224 --- /dev/null +++ b/src/Models/AssetsCreateRequestModel.cs @@ -0,0 +1,11 @@ +namespace Berufsschule_HAM.Models; + +public class AssetsCreateRequestModel +{ + public required string Cn { get; set; } + public AssetDescription? Description { get; set; } = null; + public string? Location { get; set; } = null; + public string? Name { get; set; } = null; + public string? Owner { get; set; } = null; + public string? SerialNumber { get; set; } = null; +} \ No newline at end of file diff --git a/src/Services/LdapService.cs b/src/Services/LdapService.cs index 53ac8eb..32d93bc 100644 --- a/src/Services/LdapService.cs +++ b/src/Services/LdapService.cs @@ -175,10 +175,16 @@ public partial class LdapService : IDisposable await CreateObject(dn, attributeSet); } - public async Task CreateAsset(LdapAttributeSet attributeSet) - { - await CreateObject(AssetsBaseDn, attributeSet); - } +public async Task CreateAsset(LdapAttributeSet attributeSet) +{ + string? cn = attributeSet.GetAttribute("cn")?.StringValue; + + if (string.IsNullOrEmpty(cn)) + throw new ArgumentException("AttributeSet must contain a cn attribute."); + + string dn = PrependRDN($"cn={cn}", AssetsBaseDn); + await CreateObject(dn, attributeSet); +} public async Task CreateLocation(LdapAttributeSet attributeSet) { From 285a0968ecfe4835616de689e9e25afbd5262925 Mon Sep 17 00:00:00 2001 From: anomny Date: Sat, 4 Oct 2025 15:11:08 +0200 Subject: [PATCH 3/5] Use collection initializers --- src/Controllers/AssetsController.cs | 44 ++++++++++++++--------------- src/Controllers/GroupsController.cs | 26 +++++++++-------- src/Controllers/UsersController.cs | 20 +++++++------ 3 files changed, 46 insertions(+), 44 deletions(-) diff --git a/src/Controllers/AssetsController.cs b/src/Controllers/AssetsController.cs index f273111..1d040a4 100644 --- a/src/Controllers/AssetsController.cs +++ b/src/Controllers/AssetsController.cs @@ -36,30 +36,28 @@ public class AssetsController : Controller { var ownerDn = $"uid={assetModel.Owner},ou=people,dc=example,dc=com"; - var attributeSet = new LdapAttributeSet(); - attributeSet.Add(new LdapAttribute("objectClass", new[] { - "top", - "device", - "extensibleObject" - })); - attributeSet.Add(new LdapAttribute("cn", assetModel.Cn)); - attributeSet.Add(new LdapAttribute("serialNumber", assetModel.SerialNumber)); - attributeSet.Add(new LdapAttribute("l", assetModel.Location)); - attributeSet.Add(new LdapAttribute("owner", ownerDn)); - attributeSet.Add(new LdapAttribute("name", assetModel.Name)); - attributeSet.Add(new LdapAttribute( - "description", - JsonSerializer.Serialize(new AssetDescription() - { - Type = assetModel.Description.Type, - Purchase = new AssetPurchase + LdapAttributeSet attributeSet = + [ + new LdapAttribute("objectClass", new[] {"top", "device", "extensibleObject"}), + new LdapAttribute("cn", assetModel.Cn), + new LdapAttribute("serialNumber", assetModel.SerialNumber), + new LdapAttribute("l", assetModel.Location), + new LdapAttribute("owner", ownerDn), + new LdapAttribute("name", assetModel.Name), + new LdapAttribute( + "description", + JsonSerializer.Serialize(new AssetDescription() { - PurchasedAt = assetModel.Description.Purchase.PurchasedAt, - PurchaseDate = assetModel.Description.Purchase.PurchaseDate, - PurchaseValue = assetModel.Description.Purchase.PurchaseValue - } - }) - )); + Type = assetModel.Description!.Type, + Purchase = new AssetPurchase + { + PurchasedAt = assetModel.Description.Purchase!.PurchasedAt, + PurchaseDate = assetModel.Description.Purchase.PurchaseDate, + PurchaseValue = assetModel.Description.Purchase.PurchaseValue + } + }) + ) + ]; await _ldap.CreateAsset(attributeSet); diff --git a/src/Controllers/GroupsController.cs b/src/Controllers/GroupsController.cs index 0ca257c..39e91df 100644 --- a/src/Controllers/GroupsController.cs +++ b/src/Controllers/GroupsController.cs @@ -65,19 +65,21 @@ public class GroupsController : Controller try { description ??= JsonSerializer.Serialize(new GroupPermissions() {Permissions = []}); - - var attributeSet = new LdapAttributeSet(); - attributeSet.Add(new LdapAttribute("objectClass", "posixGroup")); - attributeSet.Add(new LdapAttribute("objectClass", "top")); - attributeSet.Add(new LdapAttribute("cn", cn)); - attributeSet.Add(new LdapAttribute("gidNumber", gidNumber)); - attributeSet.Add(new LdapAttribute( - "description", - JsonSerializer.Serialize(new GroupPermissions() - { - Permissions = [.. permissions] - }))); + LdapAttributeSet attributeSet = + [ + new LdapAttribute("objectClass", "posixGroup"), + new LdapAttribute("objectClass", "top"), + new LdapAttribute("cn", cn), + new LdapAttribute("gidNumber", gidNumber), + new LdapAttribute( + "description", + JsonSerializer.Serialize(new GroupPermissions() + { + Permissions = [.. permissions] + })) + ]; + await _ldap.CreateGroup(cn, attributeSet); return true; } diff --git a/src/Controllers/UsersController.cs b/src/Controllers/UsersController.cs index 4251149..e2091f5 100644 --- a/src/Controllers/UsersController.cs +++ b/src/Controllers/UsersController.cs @@ -75,15 +75,17 @@ public class UsersController : Controller userPassword = "{SHA256}" + Convert.ToBase64String(hashedPassword); } - LdapAttributeSet attributeSet = new LdapAttributeSet(); - attributeSet.Add(new LdapAttribute("objectClass", "inetOrgPerson")); - attributeSet.Add(new LdapAttribute("cn", cn)); - attributeSet.Add(new LdapAttribute("sn", sn)); - attributeSet.Add(new LdapAttribute("title", title)); - attributeSet.Add(new LdapAttribute("uid", uid)); - attributeSet.Add(new LdapAttribute("jpegPhoto", jpegPhoto)); - attributeSet.Add(new LdapAttribute("description", description)); - attributeSet.Add(new LdapAttribute("userPassword", userPassword)); + LdapAttributeSet attributeSet = + [ + new LdapAttribute("objectClass", "inetOrgPerson"), + new LdapAttribute("cn", cn), + new LdapAttribute("sn", sn), + new LdapAttribute("title", title), + new LdapAttribute("uid", uid), + new LdapAttribute("jpegPhoto", jpegPhoto), + new LdapAttribute("description", description), + new LdapAttribute("userPassword", userPassword), + ]; await _ldap.CreateUser(uid, attributeSet); return true; } From 157e75f0bae41b4bc09a0d0173f820513a95b146 Mon Sep 17 00:00:00 2001 From: anomny Date: Sat, 4 Oct 2025 16:37:53 +0200 Subject: [PATCH 4/5] Add null check --- src/Controllers/AssetsController.cs | 77 +++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 21 deletions(-) diff --git a/src/Controllers/AssetsController.cs b/src/Controllers/AssetsController.cs index 1d040a4..c6ad432 100644 --- a/src/Controllers/AssetsController.cs +++ b/src/Controllers/AssetsController.cs @@ -34,38 +34,73 @@ public class AssetsController : Controller try { - var ownerDn = $"uid={assetModel.Owner},ou=people,dc=example,dc=com"; - LdapAttributeSet attributeSet = [ new LdapAttribute("objectClass", new[] {"top", "device", "extensibleObject"}), - new LdapAttribute("cn", assetModel.Cn), - new LdapAttribute("serialNumber", assetModel.SerialNumber), - new LdapAttribute("l", assetModel.Location), - new LdapAttribute("owner", ownerDn), - new LdapAttribute("name", assetModel.Name), - new LdapAttribute( - "description", - JsonSerializer.Serialize(new AssetDescription() - { - Type = assetModel.Description!.Type, - Purchase = new AssetPurchase - { - PurchasedAt = assetModel.Description.Purchase!.PurchasedAt, - PurchaseDate = assetModel.Description.Purchase.PurchaseDate, - PurchaseValue = assetModel.Description.Purchase.PurchaseValue - } - }) - ) ]; + if (assetModel.Cn != null) + { + attributeSet.Add(new LdapAttribute("cn", assetModel.Cn)); + } + if (assetModel.SerialNumber != null) + { + attributeSet.Add(new LdapAttribute("serialNumber", assetModel.SerialNumber)); + } + if (assetModel.Location != null) + { + attributeSet.Add(new LdapAttribute("l", assetModel.Location)); + } + if (assetModel.Owner != null) + { + var ownerDn = $"uid={assetModel.Owner},ou=people,dc=example,dc=com"; + attributeSet.Add(new LdapAttribute("owner", ownerDn)); + } + if (assetModel.Name != null) + { + attributeSet.Add(new LdapAttribute("name", assetModel.Name)); + } + if (assetModel.Description != null) + { + var assetDescription = new AssetDescription(); + + if (assetModel.Description.Type != null) + { + assetDescription.Type = assetModel.Description.Type; + } + if (assetModel.Description.Purchase != null) + { + var purchase = new AssetPurchase(); + if (assetModel.Description.Purchase.PurchasedAt != null) + { + purchase.PurchasedAt = assetModel.Description.Purchase.PurchasedAt; + } + if (assetModel.Description.Purchase.PurchaseDate != null) + { + purchase.PurchaseDate = assetModel.Description.Purchase.PurchaseDate; + } + if (assetModel.Description.Purchase.PurchasedBy != null) + { + purchase.PurchasedBy = assetModel.Description.Purchase.PurchasedBy; + } + if (assetModel.Description.Purchase.PurchaseValue != null) + { + purchase.PurchaseValue = assetModel.Description.Purchase.PurchaseValue; + } + + assetDescription.Purchase = purchase; + } + + attributeSet.Add(new LdapAttribute("description", JsonSerializer.Serialize(assetDescription))); + } + await _ldap.CreateAsset(attributeSet); return true; } catch (Exception e) { - _logger.LogError("Unable to create an asset because the Exception: " + e.Message); + _logger.LogError($"Unable to create an asset because of the exception: {e.Message}", e); return false; } } From a80f4b2f1634d07001d352051098fb2a96ca464b Mon Sep 17 00:00:00 2001 From: anomny Date: Sat, 4 Oct 2025 17:18:44 +0200 Subject: [PATCH 5/5] Remove additional owner information --- src/Controllers/AssetsController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controllers/AssetsController.cs b/src/Controllers/AssetsController.cs index c6ad432..bb6df84 100644 --- a/src/Controllers/AssetsController.cs +++ b/src/Controllers/AssetsController.cs @@ -53,7 +53,7 @@ public class AssetsController : Controller } if (assetModel.Owner != null) { - var ownerDn = $"uid={assetModel.Owner},ou=people,dc=example,dc=com"; + var ownerDn = $"uid={assetModel.Owner}"; attributeSet.Add(new LdapAttribute("owner", ownerDn)); } if (assetModel.Name != null)