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; } /// /// Compare all Disco users against their Active Directory accounts. /// Returns a summary with per-user comparison results. /// 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; } /// /// Compare a single Disco user against their AD account. /// 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; } /// /// Compare a single field between Disco and AD values. /// Treats null and empty string as equivalent. /// 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)")); } } /// /// Normalise a value for comparison - treat null and whitespace as empty. /// private string NormaliseValue(string value) { if (string.IsNullOrWhiteSpace(value)) return string.Empty; return value.Trim(); } } }