Files
disco-ad-compare-plugin/Features/ADCompareService.cs
T

120 lines
4.2 KiB
C#

using Disco.Data.Repository;
using Disco.Models.Repository;
using Disco.Plugins.ADCompare.Models;
using Disco.Services.Interop.ActiveDirectory;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Disco.Plugins.ADCompare.Features
{
public class ADCompareService
{
private readonly DiscoDataContext database;
public ADCompareService(DiscoDataContext database)
{
this.database = database;
}
/// <summary>
/// Compare all Disco users against their Active Directory accounts.
/// Returns a summary with per-user comparison results.
/// </summary>
public ComparisonSummary CompareAllUsers()
{
var summary = new ComparisonSummary();
// Load all users from Disco database
var discoUsers = database.Users.ToList();
summary.TotalDiscoUsers = discoUsers.Count;
foreach (var discoUser in discoUsers)
{
var result = CompareUser(discoUser);
summary.Results.Add(result);
}
summary.UsersCompared = summary.Results.Count(r => r.UserFoundInAD);
summary.UsersNotFoundInAD = summary.Results.Count(r => !r.UserFoundInAD);
summary.UsersWithMismatches = summary.Results.Count(r => r.HasMismatches);
summary.UsersInSync = summary.Results.Count(r => r.UserFoundInAD && !r.HasMismatches && !r.ADAccountDisabled);
summary.ADAccountsDisabled = summary.Results.Count(r => r.ADAccountDisabled);
return summary;
}
/// <summary>
/// Compare a single Disco user against their AD account.
/// </summary>
public UserComparisonResult CompareUser(User discoUser)
{
var result = new UserComparisonResult
{
UserId = discoUser.UserId,
DisplayName = discoUser.DisplayName
};
try
{
// Look up the user in AD using their UserId (DOMAIN\username format)
var adUser = ActiveDirectory.RetrieveADUserAccount(discoUser.UserId);
if (adUser == null)
{
result.UserFoundInAD = false;
return result;
}
result.UserFoundInAD = true;
result.ADAccountDisabled = adUser.IsDisabled;
// Compare core fields
CompareField(result, "Display Name", discoUser.DisplayName, adUser.DisplayName);
CompareField(result, "Surname", discoUser.Surname, adUser.Surname);
CompareField(result, "Given Name", discoUser.GivenName, adUser.GivenName);
CompareField(result, "Email Address", discoUser.EmailAddress, adUser.Email);
CompareField(result, "Phone Number", discoUser.PhoneNumber, adUser.Phone);
}
catch (Exception ex)
{
// If we can't look up the user in AD, mark as not found
result.UserFoundInAD = false;
result.Mismatches.Add(new FieldMismatch(
"AD Lookup Error",
discoUser.UserId,
ex.Message
));
}
return result;
}
/// <summary>
/// Compare a single field between Disco and AD values.
/// Treats null and empty string as equivalent.
/// </summary>
private void CompareField(UserComparisonResult result, string fieldName, string discoValue, string adValue)
{
var normalisedDisco = NormaliseValue(discoValue);
var normalisedAD = NormaliseValue(adValue);
if (!string.Equals(normalisedDisco, normalisedAD, StringComparison.OrdinalIgnoreCase))
{
result.Mismatches.Add(new FieldMismatch(fieldName, discoValue ?? "(empty)", adValue ?? "(empty)"));
}
}
/// <summary>
/// Normalise a value for comparison - treat null and whitespace as empty.
/// </summary>
private string NormaliseValue(string value)
{
if (string.IsNullOrWhiteSpace(value))
return string.Empty;
return value.Trim();
}
}
}