diff --git a/src/Controllers/LocationsController.cs b/src/Controllers/LocationsController.cs index bdcefc1..8e46229 100644 --- a/src/Controllers/LocationsController.cs +++ b/src/Controllers/LocationsController.cs @@ -1,13 +1,19 @@ -// Controllers/LocationsController.cs using Berufsschule_HAM.Services; +using Berufsschule_HAM.Models; using Microsoft.AspNetCore.Mvc; -using System.Threading.Tasks; +using System.Text.Json; [Route("[controller]")] public class LocationsController : Controller { private readonly LdapService _ldap; - public LocationsController(LdapService ldap) => _ldap = ldap; + private readonly ILogger _logger; + + public LocationsController(LdapService ldap, ILogger logger) + { + _ldap = ldap; + _logger = logger; + } [HttpGet("Index")] public async Task>> Index() @@ -33,5 +39,45 @@ public class LocationsController : Controller } }); } + [HttpPost("Update")] + public async Task Update(LocationsModifyRequestModel requestModel) + { + if (requestModel is null) + { + _logger.LogError("Unable to update a location because the LocationsModifyRequestModel is null"); + return false; + } + string cn = requestModel.Cn; + if (requestModel.NewCn is not null) + { + await _ldap.UpdateLocation(cn, "cn", requestModel.NewCn); + cn = requestModel.NewCn; + } + if (requestModel.Location is not null) + { + await _ldap.UpdateLocation(cn, "location", requestModel.Location); + } + if (requestModel.Street is not null) + { + await _ldap.UpdateLocation(cn, "street", requestModel.Street); + } + if (requestModel.Description is not null) + { + LocationsDescription description = requestModel.Description; + LocationModel? location = null; + if (description.Seat is null) + { + location ??= await _ldap.GetLocationByCnAsync(cn); + description.Seat = location.Description?.Seat; + } + else if (description.RoomNumber is null) + { + location ??= await _ldap.GetLocationByCnAsync(cn); + description.RoomNumber = location.Description?.RoomNumber; + } + await _ldap.UpdateLocation(cn, "description", JsonSerializer.Serialize(requestModel.Description)); + } + return true; + } } diff --git a/src/Exceptions/ConfigurationExceptions.cs b/src/Exceptions/ConfigurationExceptions.cs index f021265..5ed0e25 100644 --- a/src/Exceptions/ConfigurationExceptions.cs +++ b/src/Exceptions/ConfigurationExceptions.cs @@ -1,3 +1,5 @@ namespace Berufsschule_HAM.Exceptions; -public class GroupModelConfigurationException : Exception {} \ No newline at end of file +public class GroupModelConfigurationException : Exception { } + +public class LocationModelConfigurationException : Exception { } \ No newline at end of file diff --git a/src/Models/LocationsModels.cs b/src/Models/LocationsModels.cs new file mode 100644 index 0000000..844d65e --- /dev/null +++ b/src/Models/LocationsModels.cs @@ -0,0 +1,31 @@ +namespace Berufsschule_HAM.Models; + +using System.Text.Json; +using Berufsschule_HAM.Exceptions; +public class LocationModel +{ + public required string Cn { get; set; } + public LocationsDescription? Description { get; set; } + public string? Location { get; set; } + public string? Street { get; set; } + public LocationModel(Dictionary ldapData) + { + Cn = ldapData.GetValueOrDefault("cn") ?? throw new LocationModelConfigurationException(); + Location = ldapData.GetValueOrDefault("l"); + Street = ldapData.GetValueOrDefault("street"); + string? descriptionValue = ldapData.GetValueOrDefault("description"); + if (descriptionValue is null) + { + Description = new(); + } + else + { + Description = JsonSerializer.Deserialize(descriptionValue); + } + } +} +public class LocationsDescription +{ + public string? RoomNumber { get; set; } + public string? Seat { get; set; } +} \ No newline at end of file diff --git a/src/Models/LocationsRequestModels.cs b/src/Models/LocationsRequestModels.cs new file mode 100644 index 0000000..0c9c76f --- /dev/null +++ b/src/Models/LocationsRequestModels.cs @@ -0,0 +1,10 @@ +namespace Berufsschule_HAM.Models; + +public class LocationsModifyRequestModel +{ + public required string Cn { get; set; } + public string? NewCn { get; set; } = null; + public LocationsDescription? Description { get; set; } = null; + public string? Location { get; set; } = null; + public string? Street { get; set; } = null; +} \ No newline at end of file diff --git a/src/Services/LdapService.cs b/src/Services/LdapService.cs index 323e4cc..5cdc3f0 100644 --- a/src/Services/LdapService.cs +++ b/src/Services/LdapService.cs @@ -46,7 +46,7 @@ public partial class LdapService : IDisposable 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 string[] UsersAttributes => ["cn", "sn", "title", "uid", "jpegPhoto", "userPassword", "description"]; - public string[] LocationsAttributes => ["l", "street", "description"]; + public string[] LocationsAttributes => ["cn", "l", "street", "description"]; public string[] GroupsAttributes => ["cn", "gidNumber", "description"]; public async Task>> ListLocationsAsync() { @@ -139,6 +139,14 @@ public partial class LdapService : IDisposable return new GroupModel((await ListObjectBy(GroupsBaseDn, $"cn={cn}", attributes)).First()) { Cn = cn }; } + public async Task GetLocationByCnAsync(string cn) + { + return await GetLocationByCnAsync(cn, LocationsAttributes); + } + public async Task GetLocationByCnAsync(string cn, string[] attributes) + { + return new LocationModel((await ListObjectBy(LocationsBaseDn, $"cn={cn}", attributes)).First()) { Cn = cn }; + } public async Task>> ListDeviceAsync() { @@ -285,6 +293,11 @@ public partial class LdapService : IDisposable await UpdateObject(GroupsBaseDn, "cn", cn, attributeName, attributeValue); } + public async Task UpdateLocation(string cn, string attributeName, string attributeValue) + { + await UpdateObject(LocationsBaseDn, "cn", cn, attributeName, attributeValue); + } + public async Task UpdateObject(string baseDn, string rdnKey, string rdnValue, string attributeName, string attributeValue) { await ConnectAndBind();