using Disco.Data.Repository; using Disco.Models.UI.Device; using Disco.Services.Interop.ActiveDirectory; using Disco.Services.Plugins; using Disco.Services.Plugins.Features.UIExtension; using System; using System.Text; using System.Web.Mvc; namespace Disco.Plugins.ADCompare.Features { [PluginFeature(Id = "ADCompareDeviceUI", Name = "Device Page - AD Compare")] public class DeviceUIExtension : UIExtensionFeature { public override void Initialize(DiscoDataContext Database) { Register(); } public override UIExtensionResult ExecuteAction(ControllerContext context, DeviceShowModel model) { var device = model.Device; if (device == null || string.IsNullOrEmpty(device.DeviceDomainId)) return Nothing(); var html = new StringBuilder(); // Wrapper div with unique ID for relocation html.Append("
"); html.Append("
"); html.Append("

"); html.Append(" AD Compare

"); try { var adAccount = ActiveDirectory.RetrieveADMachineAccount( device.DeviceDomainId, new[] { "managedBy", "lastLogonTimestamp" }); if (adAccount == null) { html.Append("
"); html.Append(" Computer not found in Active Directory"); html.Append("
"); } else { var managedByDN = adAccount.GetPropertyValue("managedBy"); var discoAssignedUser = device.AssignedUserId; var hasManagedBy = !string.IsNullOrEmpty(managedByDN); var hasAssignment = !string.IsNullOrEmpty(discoAssignedUser); string managedByDisplayName = hasManagedBy ? ExtractCNFromDN(managedByDN) : null; string assignedUserDN = null; if (hasAssignment) { try { var assignedUserAD = ActiveDirectory.RetrieveADUserAccount(discoAssignedUser); if (assignedUserAD != null) assignedUserDN = assignedUserAD.DistinguishedName; } catch { } } bool isMatch = false; if (!hasAssignment && !hasManagedBy) isMatch = true; else if (hasAssignment && hasManagedBy && assignedUserDN != null) isMatch = string.Equals(assignedUserDN, managedByDN, StringComparison.OrdinalIgnoreCase); html.Append(""); if (isMatch) { html.Append(""); } else { html.Append(""); } html.Append(""); html.Append(""); var lastLogonTicks = adAccount.GetPropertyValue("lastLogonTimestamp"); html.Append(""); if (adAccount.IsDisabled) { html.Append(""); } html.Append("
"); html.Append(" Managed By matches Assigned User"); html.Append("
"); html.Append(" Managed By does NOT match Assigned User"); html.Append("
Disco Assigned User"); if (hasAssignment) { html.Append(Encode(discoAssignedUser)); if (device.AssignedUser != null) { html.Append(" ("); html.Append(Encode(device.AssignedUser.DisplayName)); html.Append(")"); } } else { html.Append("Not assigned"); } html.Append("
AD Managed By"); if (hasManagedBy) { html.Append(Encode(managedByDisplayName ?? managedByDN)); } else { html.Append("Empty"); } html.Append("
Last Login"); if (lastLogonTicks > 0) { try { var lastLogon = DateTime.FromFileTime(lastLogonTicks); var ago = DateTime.Now.Subtract(lastLogon); html.Append(Encode(lastLogon.ToString("dd/MM/yyyy hh:mm tt"))); html.Append(" ("); html.Append(FormatTimeAgo(ago)); html.Append(")"); } catch { html.Append("Unable to parse"); } } else { html.Append("Never"); } html.Append("
AD Status"); html.Append(" Disabled"); html.Append("
"); } } catch (Exception ex) { html.Append("
"); html.Append(" AD lookup error: "); html.Append(Encode(ex.Message)); html.Append("
"); } html.Append("
"); // form-group html.Append("
"); // wrapper // Script to relocate panel under the user assignment section html.Append(""); return Literal(html.ToString()); } private string ExtractCNFromDN(string dn) { if (string.IsNullOrEmpty(dn)) return null; if (dn.StartsWith("CN=", StringComparison.OrdinalIgnoreCase)) { var commaIndex = dn.IndexOf(','); if (commaIndex > 3) return dn.Substring(3, commaIndex - 3); return dn.Substring(3); } return dn; } private string Encode(string value) { if (string.IsNullOrEmpty(value)) return ""; return System.Web.HttpUtility.HtmlEncode(value); } private string FormatTimeAgo(TimeSpan span) { if (span.TotalDays >= 365) return string.Format("{0} year(s) ago", (int)(span.TotalDays / 365)); if (span.TotalDays >= 30) return string.Format("{0} month(s) ago", (int)(span.TotalDays / 30)); if (span.TotalDays >= 1) return string.Format("{0} day(s) ago", (int)span.TotalDays); if (span.TotalHours >= 1) return string.Format("{0} hour(s) ago", (int)span.TotalHours); return "Just now"; } } }