This commit is contained in:
Rhywden
2026-08-23 15:31:34 +02:00
5 changed files with 47 additions and 12 deletions
+5 -1
View File
@@ -28,6 +28,7 @@ else
<th>Classroom</th>
<th>Given name</th>
<th>Incomplete</th>
<th>Role</th>
</tr>
</thead>
<tbody>
@@ -39,6 +40,7 @@ else
<td>@user.Classroom</td>
<td>@user.GivenName</td>
<td>@user.Incomplete</td>
<td>@user.Role</td>
</tr>
}
</tbody>
@@ -56,7 +58,9 @@ else
private Task DownloadCsvAsync()
{
var csv = string.Join("\r\n", Users.Select(user => string.Join(';',
var csv = string.Join("\r\n", users!
.Where(user => user.Role == Wollmilchsau.Models.LdapUserRole.Student)
.Select(user => string.Join(';',
user.GivenName ?? string.Empty,
user.Surname ?? string.Empty,
user.Classroom ?? string.Empty,
+8 -1
View File
@@ -1,8 +1,15 @@
namespace Wollmilchsau.Models;
public enum LdapUserRole
{
Student,
Teacher
}
public sealed record LdapUser(
string Username,
string? Surname,
string? Classroom,
string? GivenName,
bool Incomplete);
bool Incomplete,
LdapUserRole Role);
@@ -24,4 +24,7 @@ public sealed class LdapOptions
[Required]
public string StudentsRole { get; init; } = string.Empty;
[Required]
public string TeacherRole { get; init; } = string.Empty;
}
+26 -5
View File
@@ -49,27 +49,30 @@ public sealed class LdapService(IOptions<LdapOptions> options) : ILdapService
private IEnumerable<LdapUser> GetUsers(LdapConnection connection)
{
var studentRoleDn = BuildDistinguishedName(_options.StudentsRole, _options.RoleBase);
var teacherRoleDn = BuildDistinguishedName(_options.TeacherRole, _options.RoleBase);
var request = new SearchRequest(
BuildDistinguishedName(_options.UserBase),
$"(memberOf={EscapeFilterValue(studentRoleDn)})",
$"(|(memberOf={EscapeFilterValue(studentRoleDn)})(memberOf={EscapeFilterValue(teacherRoleDn)}))",
SearchScope.Subtree,
"uid",
"sn",
"departmentNumber",
"givenName");
"givenName",
"memberOf");
var response = (SearchResponse)connection.SendRequest(request);
return response.Entries
.Cast<SearchResultEntry>()
.Select(CreateUser);
.Select(entry => CreateUser(entry, studentRoleDn, teacherRoleDn));
}
private LdapUser CreateUser(SearchResultEntry entry)
private LdapUser CreateUser(SearchResultEntry entry, string studentRoleDn, string teacherRoleDn)
{
var username = GetFirstAttributeValue(entry, "uid") ?? throw new InvalidOperationException($"LDAP user entry '{entry.DistinguishedName}' is missing uid.");
var surname = CapitalizeFirstLetter(GetFirstAttributeValue(entry, "sn"));
var classroom = GetFirstAttributeValue(entry, "departmentNumber");
var givenName = GetFirstAttributeValue(entry, "givenName");
var role = DetermineUserRole(entry, studentRoleDn, teacherRoleDn);
return new LdapUser(
username,
@@ -78,7 +81,25 @@ public sealed class LdapService(IOptions<LdapOptions> options) : ILdapService
givenName,
string.IsNullOrWhiteSpace(surname) ||
string.IsNullOrWhiteSpace(classroom) ||
string.IsNullOrWhiteSpace(givenName));
string.IsNullOrWhiteSpace(givenName),
role);
}
private static LdapUserRole DetermineUserRole(SearchResultEntry entry, string studentRoleDn, string teacherRoleDn)
{
var roles = GetAttributeValues(entry, "memberOf");
if (roles.Contains(studentRoleDn, StringComparer.OrdinalIgnoreCase))
{
return LdapUserRole.Student;
}
if (roles.Contains(teacherRoleDn, StringComparer.OrdinalIgnoreCase))
{
return LdapUserRole.Teacher;
}
throw new InvalidOperationException($"LDAP user entry '{entry.DistinguishedName}' is not a member of a supported role.");
}
private string BuildDistinguishedName(params string[] relativeNames)
+1 -1
View File
@@ -14,7 +14,7 @@
<PackageReference Include="Hangfire" Version="1.8.24" />
<PackageReference Include="Hangfire.AspNetCore" Version="1.8.24" />
<PackageReference Include="Hangfire.Redis.StackExchange" Version="1.12.0" />
<PackageReference Include="Marten.AspNetCore" Version="9.27.0" />
<PackageReference Include="Marten.AspNetCore" Version="9.28.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="10.0.11" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="10.0.11" />
<PackageReference Include="Microsoft.Graph" Version="6.5.0" />