From fe59972d2a08aa8570a416de0a9fd47cb0bc17b8 Mon Sep 17 00:00:00 2001 From: Niko Ehrenfeuchter <nikolaus.ehrenfeuchter@unibas.ch> Date: Wed, 17 Jan 2018 16:29:02 +0100 Subject: [PATCH] Move AD related methods to ATXCommon.ActiveDirectory. --- ATXSerializables/ATXCommon.csproj | 3 ++ ATXSerializables/ActiveDirectory.cs | 78 +++++++++++++++++++++++++++++ AutoTx/AutoTx.cs | 71 +------------------------- AutoTx/Email.cs | 7 +-- 4 files changed, 86 insertions(+), 73 deletions(-) create mode 100644 ATXSerializables/ActiveDirectory.cs diff --git a/ATXSerializables/ATXCommon.csproj b/ATXSerializables/ATXCommon.csproj index 6437a4c..4cd3753 100644 --- a/ATXSerializables/ATXCommon.csproj +++ b/ATXSerializables/ATXCommon.csproj @@ -37,6 +37,8 @@ <Reference Include="System" /> <Reference Include="System.Configuration" /> <Reference Include="System.Core" /> + <Reference Include="System.DirectoryServices.AccountManagement" /> + <Reference Include="System.Management" /> <Reference Include="System.Xml.Linq" /> <Reference Include="System.Data.DataSetExtensions" /> <Reference Include="Microsoft.CSharp" /> @@ -44,6 +46,7 @@ <Reference Include="System.Xml" /> </ItemGroup> <ItemGroup> + <Compile Include="ActiveDirectory.cs" /> <Compile Include="FsUtils.cs" /> <Compile Include="Serializables\DriveToCheck.cs" /> <Compile Include="Serializables\ServiceConfig.cs" /> diff --git a/ATXSerializables/ActiveDirectory.cs b/ATXSerializables/ActiveDirectory.cs new file mode 100644 index 0000000..98b99bf --- /dev/null +++ b/ATXSerializables/ActiveDirectory.cs @@ -0,0 +1,78 @@ +using System; +using System.DirectoryServices.AccountManagement; +using System.Linq; +using System.Management; +using NLog; + +namespace ATXCommon +{ + public static class ActiveDirectory + { + private static readonly Logger Log = LogManager.GetCurrentClassLogger(); + + /// <summary> + /// Check if a user is currently logged into Windows. + /// + /// WARNING: this DOES NOT ACCOUNT for users logged in via RDP!! + /// </summary> + /// See https://stackoverflow.com/questions/5218778/ for the RDP problem. + public static bool NoUserIsLoggedOn() { + var username = ""; + try { + var searcher = new ManagementObjectSearcher("SELECT UserName " + + "FROM Win32_ComputerSystem"); + var collection = searcher.Get(); + username = (string)collection.Cast<ManagementBaseObject>().First()["UserName"]; + } + catch (Exception ex) { + // TODO / FIXME: combine log and admin-email! + var msg = string.Format("Error in getCurrentUsername(): {0}", ex.Message); + Log.Error(msg); + // TODO: FIXME! + // SendAdminEmail(msg); + } + return username == ""; + } + + /// <summary> + /// Get the user email address from ActiveDirectory. + /// </summary> + /// <param name="username">The username.</param> + /// <returns>Email address of AD user, an empty string if not found.</returns> + public static string GetEmailAddress(string username) { + try { + using (var pctx = new PrincipalContext(ContextType.Domain)) { + using (var up = UserPrincipal.FindByIdentity(pctx, username)) { + if (up != null && !string.IsNullOrWhiteSpace(up.EmailAddress)) { + return up.EmailAddress; + } + } + } + } + catch (Exception ex) { + Log.Warn("Can't find email address for {0}: {1}", username, ex.Message); + } + return ""; + } + + /// <summary> + /// Get the full user name (human-friendly) from ActiveDirectory. + /// </summary> + /// <param name="username">The username.</param> + /// <returns>A human-friendly string representation of the user principal.</returns> + public static string GetFullUserName(string username) { + try { + using (var pctx = new PrincipalContext(ContextType.Domain)) { + using (var up = UserPrincipal.FindByIdentity(pctx, username)) { + if (up != null) + return up.GivenName + " " + up.Surname; + } + } + } + catch (Exception ex) { + Log.Warn("Can't find full name for {0}: {1}", username, ex.Message); + } + return ""; + } + } +} diff --git a/AutoTx/AutoTx.cs b/AutoTx/AutoTx.cs index 0167d2c..7263467 100644 --- a/AutoTx/AutoTx.cs +++ b/AutoTx/AutoTx.cs @@ -6,9 +6,6 @@ using System.Linq; using System.ServiceProcess; using System.IO; using System.Timers; -using System.DirectoryServices.AccountManagement; -using System.Globalization; -using System.Management; using NLog; using NLog.Config; using NLog.Targets; @@ -469,7 +466,7 @@ namespace AutoTx } // set state to "Running" if no-one is logged on: - if (NoUserIsLoggedOn()) { + if (ActiveDirectory.NoUserIsLoggedOn()) { _status.ServiceSuspended = false; if (!string.IsNullOrEmpty(_status.LimitReason)) { _status.LimitReason = ""; // reset to force a message on next service suspend @@ -512,72 +509,6 @@ namespace AutoTx #endregion - #region ActiveDirectory, email address, user name, ... - - /// <summary> - /// Check if a user is currently logged into Windows. - /// - /// WARNING: this DOES NOT ACCOUNT for users logged in via RDP!! - /// </summary> - /// See https://stackoverflow.com/questions/5218778/ for the RDP problem. - private bool NoUserIsLoggedOn() { - var username = ""; - try { - var searcher = new ManagementObjectSearcher("SELECT UserName " + - "FROM Win32_ComputerSystem"); - var collection = searcher.Get(); - username = (string) collection.Cast<ManagementBaseObject>().First()["UserName"]; - } - catch (Exception ex) { - // TODO / FIXME: combine log and admin-email! - var msg = string.Format("Error in getCurrentUsername(): {0}", ex.Message); - Log.Error(msg); - SendAdminEmail(msg); - } - return username == ""; - } - - /// <summary> - /// Get the user email address from ActiveDirectory. - /// </summary> - /// <param name="username">The username.</param> - /// <returns>Email address of AD user, an empty string if not found.</returns> - public string GetEmailAddress(string username) { - try { - using (var pctx = new PrincipalContext(ContextType.Domain)) { - using (var up = UserPrincipal.FindByIdentity(pctx, username)) { - if (up != null && !String.IsNullOrEmpty(up.EmailAddress)) { - return up.EmailAddress; - } - } - } - } - catch (Exception ex) { - Log.Warn("Can't find email address for {0}: {1}", username, ex.Message); - } - return ""; - } - - /// <summary> - /// Get the full user name (human-friendly) from ActiveDirectory. - /// </summary> - /// <param name="username">The username.</param> - /// <returns>A human-friendly string representation of the user principal.</returns> - public string GetFullUserName(string username) { - try { - using (var pctx = new PrincipalContext(ContextType.Domain)) { - using (var up = UserPrincipal.FindByIdentity(pctx, username)) { - if (up != null) return up.GivenName + " " + up.Surname; - } - } - } - catch (Exception ex) { - Log.Warn("Can't find full name for {0}: {1}", username, ex.Message); - } - return ""; - } - - #endregion #region transfer tasks diff --git a/AutoTx/Email.cs b/AutoTx/Email.cs index e036f4b..eefb9b2 100644 --- a/AutoTx/Email.cs +++ b/AutoTx/Email.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Net.Mail; using System.Text; +using ATXCommon; namespace AutoTx { @@ -23,7 +24,7 @@ namespace AutoTx } if (!recipient.Contains(@"@")) { Log.Debug("Invalid recipient, trying to resolve via AD: {0}", recipient); - recipient = GetEmailAddress(recipient); + recipient = ActiveDirectory.GetEmailAddress(recipient); } if (string.IsNullOrWhiteSpace(recipient)) { Log.Info("Invalid or empty recipient given, NOT sending email!"); @@ -149,7 +150,7 @@ namespace AutoTx } var substitutions = new List<Tuple<string, string>> { - Tuple.Create("FACILITY_USER", GetFullUserName(userDir)), + Tuple.Create("FACILITY_USER", ActiveDirectory.GetFullUserName(userDir)), Tuple.Create("HOST_ALIAS", _config.HostAlias), Tuple.Create("HOST_NAME", Environment.MachineName), Tuple.Create("DESTINATION_ALIAS", _config.DestinationAlias), @@ -181,7 +182,7 @@ namespace AutoTx var userDir = new DirectoryInfo(_status.CurrentTransferSrc).Name; var substitutions = new List<Tuple<string, string>> { - Tuple.Create("FACILITY_USER", GetFullUserName(userDir)), + Tuple.Create("FACILITY_USER", ActiveDirectory.GetFullUserName(userDir)), Tuple.Create("HOST_ALIAS", _config.HostAlias), Tuple.Create("HOST_NAME", Environment.MachineName), Tuple.Create("EMAIL_FROM", _config.EmailFrom) -- GitLab