Scan Active Directory for User Information

Fighting with a way to automatically get a windows authenticated users information from Active Directory.  Settled on the following methods.

Create a list of lookup functions for things to try

private static readonly IReadOnlyCollection<Func<IIdentity, User>> UserLookupFns = new List<Func<IIdentity, User>>
{
	ident => ident.FromUserPrincipal(),
	ident => ident.FromDirectoryEntry(),
	ident => ident.NoDetails()
};

Use multiple strategies to get user information

public static User ToUser(this IIdentity identity)
{
	foreach (var lookup in UserLookupFns)
	{
		var currentUser = lookup(identity) ?? new User();
		if (!currentUser.IsEmpty())
		{
			return currentUser;
		}
	}
	return identity.NoDetails();
}

From Directory Entries

private static User FromDirectoryEntry(this IIdentity identity)
{
	var fullName = identity.UserProperty(@"fullname") ?? "";
	if (string.IsNullOrEmpty(fullName))
	{
		return null;
	}
	return new User
	{
		Login = identity.Name,
		FirstName = fullName.SplitOnWhiteSpace().FirstOrDefault() ?? "",
		LastName = fullName.SplitOnWhiteSpace().LastOrDefault() ?? "",
		AutoEnrolled = true,
		Role = RoleActions.All().OrderBy(k => k.Key).FirstOrDefault().Key
	};
}
private static string UserProperty(this IIdentity identity, string propertyName)
{
	try
	{
		var userEntry = new DirectoryEntry($"WinNT://{identity.Domain()}/{identity.Login()},User");
		if (!userEntry.Properties.Contains(propertyName))
		{
			return "";
		}
		return (string)userEntry.Properties[propertyName].Value;
	}
	catch (Exception exc)
	{
		typeof(UserExtensions).Log().Warn(exc);
	}
	return "";
}

From Active Directory query

private static User FromDomain(this IIdentity identity)
{
	var username = identity.Login();
	var domain = identity.Domain();
	var domainContext = new PrincipalContext(ContextType.Domain, domain);
	var current = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, username);
	typeof(UserExtensions).Log().Debug($"Current user principal: {current.Dump()}");
	return current.ToUser(identity.Name);
}

private static string Domain(this IIdentity identity)
{
	var s = identity.Name;
	var stop = s.IndexOf("\\\\", StringComparison.Ordinal);
	return stop > -1 ? s.Substring(0, stop) : string.Empty;
}

private static string Login(this IIdentity identity)
{
	var s = identity.Name;
	var stop = s.IndexOf("\\\\", StringComparison.Ordinal);
	return stop > -1 ? s.Substring(stop + 1, s.Length - stop - 1) : string.Empty;
}