<%@ WebService Language="C#" Class="GCS_CustomWebService" %> using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Web; using System.Web.Services; using System.Data; using System.Data.SqlClient; using System.Net.Mail; using System.Text; using System.Threading; using System.Configuration; using System.IO; using System.Web.Services.Protocols; using AppPortal.Business; using AppPortal.Business.Common; using AppPortal.Business.FNMP; /// /// Author's Name: Osagyefo Kouta-Lopatey /// Author's Company: Flexera Software /// Author's Department: Global Consulting Services /// /// UPDATE LOG /// DATE NAME DESCRIPTION /// 06-SEP-2021 Jim Dempsey Fixed GetTargetUserForRequest; /// Fixed GetLoggedInUserPropertyValue and GetUserPropertyValue to return string instead of datatable /// Updated to dynamically retrieve App Portal connection string; /// Removed dependency on BLTest web service; /// Removed customer-specific web methods. /// 30-SEP-2021 Jim Dempsey Added GetCatalogVariable and SetCatalogVariable web methods. /// 19-JAN-2022 Jim Dempsey Updated SetCatalogVariable to update catalog item UpdatedOn /// 26-JAN-2022 Jim Dempsey Added GCSLog and GCSErrorLog /// 29-JAN-2022 Jim Dempsey Added GetABSetting /// 11-FEB-2022 Jim Dempsey Added GetMachineDomainFromFNMS /// /// [WebService(Namespace = "http://flexerasoftware.com/AppPortal")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. // [System.Web.Script.Services.ScriptService] public class GCS_CustomWebService : System.Web.Services.WebService { const string LogFile = "GCS_CustomWebService.log"; // The filename for the log file const string ErrorLogFile = "GCS_CustomWebService_Error.log"; // The filename for the error log file /// /// Get the value of a specific request variable /// /// /// /// [WebMethod(Description=@"Get the value of an App Portal request variable.")] public string GetVariableValue(int requestID, string varName) { //Log.l1("Getting value for " + varName + " variable...", LogFile); SelfService.ESD esd = new SelfService.ESD(); DataTable dt = esd.getEmailVariables(requestID); dt.TableName = "EmailVariables"; foreach (DataRow row in dt.Rows) { if (row.Field(0) == "##" + varName + "##") { Log.l1("Variable Name: " + (row.Field(0)) + "; Variable Value = " + (row.Field(1)), LogFile, (int)LoggingLevel.NORMAL); return row.Field(1); } } string result = string.Format("Could not retrieve value for request variable {0}", varName); Log.l1(result, LogFile, (int)LoggingLevel.NORMAL); return result; } /// /// Get the target user of a request. /// /// The App Portal request ID /// Unique user name (domain\userid) of the target user of the request. [WebMethod(Description=@"Get the target user of a request.")] public string GetTargetUserForRequest(int requestId) { return GetVariableValue(requestId, "UniqueUserName"); } /// /// Get all the devices assigned to the logged in user. /// /// /// List of devices [WebMethod(Description=@"Get all the devices assigned to the logged in user.")] public DataTable GetDevicesForLoggedInUser() { string userUniqueId = GetUniqueIdForLoggedInUser(); SqlUtilities su = new SqlUtilities(ESDConfig.getConnString()); string sqlQuery = String.Format(@" SELECT MachineName FROM vUserComputerMap WHERE Active = 1 AND UniqueName = '{0}'", userUniqueId); DataTable dt = su.ExecuteSQLAndReturnDataSet(sqlQuery).Tables[0]; Log.l1(string.Format("Found '{0}' device(s) for {1}", (dt.Rows.Count).ToString(), userUniqueId), LogFile, (int)LoggingLevel.VERBOSE); if (dt.Rows.Count > 0) { foreach (DataRow row in dt.Rows) { Log.l1(row.Field(0), LogFile, (int)LoggingLevel.VERBOSE); } } return dt; } /// /// Get the unique id of the logged in user. /// /// The user's unique user name. /// The unique user name [WebMethod(Description =@"Get the unique ID (domain\username) of the logged in user.")] public string GetUniqueIdForLoggedInUser() { return System.Web.HttpContext.Current.User.Identity.Name; // who is logged into the machine from which you are accessing App Portal. Assuming that the same user is logged into App Portal //string i = HttpContext.Current.Session("UniqueUserName").ToString(); //return i; } /// /// Get all the devices assigned to a specific user. /// /// The user's unique user name (domain\userid). /// List of devices [WebMethod(Description=@"Get all the devices assigned to a specific user.")] public DataTable GetDevicesForUser(string userUniqueId) { SqlUtilities su = new SqlUtilities(ESDConfig.getConnString()); string sqlQuery = String.Format(@" SELECT MachineName FROM vUserComputerMap WHERE Active = 1 AND UniqueName = '{0}'", userUniqueId); DataTable dt = su.ExecuteSQLAndReturnDataSet(sqlQuery).Tables[0]; Log.l1(string.Format("Found '{0}' device(s) for {1}", (dt.Rows.Count).ToDbString(), userUniqueId), LogFile, (int)LoggingLevel.VERBOSE); return dt; } /// /// Get a specific property of the logged in user from the App Portal database. /// The logged in user is also the requester. /// /// The name of the user property. /// The value of the user property. [WebMethod(Description=@"Get a specific AD property of the logged in user.")] public string GetLoggedInUserPropertyValue(string propertyName) { string userUniqueId = GetUniqueIdForLoggedInUser(); //@"flex\jsmith"; string propertyValue = ""; SqlUtilities su = new SqlUtilities(ESDConfig.getConnString()); string sqlQuery = String.Format(@" SELECT {0} FROM WD_User WHERE UniqueName = '{1}'", propertyName, userUniqueId); //Log.l1(string.Format("sqlQuery: {0}", sqlQuery), LogFile, (int)LoggingLevel.VERBOSE); propertyValue = su.ExecuteSQLAndReturnSingleValue(sqlQuery).ToDbString(); Log.l1(string.Format("User: {0}, Property name: {1}, Value: {2}", userUniqueId, propertyName, propertyValue), LogFile, (int)LoggingLevel.VERBOSE); return propertyValue; } /// /// Get a specific property of the specified user from the App Portal database. /// /// The name of the user property. /// The user's unique user name (domain\userid). /// The value of the user property. [WebMethod(Description=@"Get a specific AD property of a specific user.")] public string GetUserPropertyValue(string userUniqueId, string propertyName) { string propertyValue = ""; SqlUtilities su = new SqlUtilities(ESDConfig.getConnString()); string sqlQuery = String.Format(@" SELECT {0} FROM WD_User WHERE UniqueName = '{1}'", propertyName, userUniqueId); //Log.l1(string.Format("sqlQuery: {0}", sqlQuery), LogFile, (int)LoggingLevel.VERBOSE); propertyValue = su.ExecuteSQLAndReturnSingleValue(sqlQuery).ToDbString(); Log.l1(string.Format("User: {0}, Property name: {1}, Value: {2}", userUniqueId, propertyName, propertyValue), LogFile, (int)LoggingLevel.VERBOSE); return propertyValue; } /// /// Add user to or remove user from an AD group. /// /// The AD user id. /// The name of the AD group. /// The action to perform. Either 'add' or 'remove'. /// The value of the user property. [WebMethod(Description=@"Add user to or remove user from an AD group. Valid values for strAction are 'Add' or 'Remove' (without the quotes). The default action is 'Add'.")] public int AddRemoveADGroupMember(string strUserName, string strGroupName, string strAction) { string strADAction = string.Empty; if (string.IsNullOrEmpty(strAction)) { strADAction = "Add"; Log.l1(string.Format("AD action/operation has not been specified. '{0}' is the default operation", strADAction), LogFile, (int)LoggingLevel.VERBOSE); } else { // Make sure the action is in Title Case TextInfo ti = new CultureInfo("en-US",false).TextInfo; strADAction = string.Format("{0}{1}", ti.ToUpper(strAction[0]), ti.ToLower(strAction.Substring(1))); } Log.l1(string.Format("AddRemoveADGroupMember: {0} | {1} | {2}", strADAction, strUserName, strGroupName), LogFile, (int)LoggingLevel.VERBOSE); DirectoryServices ds = new DirectoryServices(); // Get AD group GUID string groupguid = ds.getGUIDFromName(strGroupName); Log.l1(string.Format(" --GUID for AD Group '{0}': {1}", strGroupName, groupguid), LogFile, (int)LoggingLevel.VERBOSE); // Get AD user DN string userdn = ActiveDirectory.getDNFromName(strUserName); Log.l1(string.Format(" --DN for AD User '{0}': {1}", strUserName, userdn), LogFile, (int)LoggingLevel.VERBOSE); ActiveDirectory ad = new ActiveDirectory(); try { // Add user to or remove user from group int oResult = ad.AddUserToGroup(userdn, groupguid, strADAction); if (oResult == 1) { Log.l1(string.Format(" --'{0}' operation was completed successfully", strADAction), LogFile, (int)LoggingLevel.VERBOSE); return oResult; } else { Log.l1(string.Format(" --'{0}' operation failed", strADAction), LogFile, (int)LoggingLevel.VERBOSE); return oResult; } } catch (Exception ex) { Log.l1(string.Format(" --Exception calling AddUserToGroup: {0}, {1}, {2}", strADAction, strUserName, strGroupName, ex), LogFile, (int)LoggingLevel.VERBOSE); Log.l("AddUserToGroup", ex, LogFile); } return 0; } /// /// Get the value of a specific catalog variable for the specified catalog item. /// /// The package ID of the desired catalog item (use 0 if getting a global catalog variable). /// The name of the catalog variable to be retrieved (use the full name, including the prefix and underscore). /// The value of the specified catalog variable. [WebMethod(Description=@"Get the value of a specific catalog variable on a specific catalog item. (Use packageId=0 for a global variable. Use the full variableName, including the prefix and underscore - e.g. Custom_Template instead of Template.)")] public string GetCatalogVariable(int packageId, string variableName) { string variableValue = ""; SqlUtilities su = new SqlUtilities(ESDConfig.getConnString()); string sqlQuery = String.Format(@" SELECT [Value] FROM WD_CatalogVariable WHERE [CatalogID] = {0} AND [Key] = '{1}'", packageId, variableName); //Log.l1(string.Format("sqlQuery: {0}", sqlQuery), LogFile, (int)LoggingLevel.VERBOSE); variableValue = su.ExecuteSQLAndReturnSingleValue(sqlQuery).ToDbString(); Log.l1(string.Format("Catalog Item: [{0}], Variable Name: [{1}], Variable Value: [{2}]", packageId, variableName, variableValue), LogFile, (int)LoggingLevel.VERBOSE); return variableValue; } /// /// Set the value of a specific catalog variable for the specified catalog item. /// /// The package ID of the desired catalog item (use 0 if setting a global catalog variable). /// The name of the catalog variable to be set (include the prefix and underscore). /// The value to be set for the specified catalog variable. /// The description of the catalog variable to be set. [OPTIONAL] /// "Success" if the variable was set successfully or an error message if the variable was not set. [WebMethod(Description=@"Set the value of a specific catalog variable on a specific catalog item. (Use packageId=0 for a global variable. Include the prefix and underscore in the variableName - e.g. Custom_Template instead of Template. variableDescription is optional.)")] public string SetCatalogVariable(int packageId, string variableName, string variableValue, string variableDescription="") { string retVal = ""; if (string.IsNullOrEmpty(variableName)) { retVal = "Error: variableName must not be empty"; Log.l1(retVal, LogFile); return retVal; } SqlUtilities su = new SqlUtilities(ESDConfig.getConnString()); string sqlQuery = String.Format(@" DECLARE @Order int SET @Order = ISNULL((SELECT MAX([Order]) FROM WD_CatalogVariable WHERE [CatalogID]={0}) + 1, 0) IF EXISTS (SELECT * FROM WD_CatalogVariable WHERE [CatalogID] = {0} AND [Key] = '{1}') BEGIN UPDATE WD_CatalogVariable SET [Value]='{2}', [IsSaasCatalog]=0, [Description]='{3}' WHERE [CatalogID] = {0} AND [Key] = '{1}' END ELSE BEGIN INSERT INTO WD_CatalogVariable ([Key], [Value], [Order], [CatalogID], [IsSaasCatalog], [Description]) VALUES ('{1}', '{2}', @Order, {0}, 0, '{3}') END", packageId, variableName, variableValue, variableDescription); //Log.l1(string.Format("sqlQuery: {0}", sqlQuery), LogFile, (int)LoggingLevel.VERBOSE); try { int rows = su.ExecuteSQL(sqlQuery); if (rows > 0) { retVal = "Success"; Log.l1(string.Format("Successfully inserted or updated {0} row(s) in WD_CatalogVariable for Catalog Item: [{1}], Variable Name: [{2}], Variable Value: [{3}], Variable Description: [{4}]", rows, packageId, variableName, variableValue, variableDescription), LogFile, (int)LoggingLevel.VERBOSE); string userUniqueId = GetUniqueIdForLoggedInUser(); //@"flex\jsmith"; sqlQuery = String.Format(@" UPDATE WD_WebPackages SET [UpdatedOn]=GETDATE(), [UpdatedBy]='{1}' WHERE [PackageID] = {0}", packageId, userUniqueId); rows = su.ExecuteSQL(sqlQuery); } else { retVal = string.Format("Error: Unable to insert or update WD_CatalogVariable for Catalog Item: [{0}], Variable Name: [{1}]", packageId, variableName); Log.l1(retVal, LogFile); } } catch(Exception ex) { retVal = string.Format("Error: {0}", ex.Message); Log.l1(string.Format("Error: Unable to insert or update WD_CatalogVariable for Catalog Item: [{0}], Variable Name: [{1}]", packageId, variableName), LogFile); Log.l1(retVal, LogFile); } return retVal; } /// /// Add a message to the specified log file /// /// The message to write to the log. /// The log file to which the message will be written. /// bool value indicating success/failure writing to the log. [WebMethod(Description=@"Add a message to the specified log file.")] public bool GCSLog(string strMessage, string strLogFile=LogFile) { try { Log.l1(strMessage, strLogFile); } catch { return false; } return true; } /// /// Add an error message to the specified log file and corresponding error log file /// /// The message to write to the log. /// The log file to which the message will be written. /// bool value indicating success/failure writing to the log. [WebMethod(Description=@"Add an error message to the specified log file and corresponding error log file.")] public bool GCSLogError(string strMessage, string strLogFile=LogFile) { string strErrorLogFile = strLogFile.Substring(0,strLogFile.Length-4) + @"_Error.log"; try { Log.l1(strMessage, strLogFile); Log.l1(strMessage, strErrorLogFile); } catch { return false; } return true; } /// /// Get the value of an App Broker setting. /// /// The name of the desired App Broker setting. /// The value of and App Broker setting. [WebMethod(Description=@"Get the value of an App Broker setting.")] public string GetABSetting(string strSetting) { if (strSetting=="ConnectionString") { return ESDConfig.getConnString(); } return ESDConfig.getConfigValue(strSetting).ToDbString(); } /// /// Get MachineDomain for a device from FNMS. /// /// The name of the device for which to look up the domain. /// The domain "flat name" for the specified device. [WebMethod(Description=@"Get all inventory devices from FNMS.")] public string GetMachineDomainFromFNMS(string strMachineName) { string strMachineDomain = ""; string fnmsServer = ESDConfig.getConfigValue("FNMSDBServer").ToDbString(); string fnmsDatabase = ESDConfig.getConfigValue("FNMSDBName").ToDbString(); string fnmsConnStr = String.Format("Data Source={0};Initial Catalog={1};Integrated Security=True;", fnmsServer, fnmsDatabase); SqlUtilities su = new SqlUtilities(fnmsConnStr); string sqlQuery = String.Format(@" SELECT cd.FlatName AS [MachineDomain] FROM ComplianceComputer cc JOIN ComplianceDomain cd ON cc.ComplianceDomainID = cd.ComplianceDomainID WHERE cc.ComputerName='{0}'", strMachineName); strMachineDomain = su.ExecuteSQLAndReturnSingleValue(sqlQuery).ToDbString(); Log.l1(string.Format("MachineName: [{0}], MachineDomain: [{1}]", strMachineName, strMachineDomain), LogFile, (int)LoggingLevel.VERBOSE); return strMachineDomain; } }