From d2cc376b87d32c158ff6bd73318bd446fb58e4cb Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Thu, 14 Jun 2018 11:55:38 -0700 Subject: [PATCH] Agent Proxy and Credential request handlers (#637) * Agent Proxy account WIP * Fixup Credential create\update\delete handlers * Use current user for test credential * Cleanup and delete code * Convert tabs to spaces --- .../Admin/Database/DatabasePrototype.cs | 2 +- .../Agent/AgentService.cs | 83 ++-- .../AgentUtilities.cs} | 5 +- .../Agent/Contracts/AgentProxyRequest.cs | 32 +- ...Account.cs => AgentProxyAccountActions.cs} | 170 ++++--- .../Agent/Jobs/IJobStepPropertiesControl.cs | 22 - .../Agent/Jobs/JobAlertsData.cs | 10 - .../Agent/Jobs/JobData.cs | 14 +- .../Agent/Jobs/JobFetcher.cs | 3 +- .../Agent/Jobs/JobHistoryItem.cs | 40 +- ...ications.cs => JobNotificationsActions.cs} | 6 +- .../Agent/Jobs/JobProperties.cs | 7 - ...JobSchedules.cs => JobSchedulesActions.cs} | 14 +- .../Agent/Jobs/JobSchedulesData.cs | 10 - .../Agent/Jobs/JobStepAdvancedLogging.cs | 2 + .../Agent/Jobs/JobStepData.cs | 38 +- .../Agent/Jobs/JobStepProperties.cs | 78 --- .../Agent/Jobs/JobStepPropertySheet.cs | 108 ----- .../Agent/Jobs/JobStepSubSystems.cs | 1 - .../Agent/Jobs/JobStepsActions.cs | 2 - .../Agent/Jobs/JobStepsData.cs | 30 +- .../Jobs/JobsReferencingScheduleControl.cs | 2 + .../Agent/Jobs/JobsReferencingScheduleForm.cs | 443 ------------------ .../Localization/sr.cs | 76 +++ .../Localization/sr.resx | 36 ++ .../Localization/sr.strings | 8 + .../Localization/sr.xlf | 44 ++ .../Management/Common/DataContainer.cs | 4 +- .../Management/Common/DbSize.cs | 2 +- .../Management/Common/ExecutionHandler.cs | 2 +- .../Security/Contracts/CredentialInfo.cs | 3 +- .../Security/Contracts/CredentialRequest.cs | 84 ++-- .../Security/Credential.cs | 98 ---- .../Security/CredentialActions.cs | 78 +++ .../Security/CredentialData.cs | 321 ++++++------- .../Security/SecurityService.cs | 93 +++- .../Agent/AgentProxyTests.cs | 107 +++-- .../Agent/AgentTestUtils.cs | 60 ++- .../Security/CredentialTests.cs | 92 ++++ .../Security/SecurityServiceTests.cs | 54 --- .../Security/SecurityTestUtils.cs | 95 ++++ 41 files changed, 1067 insertions(+), 1312 deletions(-) rename src/Microsoft.SqlTools.ServiceLayer/Agent/{Jobs/JobUtilities.cs => Common/AgentUtilities.cs} (96%) rename src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/{AgentProxyAccount.cs => AgentProxyAccountActions.cs} (75%) delete mode 100644 src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/IJobStepPropertiesControl.cs rename src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/{JobNotifications.cs => JobNotificationsActions.cs} (87%) rename src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/{JobSchedules.cs => JobSchedulesActions.cs} (95%) delete mode 100644 src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepProperties.cs delete mode 100644 src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepPropertySheet.cs delete mode 100644 src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobsReferencingScheduleForm.cs delete mode 100644 src/Microsoft.SqlTools.ServiceLayer/Security/Credential.cs create mode 100644 src/Microsoft.SqlTools.ServiceLayer/Security/CredentialActions.cs create mode 100644 test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/CredentialTests.cs delete mode 100644 test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/SecurityServiceTests.cs create mode 100644 test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/SecurityTestUtils.cs diff --git a/src/Microsoft.SqlTools.ServiceLayer/Admin/Database/DatabasePrototype.cs b/src/Microsoft.SqlTools.ServiceLayer/Admin/Database/DatabasePrototype.cs index 693d8076..e938e955 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Admin/Database/DatabasePrototype.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Admin/Database/DatabasePrototype.cs @@ -2042,7 +2042,7 @@ WHERE do.database_id = @DbID if ((null != sqlException) && CUtils.IsPermissionDeniedException(sqlException)) { - throw new Exception("SRError.SetOwnerFailed(this.Owner)" + ex.ToString()); + throw new Exception(SR.SetOwnerFailed(this.Owner) + ex.ToString()); } else { diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/AgentService.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/AgentService.cs index ed97b173..81193c47 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/AgentService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/AgentService.cs @@ -146,7 +146,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent foreach (var job in this.jobs.Values) { - agentJobs.Add(JobUtilities.ConvertToAgentJobInfo(job)); + agentJobs.Add(AgentUtilities.ConvertToAgentJobInfo(job)); } } result.Success = true; @@ -187,14 +187,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent if (count > 0) { var job = dt.Rows[0]; - string jobName = Convert.ToString(job[JobUtilities.UrnJobName], System.Globalization.CultureInfo.InvariantCulture); - Guid jobId = (Guid) job[JobUtilities.UrnJobId]; - int runStatus = Convert.ToInt32(job[JobUtilities.UrnRunStatus], System.Globalization.CultureInfo.InvariantCulture); + string jobName = Convert.ToString(job[AgentUtilities.UrnJobName], System.Globalization.CultureInfo.InvariantCulture); + Guid jobId = (Guid) job[AgentUtilities.UrnJobId]; + int runStatus = Convert.ToInt32(job[AgentUtilities.UrnRunStatus], System.Globalization.CultureInfo.InvariantCulture); var t = new LogSourceJobHistory(jobName, sqlConnInfo, null, runStatus, jobId, null); var tlog = t as ILogSource; tlog.Initialize(); var logEntries = t.LogEntries; - jobHistories = JobUtilities.ConvertToAgentJobHistoryInfo(logEntries, job); + jobHistories = AgentUtilities.ConvertToAgentJobHistoryInfo(logEntries, job); tlog.CloseReader(); } result.Jobs = jobHistories.ToArray(); @@ -506,45 +506,53 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent await requestContext.SendResult(null); } - internal async Task HandleCreateAgentProxyRequest(CreateAgentProxyParams parameters, RequestContext requestContext) + internal async Task HandleCreateAgentProxyRequest(CreateAgentProxyParams parameters, RequestContext requestContext) { - bool succeeded = await ConfigureAgentProxy( + var result = await ConfigureAgentProxy( parameters.OwnerUri, parameters.Proxy.AccountName, parameters.Proxy, - ConfigAction.Create); + ConfigAction.Create, + RunType.RunNow); - await requestContext.SendResult(new CreateAgentProxyResult() + await requestContext.SendResult(new AgentProxyResult() { - Success = succeeded + Success = result.Item1, + ErrorMessage = result.Item2, + Proxy = parameters.Proxy }); } - internal async Task HandleUpdateAgentProxyRequest(UpdateAgentProxyParams parameters, RequestContext requestContext) + internal async Task HandleUpdateAgentProxyRequest(UpdateAgentProxyParams parameters, RequestContext requestContext) { - bool succeeded = await ConfigureAgentProxy( + var result = await ConfigureAgentProxy( parameters.OwnerUri, - parameters.OriginalProxyName, + parameters.Proxy.AccountName, parameters.Proxy, - ConfigAction.Update); + ConfigAction.Update, + RunType.RunNow); - await requestContext.SendResult(new UpdateAgentProxyResult() + await requestContext.SendResult(new AgentProxyResult() { - Success = succeeded + Success = result.Item1, + ErrorMessage = result.Item2, + Proxy = parameters.Proxy }); } internal async Task HandleDeleteAgentProxyRequest(DeleteAgentProxyParams parameters, RequestContext requestContext) { - bool succeeded = await ConfigureAgentProxy( + var result = await ConfigureAgentProxy( parameters.OwnerUri, parameters.Proxy.AccountName, parameters.Proxy, - ConfigAction.Drop); + ConfigAction.Drop, + RunType.RunNow); await requestContext.SendResult(new ResultStatus() { - Success = succeeded + Success = result.Item1, + ErrorMessage = result.Item2 }); } @@ -682,49 +690,34 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent }); } - internal async Task ConfigureAgentProxy( + internal async Task> ConfigureAgentProxy( string ownerUri, string accountName, AgentProxyInfo proxy, - ConfigAction configAction) + ConfigAction configAction, + RunType runType) { return await Task.Run(() => { try { ConnectionInfo connInfo; - ConnectionServiceInstance.TryFindConnection( - ownerUri, - out connInfo); - + ConnectionServiceInstance.TryFindConnection(ownerUri, out connInfo); CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true); STParameters param = new STParameters(dataContainer.Document); param.SetParam("proxyaccount", accountName); - using (AgentProxyAccount agentProxy = new AgentProxyAccount(dataContainer, proxy)) + using (AgentProxyAccountActions agentProxy = new AgentProxyAccountActions(dataContainer, proxy, configAction)) { - if (configAction == ConfigAction.Create) - { - return agentProxy.Create(); - } - else if (configAction == ConfigAction.Update) - { - return agentProxy.Update(); - } - else if (configAction == ConfigAction.Drop) - { - return agentProxy.Drop(); - } - else - { - return false; - } + var executionHandler = new ExecutonHandler(agentProxy); + executionHandler.RunNow(runType, this); } + + return new Tuple(true, string.Empty); } - catch (Exception) + catch (Exception ex) { - // log exception here - return false; + return new Tuple(false, ex.ToString()); } }); } diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobUtilities.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Common/AgentUtilities.cs similarity index 96% rename from src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobUtilities.cs rename to src/Microsoft.SqlTools.ServiceLayer/Agent/Common/AgentUtilities.cs index bd6c0d5c..acf9343b 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobUtilities.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Common/AgentUtilities.cs @@ -11,11 +11,10 @@ using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.Sdk.Sfc; using Microsoft.SqlServer.Management.Smo.Agent; using Microsoft.SqlTools.ServiceLayer.Agent.Contracts; -using SMO = Microsoft.SqlServer.Management.Smo; namespace Microsoft.SqlTools.ServiceLayer.Agent { - public class JobUtilities + public class AgentUtilities { public const string UrnJobName = "JobName"; public const string UrnJobId = "JobId"; @@ -106,7 +105,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent { foreach (ILogEntry step in entry.SubEntries) { - jobSteps.Add(JobUtilities.ConvertToAgentJobStep(step, jobRow)); + jobSteps.Add(AgentUtilities.ConvertToAgentJobStep(step, jobRow)); } } jobHistoryInfo.Steps = jobSteps.ToArray(); diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Contracts/AgentProxyRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Contracts/AgentProxyRequest.cs index 3721ce32..77dbc915 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Contracts/AgentProxyRequest.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Contracts/AgentProxyRequest.cs @@ -29,6 +29,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent.Contracts public AgentProxyInfo[] Proxies { get; set; } } + /// + /// SQL Agent Proxy result + /// + public class AgentProxyResult : ResultStatus + { + public AgentProxyInfo Proxy { get; set; } + } + /// /// SQL Agent Proxy Accounts request type /// @@ -52,14 +60,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent.Contracts public AgentProxyInfo Proxy { get; set; } } - /// - /// SQL Agent create Proxy result - /// - public class CreateAgentProxyResult : ResultStatus - { - public AgentProxyInfo Proxy { get; set; } - } - /// /// SQL Agent create Proxy request type /// @@ -69,8 +69,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent.Contracts /// Request definition /// public static readonly - RequestType Type = - RequestType.Create("agent/createproxy"); + RequestType Type = + RequestType.Create("agent/createproxy"); } /// @@ -85,14 +85,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent.Contracts public AgentProxyInfo Proxy { get; set; } } - /// - /// SQL Agent update Proxy result - /// - public class UpdateAgentProxyResult : ResultStatus - { - public AgentProxyInfo Proxy { get; set; } - } - /// /// SQL Agent update Proxy request type /// @@ -102,8 +94,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent.Contracts /// Request definition /// public static readonly - RequestType Type = - RequestType.Create("agent/updateproxy"); + RequestType Type = + RequestType.Create("agent/updateproxy"); } /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/AgentProxyAccount.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/AgentProxyAccountActions.cs similarity index 75% rename from src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/AgentProxyAccount.cs rename to src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/AgentProxyAccountActions.cs index 6e908d12..556fedb7 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/AgentProxyAccount.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/AgentProxyAccountActions.cs @@ -6,19 +6,15 @@ using System; using System.Collections; using System.Data; -using System.Data.SqlClient; using Microsoft.SqlServer.Management.Common; -using Microsoft.SqlServer.Management.Diagnostics; using Microsoft.SqlServer.Management.Sdk.Sfc; -using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo.Agent; -using Microsoft.SqlTools.ServiceLayer.Admin; using Microsoft.SqlTools.ServiceLayer.Agent.Contracts; using Microsoft.SqlTools.ServiceLayer.Management; namespace Microsoft.SqlTools.ServiceLayer.Agent { - internal class AgentProxyAccount : ManagementActionBase + internal class AgentProxyAccountActions : ManagementActionBase { #region Constants internal const string ProxyAccountPropertyName = "proxyaccount"; @@ -47,35 +43,79 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent // Flag indicating that proxy account should be duplicated private bool duplicate; - public static string SysadminAccount - { - get { return "AgentProxyAccountSR.SysadminAccount"; } - } + private ConfigAction configAction; + + private bool readOnly = false; /// /// Main constructor. Creates all pages and adds them /// to the tree control. /// - public AgentProxyAccount(CDataContainer dataContainer, AgentProxyInfo proxyInfo) + public AgentProxyAccountActions(CDataContainer dataContainer, AgentProxyInfo proxyInfo, ConfigAction configAction) { this.DataContainer = dataContainer; this.proxyInfo = proxyInfo; + this.configAction = configAction; + + if (configAction != ConfigAction.Drop) + { + // Create data structures + int length = Enum.GetValues(typeof(ProxyPrincipalType)).Length; + this.principals = new ArrayList[length]; + for (int i = 0; i < length; ++i) + { + this.principals[i] = new ArrayList(); + } + + if (configAction == ConfigAction.Update) + { + RefreshData(); + } + } // Find out if we are creating a new proxy account or // modifying an existing one. GetProxyAccountName(dataContainer, ref this.proxyAccountName, ref this.duplicate); } + public static string SysadminAccount + { + get { return SR.SysadminAccount; } + } + + /// + /// Main execution method. Creates or Alters a proxyAccount name. + /// + /// Always returns false + protected override bool DoPreProcessExecution(RunType runType, out ExecutionMode executionResult) + { + base.DoPreProcessExecution(runType, out executionResult); + + if (this.configAction == ConfigAction.Create) + { + return Create(); + } + else if (this.configAction == ConfigAction.Update) + { + return Update(); + } + else if (this.configAction == ConfigAction.Drop) + { + return Drop(); + } + + // Always return false to stop framework from calling OnRunNow + return false; + } + /// /// It creates a new ProxyAccount or gets an existing /// one from JobServer and updates all properties. /// - private bool CreateOrUpdateProxyAccount( - AgentProxyInfo proxyInfo, - bool isUpdate) + private bool CreateOrUpdateProxyAccount(AgentProxyInfo proxyInfo) { ProxyAccount proxyAccount = null; - if (!isUpdate) + if (this.configAction == ConfigAction.Create) { proxyAccount = new ProxyAccount(this.DataContainer.Server.JobServer, proxyInfo.AccountName, @@ -91,14 +131,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent // Try refresh and check again this.DataContainer.Server.JobServer.ProxyAccounts.Refresh(); if (this.DataContainer.Server.JobServer.ProxyAccounts.Contains(this.proxyAccountName)) - { - // fail since account exists and asked to create a new one - if (!isUpdate) - { - return false; - } - - proxyAccount = AgentProxyAccount.GetProxyAccount(this.proxyAccountName, this.DataContainer.Server.JobServer); + { + proxyAccount = AgentProxyAccountActions.GetProxyAccount(this.proxyAccountName, this.DataContainer.Server.JobServer); // Set the other properties proxyAccount.CredentialName = proxyInfo.CredentialName; proxyAccount.Description = proxyInfo.Description; @@ -113,7 +147,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent { proxyAccount.Rename(proxyInfo.AccountName); } - } + } } else { @@ -178,13 +212,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent public bool Create() { - CreateOrUpdateProxyAccount(this.proxyInfo, false); + CreateOrUpdateProxyAccount(this.proxyInfo); return true; } public bool Update() { - CreateOrUpdateProxyAccount(this.proxyInfo, true); + CreateOrUpdateProxyAccount(this.proxyInfo); return true; } @@ -196,7 +230,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.DataContainer.Server.JobServer.ProxyAccounts.Refresh(); if (this.DataContainer.Server.JobServer.ProxyAccounts.Contains(this.proxyAccountName)) { - ProxyAccount proxyAccount = AgentProxyAccount.GetProxyAccount(this.proxyAccountName, this.DataContainer.Server.JobServer); + ProxyAccount proxyAccount = AgentProxyAccountActions.GetProxyAccount(this.proxyAccountName, this.DataContainer.Server.JobServer); proxyAccount.DropIfExists(); } } @@ -205,8 +239,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent } /// - /// Called to update the proxy object with properties - /// from this page. + /// Called to update the proxy object /// public void UpdateProxyAccount(ProxyAccount proxyAccount) { @@ -217,9 +250,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent ArrayList principalsToAdd = new ArrayList(); ArrayList principalsToRemove = new ArrayList(); - + // Process Sql Logins - if (ExtractPermissionsToAddAndRemove(this.proxyAccountName != null? proxyAccount.EnumLogins() : null, this.principals[(int) ProxyPrincipalType.SqlLogin], principalsToAdd, principalsToRemove)) + if (ExtractPermissionsToAddAndRemove( + this.configAction == ConfigAction.Update ? proxyAccount.EnumLogins() : null, + this.principals[(int) ProxyPrincipalType.SqlLogin], + principalsToAdd, + principalsToRemove)) { foreach (string principal in principalsToRemove) { @@ -233,7 +270,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent } // Process Server Roles - if (ExtractPermissionsToAddAndRemove(this.proxyAccountName != null? proxyAccount.EnumServerRoles() : null, this.principals[(int) ProxyPrincipalType.ServerRole], principalsToAdd, principalsToRemove)) + if (ExtractPermissionsToAddAndRemove( + this.configAction == ConfigAction.Update ? proxyAccount.EnumServerRoles() : null, + this.principals[(int) ProxyPrincipalType.ServerRole], + principalsToAdd, + principalsToRemove)) { foreach (string principal in principalsToRemove) { @@ -247,7 +288,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent } // Process Msdb Roles - if (ExtractPermissionsToAddAndRemove(this.proxyAccountName != null? proxyAccount.EnumMsdbRoles() : null, this.principals[(int) ProxyPrincipalType.MsdbRole], principalsToAdd, principalsToRemove)) + if (ExtractPermissionsToAddAndRemove( + this.configAction == ConfigAction.Update ? proxyAccount.EnumMsdbRoles() : null, + this.principals[(int) ProxyPrincipalType.MsdbRole], + principalsToAdd, + principalsToRemove)) { foreach (string principal in principalsToRemove) { @@ -261,7 +306,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent } } - /// /// This method scans two list of principals - an existing one extracted from ProxyAccount object /// and a new one obtained from this panel and then it creates a two differential lists: one of @@ -328,28 +372,40 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent private void RefreshData() { - // List all the jobsteps that use current - // proxy account - Request req = new Request(); - req.Urn = string.Format(System.Globalization.CultureInfo.InvariantCulture, - "Server/JobServer/Job/Step[@ProxyName=\'{0}\']", - Urn.EscapeString(this.proxyAccountName)); - req.ResultType = ResultType.IDataReader; - req.Fields = new string[] {"Name", "SubSystem"}; - req.ParentPropertiesRequests = new PropertiesRequest[1]; - req.ParentPropertiesRequests[0] = new PropertiesRequest(new string[] {"Name"}); - - Enumerator en = new Enumerator(); - using (IDataReader reader = en.Process(this.DataContainer.ServerConnection, req).Data as IDataReader) + // Reset all principal collections + for (int i = 0; i < this.principals.Length; ++i) { - while (reader.Read()) + this.principals[i].Clear(); + } + + // Add new data from proxy account + if (this.proxyAccountName != null) + { + ProxyAccount proxyAccount = GetProxyAccount(this.proxyAccountName, this.DataContainer.Server.JobServer); + + // Get all the logins associated with this proxy + DataTable dt = proxyAccount.EnumLogins(); + foreach (DataRow row in dt.Rows) { - //JobStepSubSystems. - // @TODO - write to output collection - // new GridCell(reader.GetString(0)), // Job Name (parent property is first) - // new GridCell(reader.GetString(1)), // JobStep Name - // new GridCell(JobStepSubSystems.LookupFriendlyName((AgentSubSystem) reader.GetInt32(2))) // JobStep SubSystem + this.principals[(int)ProxyPrincipalType.SqlLogin].Add(row["Name"]); } + + // Get all the Server roles associated with this proxy + dt = proxyAccount.EnumServerRoles(); + foreach (DataRow row in dt.Rows) + { + this.principals[(int)ProxyPrincipalType.ServerRole].Add(row["Name"]); + } + + // Get all the MSDB roles associated with this account + dt = proxyAccount.EnumMsdbRoles(); + foreach (DataRow row in dt.Rows) + { + this.principals[(int)ProxyPrincipalType.MsdbRole].Add(row["Name"]); + } + + // only sa can modify + this.readOnly = !this.DataContainer.Server.ConnectionContext.IsInFixedServerRole(FixedServerRoles.SysAdmin); } } @@ -383,7 +439,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent // if still cannot get the proxy throw an exception if (proxyAccount == null) { - throw new ApplicationException("SRError.ProxyAccountNotFound(proxyAccountName)"); + throw new ApplicationException(SR.ProxyAccountNotFound(proxyAccountName)); } } return proxyAccount; @@ -398,7 +454,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent parameters.SetDocument(dataContainer.Document); // Get proxy name - parameters.GetParam(AgentProxyAccount.ProxyAccountPropertyName, ref proxyAccountName); + parameters.GetParam(AgentProxyAccountActions.ProxyAccountPropertyName, ref proxyAccountName); if (proxyAccountName != null && proxyAccountName.Length == 0) { // Reset empty name back to null @@ -407,8 +463,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent // Get duplicate flag string mode = string.Empty; - if (parameters.GetParam(AgentProxyAccount.ProxyAccountMode, ref mode) && - 0 == string.Compare(mode, AgentProxyAccount.ProxyAccountDuplicateMode, StringComparison.Ordinal)) + if (parameters.GetParam(AgentProxyAccountActions.ProxyAccountMode, ref mode) && + 0 == string.Compare(mode, AgentProxyAccountActions.ProxyAccountDuplicateMode, StringComparison.Ordinal)) { duplicate = true; } @@ -434,7 +490,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent { if (includeSysadmin) { - proxyAccounts.Add(AgentProxyAccount.SysadminAccount); + proxyAccounts.Add(AgentProxyAccountActions.SysadminAccount); } // Get the list of proxy accounts diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/IJobStepPropertiesControl.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/IJobStepPropertiesControl.cs deleted file mode 100644 index fe1e8076..00000000 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/IJobStepPropertiesControl.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using Microsoft.SqlServer.Management.Sdk.Sfc; - -namespace Microsoft.SqlTools.ServiceLayer.Agent -{ - /// - /// Summary description for IJobStepPropertiesControl. - /// - internal interface IJobStepPropertiesControl - { - void Load(JobStepData data); - void Save(JobStepData data, bool isSwitching); - } -} - - - - - - - - diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobAlertsData.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobAlertsData.cs index 0f08c329..4b214367 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobAlertsData.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobAlertsData.cs @@ -3,19 +3,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // - using System; using System.Collections; -using System.Collections.Generic; -using System.Data; -using System.Globalization; -using Microsoft.SqlServer.Management.Common; -using Microsoft.SqlServer.Management.Sdk.Sfc; -using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo.Agent; -using Microsoft.SqlServer.Management.Diagnostics; -using Microsoft.SqlTools.ServiceLayer.Admin; -using SMO = Microsoft.SqlServer.Management.Smo; using Microsoft.SqlTools.ServiceLayer.Management; namespace Microsoft.SqlTools.ServiceLayer.Agent diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobData.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobData.cs index c3e4bf52..23e896b8 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobData.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobData.cs @@ -12,7 +12,6 @@ using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.Sdk.Sfc; using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo.Agent; -using Microsoft.SqlTools.ServiceLayer.Admin; using Microsoft.SqlTools.ServiceLayer.Agent.Contracts; using Microsoft.SqlTools.ServiceLayer.Management; using SMO = Microsoft.SqlServer.Management.Smo; @@ -523,15 +522,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent set { CheckAndLoadMsaInformation(); - //If a change in the targetLocalServer was detected, then fire the OnCategoriesChanged - //event so that the categories drop down list is properly populated. + // If a change in the targetLocalServer was detected, then fire the OnCategoriesChanged + // event so that the categories drop down list is properly populated. if (this.targetLocalServer != value) { this.targetLocalServer = value; this.displayableCategories = null; CheckAndLoadDisplayableCategories(); OnCategoriesChanged(); - //TODO: add method to do this? this.owners = null; OnOwnersChanged(); } @@ -581,7 +579,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent private void OnCategoriesChanged() { - //Fire the categories changed event. + // Fire the categories changed event. if (this.CategoriesChanged != null) { this.CategoriesChanged(this, EventArgs.Empty); @@ -589,7 +587,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent } private void OnOwnersChanged() { - //Fire the categories changed event. + // Fire the categories changed event. if (this.OwnersChanged != null) { this.OwnersChanged(this, EventArgs.Empty); @@ -1129,7 +1127,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent if (!targetServerSelected) { ///Not target servers selected. Throw error. - throw new ApplicationException("SRError.TargetServerNotSelected"); + throw new ApplicationException(SR.TargetServerNotSelected); } } @@ -1386,7 +1384,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent { if (smoJobCollection.Contains(jobName)) { - throw new ApplicationException("SRError.JobAlreadyExists(jobName)"); + throw new ApplicationException(SR.JobAlreadyExists(jobName)); } } finally diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobFetcher.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobFetcher.cs index 0f3adfc0..0d28b0e0 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobFetcher.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobFetcher.cs @@ -8,10 +8,11 @@ using System.Text; using System.Data; using System.Globalization; using System.Collections.Generic; + +using SMO = Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.Sdk.Sfc; using Microsoft.SqlServer.Management.Smo.Agent; -using SMO = Microsoft.SqlServer.Management.Smo; using Microsoft.SqlTools.ServiceLayer.Agent.Contracts; namespace Microsoft.SqlTools.ServiceLayer.Agent diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobHistoryItem.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobHistoryItem.cs index 0ca4be2b..57a19970 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobHistoryItem.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobHistoryItem.cs @@ -7,10 +7,6 @@ using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; -using System.Globalization; -using System.Text; -using System.Xml; -using Microsoft.SqlTools.ServiceLayer.Admin; using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.Sdk.Sfc; using Microsoft.SqlServer.Management.Smo.Agent; @@ -433,10 +429,10 @@ ORDER BY [InstanceID] ASC"; { m_originalSourceName = sourceName; - m_pointInTime = Convert.ToDateTime(dr[JobUtilities.UrnRunDate], System.Globalization.CultureInfo.InvariantCulture); - m_serverName = Convert.ToString(dr[JobUtilities.UrnServer], System.Globalization.CultureInfo.InvariantCulture); - m_fieldJobName = Convert.ToString(dr[JobUtilities.UrnJobName], System.Globalization.CultureInfo.InvariantCulture); - switch ((Microsoft.SqlServer.Management.Smo.Agent.CompletionResult)Convert.ToInt32(dr[JobUtilities.UrnRunStatus], System.Globalization.CultureInfo.InvariantCulture)) + m_pointInTime = Convert.ToDateTime(dr[AgentUtilities.UrnRunDate], System.Globalization.CultureInfo.InvariantCulture); + m_serverName = Convert.ToString(dr[AgentUtilities.UrnServer], System.Globalization.CultureInfo.InvariantCulture); + m_fieldJobName = Convert.ToString(dr[AgentUtilities.UrnJobName], System.Globalization.CultureInfo.InvariantCulture); + switch ((Microsoft.SqlServer.Management.Smo.Agent.CompletionResult)Convert.ToInt32(dr[AgentUtilities.UrnRunStatus], System.Globalization.CultureInfo.InvariantCulture)) { case CompletionResult.Cancelled: m_severity = SeverityClass.Cancelled; @@ -483,7 +479,7 @@ ORDER BY [InstanceID] ASC"; // if stepId is zero then dont show stepID and step name in log viewer // Valid step Ids starts from index 1 - int currentStepId = (int)dr[JobUtilities.UrnStepID]; + int currentStepId = (int)dr[AgentUtilities.UrnStepID]; if (currentStepId == 0) { m_fieldStepID = String.Empty; @@ -493,18 +489,18 @@ ORDER BY [InstanceID] ASC"; else { m_fieldStepID = Convert.ToString(currentStepId, System.Globalization.CultureInfo.CurrentCulture); - m_fieldStepName = Convert.ToString(dr[JobUtilities.UrnStepName], System.Globalization.CultureInfo.CurrentCulture); + m_fieldStepName = Convert.ToString(dr[AgentUtilities.UrnStepName], System.Globalization.CultureInfo.CurrentCulture); } - m_fieldMessage = Convert.ToString(dr[JobUtilities.UrnMessage], System.Globalization.CultureInfo.CurrentCulture); - m_fieldSqlSeverity = Convert.ToString(dr[JobUtilities.UrnSqlSeverity], System.Globalization.CultureInfo.CurrentCulture); - m_fieldSqlMessageID = Convert.ToString(dr[JobUtilities.UrnSqlMessageID], System.Globalization.CultureInfo.CurrentCulture); - m_fieldOperatorEmailed = Convert.ToString(dr[JobUtilities.UrnOperatorEmailed], System.Globalization.CultureInfo.CurrentCulture); - m_fieldOperatorNetsent = Convert.ToString(dr[JobUtilities.UrnOperatorNetsent], System.Globalization.CultureInfo.CurrentCulture); - m_fieldOperatorPaged = Convert.ToString(dr[JobUtilities.UrnOperatorPaged], System.Globalization.CultureInfo.CurrentCulture); - m_fieldRetriesAttempted = Convert.ToString(dr[JobUtilities.UrnRetriesAttempted], System.Globalization.CultureInfo.CurrentCulture); + m_fieldMessage = Convert.ToString(dr[AgentUtilities.UrnMessage], System.Globalization.CultureInfo.CurrentCulture); + m_fieldSqlSeverity = Convert.ToString(dr[AgentUtilities.UrnSqlSeverity], System.Globalization.CultureInfo.CurrentCulture); + m_fieldSqlMessageID = Convert.ToString(dr[AgentUtilities.UrnSqlMessageID], System.Globalization.CultureInfo.CurrentCulture); + m_fieldOperatorEmailed = Convert.ToString(dr[AgentUtilities.UrnOperatorEmailed], System.Globalization.CultureInfo.CurrentCulture); + m_fieldOperatorNetsent = Convert.ToString(dr[AgentUtilities.UrnOperatorNetsent], System.Globalization.CultureInfo.CurrentCulture); + m_fieldOperatorPaged = Convert.ToString(dr[AgentUtilities.UrnOperatorPaged], System.Globalization.CultureInfo.CurrentCulture); + m_fieldRetriesAttempted = Convert.ToString(dr[AgentUtilities.UrnRetriesAttempted], System.Globalization.CultureInfo.CurrentCulture); - Int64 hhmmss = Convert.ToInt64(dr[JobUtilities.UrnRunDuration], System.Globalization.CultureInfo.InvariantCulture); // HHMMSS + Int64 hhmmss = Convert.ToInt64(dr[AgentUtilities.UrnRunDuration], System.Globalization.CultureInfo.InvariantCulture); // HHMMSS int hh = Convert.ToInt32(hhmmss / 10000, System.Globalization.CultureInfo.InvariantCulture); int mm = Convert.ToInt32((hhmmss / 100) % 100, System.Globalization.CultureInfo.InvariantCulture); int ss = Convert.ToInt32(hhmmss % 100, System.Globalization.CultureInfo.InvariantCulture); @@ -537,7 +533,7 @@ ORDER BY [InstanceID] ASC"; { DataRow dr = dt.Rows[i]; - object o = dr[JobUtilities.UrnStepID]; + object o = dr[AgentUtilities.UrnStepID]; try { @@ -575,8 +571,8 @@ ORDER BY [InstanceID] ASC"; { m_originalSourceName = sourceName; - m_pointInTime = Convert.ToDateTime(dr[JobUtilities.UrnRunDate], System.Globalization.CultureInfo.InvariantCulture); - m_fieldJobName = Convert.ToString(dr[JobUtilities.UrnJobName], System.Globalization.CultureInfo.InvariantCulture); + m_pointInTime = Convert.ToDateTime(dr[AgentUtilities.UrnRunDate], System.Globalization.CultureInfo.InvariantCulture); + m_fieldJobName = Convert.ToString(dr[AgentUtilities.UrnJobName], System.Globalization.CultureInfo.InvariantCulture); m_severity = SeverityClass.InProgress; @@ -591,7 +587,7 @@ ORDER BY [InstanceID] ASC"; m_fieldRetriesAttempted = null; m_serverName = null; - m_fieldDuration = Convert.ToString(Convert.ToDateTime(dr[JobUtilities.UrnServerTime]) - Convert.ToDateTime(dr[JobUtilities.UrnRunDate], System.Globalization.CultureInfo.InvariantCulture), System.Globalization.CultureInfo.InvariantCulture); + m_fieldDuration = Convert.ToString(Convert.ToDateTime(dr[AgentUtilities.UrnServerTime]) - Convert.ToDateTime(dr[AgentUtilities.UrnRunDate], System.Globalization.CultureInfo.InvariantCulture), System.Globalization.CultureInfo.InvariantCulture); } catch (InvalidCastException) { diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobNotifications.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobNotificationsActions.cs similarity index 87% rename from src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobNotifications.cs rename to src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobNotificationsActions.cs index 0457411e..ba0582b5 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobNotifications.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobNotificationsActions.cs @@ -5,11 +5,11 @@ using System; using System.Collections; +using System.Globalization; using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.Sdk.Sfc; using Microsoft.SqlServer.Management.Smo.Agent; -using System.Globalization; using Microsoft.SqlTools.ServiceLayer.Management; using Microsoft.SqlTools.ServiceLayer.Admin; @@ -18,12 +18,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent /// /// Summary description for JobNotifications. /// - internal class JobNotifications : ManagementActionBase + internal class JobNotificationsActions : ManagementActionBase { private JobData data; private bool loading = false; - public JobNotifications(CDataContainer dataContainer, JobData data) + public JobNotificationsActions(CDataContainer dataContainer, JobData data) { this.DataContainer = dataContainer; this.data = data; diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobProperties.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobProperties.cs index 4eb8a40b..c1535950 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobProperties.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobProperties.cs @@ -4,15 +4,8 @@ // using System; -using System.Text; using System.Data; using System.Globalization; -using System.Collections.Generic; -using Microsoft.SqlServer.Management.Common; -using Microsoft.SqlServer.Management.Sdk.Sfc; -using Microsoft.SqlServer.Management.Smo.Agent; -using SMO = Microsoft.SqlServer.Management.Smo; -using Microsoft.SqlTools.ServiceLayer.Agent.Contracts; namespace Microsoft.SqlTools.ServiceLayer.Agent { diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobSchedules.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobSchedulesActions.cs similarity index 95% rename from src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobSchedules.cs rename to src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobSchedulesActions.cs index a4b699de..dfd36e38 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobSchedules.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobSchedulesActions.cs @@ -3,33 +3,23 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // -using Microsoft.SqlServer.Management.Sdk.Sfc; using System; -using System.Drawing; -using System.Collections; using System.Collections.Generic; -using System.ComponentModel; -using Microsoft.SqlServer.Management.Smo; -using Microsoft.SqlServer.Management.Common; -using Microsoft.SqlServer.Management.Smo.Agent; using System.Globalization; using System.Text; -using Microsoft.SqlServer.Management.SqlManagerUI; -using Microsoft.SqlServer.Management.Diagnostics; using Microsoft.SqlTools.ServiceLayer.Management; -using Microsoft.SqlTools.ServiceLayer.Admin; namespace Microsoft.SqlTools.ServiceLayer.Agent { /// /// Summary description for JobSchedules. /// - internal class JobSchedules : ManagementActionBase + internal class JobSchedulesActions : ManagementActionBase { private bool sharedSchedulesSupported = false; private JobData data; - public JobSchedules(CDataContainer dataContainer, JobData data) + public JobSchedulesActions(CDataContainer dataContainer, JobData data) { this.DataContainer = dataContainer; this.data = data; diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobSchedulesData.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobSchedulesData.cs index 9c6047ee..b07b4e40 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobSchedulesData.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobSchedulesData.cs @@ -3,21 +3,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // - using System; -using System.Collections; using System.Collections.Generic; -using System.Data; -using System.Globalization; -using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.Sdk.Sfc; -using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo.Agent; -using Microsoft.SqlServer.Management.Diagnostics; -using Microsoft.SqlTools.ServiceLayer.Admin; using Microsoft.SqlTools.ServiceLayer.Management; -using SMO = Microsoft.SqlServer.Management.Smo; - namespace Microsoft.SqlTools.ServiceLayer.Agent { diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepAdvancedLogging.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepAdvancedLogging.cs index 45e0be92..2c5e4afc 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepAdvancedLogging.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepAdvancedLogging.cs @@ -1,3 +1,4 @@ +#if false // // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. @@ -176,3 +177,4 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent #endregion } } +#endif \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepData.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepData.cs index 58e62bc4..46fa34b5 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepData.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepData.cs @@ -5,13 +5,9 @@ using System; using System.Collections; -using System.Collections.Generic; using System.Data; -using System.Globalization; using Microsoft.SqlServer.Management.Common; -using Microsoft.SqlServer.Management.Diagnostics; using Microsoft.SqlServer.Management.Sdk.Sfc; -using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo.Agent; using SMO = Microsoft.SqlServer.Management.Smo; @@ -202,6 +198,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent return this.alreadyCreated; } } + public bool ToBeDeleted { get @@ -213,6 +210,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.deleted = value; } } + public JobStepsData Parent { get @@ -220,6 +218,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent return this.parent; } } + public string[] Databases { get @@ -227,6 +226,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent return this.parent.Databases; } } + public bool StepIdChanged { get @@ -237,6 +237,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.id != this.originalId; } } + public bool IsReadOnly { get { return parent.IsReadOnly; } @@ -269,6 +270,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.command = value; } } + public int CommandExecutionSuccessCode { get @@ -282,6 +284,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.commandExecutionSuccessCode = value; } } + public string DatabaseName { get @@ -295,6 +298,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.databaseName = value; } } + public string DatabaseUserName { get @@ -308,6 +312,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.databaseUserName = value; } } + public string Server { get @@ -321,6 +326,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.server = value; } } + public int ID { get @@ -332,6 +338,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.id = value; } } + public StepCompletionAction FailureAction { get @@ -344,6 +351,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent return this.failureAction; } } + public JobStepData FailStep { get @@ -355,6 +363,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent return this.failStep; } } + public StepCompletionAction SuccessAction { get @@ -367,6 +376,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent return this.successAction; } } + public JobStepData SuccessStep { get @@ -378,6 +388,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent return this.successStep; } } + public OSRunPriority Priority { get @@ -391,6 +402,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.priority = value; } } + public string OutputFileName { get @@ -404,6 +416,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.outputFileName = value; } } + public bool AppendToLogFile { get @@ -417,6 +430,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.appendToLogFile = value; } } + public bool AppendToStepHistory { get @@ -430,6 +444,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.appendToStepHist = value; } } + public bool CanLogToTable { get @@ -437,6 +452,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent return this.Version.Major >= 9; } } + public bool WriteLogToTable { get @@ -450,6 +466,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.writeLogToTable = value; } } + public bool AppendLogToTable { get @@ -463,6 +480,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.appendLogToTable = value; } } + public int RetryAttempts { get @@ -476,6 +494,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.retryAttempts = value; } } + public int RetryInterval { get @@ -527,7 +546,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent { // Return sysadmin account name when proxy // name is not set, so we match the setter logic - return AgentProxyAccount.SysadminAccount; + return AgentProxyAccountActions.SysadminAccount; } else { @@ -537,7 +556,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent set { CheckAndLoadExpandedInformation(); - if (value == AgentProxyAccount.SysadminAccount) + if (value == AgentProxyAccountActions.SysadminAccount) { // Sysadmin is just a special name used // to reset proxy account @@ -558,18 +577,21 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent { SetDefaults(); } + // new job step with context public JobStepData(JobStepsData parent) { this.parent = parent; SetDefaults(); } + // existing job step public JobStepData(JobStep source, JobStepsData parent) { this.parent = parent; LoadData(source); } + // copy constructor public JobStepData(JobStepData source) { @@ -647,6 +669,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.cachedSource = source; } + /// /// Load all data nessesary to edit a job /// @@ -694,6 +717,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.cachedSource = null; } + /// /// Set defaults for a new empty job /// @@ -725,6 +749,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.proxyName = string.Empty; this.urn = null; } + /// /// Load the completion actions for the step /// @@ -751,6 +776,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent { return ApplyChanges(job, false); } + /// /// Save changes to the job step /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepProperties.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepProperties.cs deleted file mode 100644 index 7e8d952d..00000000 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepProperties.cs +++ /dev/null @@ -1,78 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; -using System.Collections; -using System.Collections.Generic; -using System.ComponentModel; -using System.Globalization; -using Microsoft.SqlServer.Management.Common; -using Microsoft.SqlServer.Management.Sdk.Sfc; -using Microsoft.SqlServer.Management.Smo; -using Microsoft.SqlServer.Management.Smo.Agent; -using Microsoft.SqlServer.Management.Diagnostics; -using Microsoft.SqlTools.ServiceLayer.Admin; -using Microsoft.SqlTools.ServiceLayer.Management; - -namespace Microsoft.SqlTools.ServiceLayer.Agent -{ - /// - /// Summary description for JobStepProperties. - /// - internal class JobStepProperties : ManagementActionBase - { - private JobStepSubSystems subSystems; - private JobStepSubSystem selectedSubSystem = null; - private bool needToUpdate = false; - private const int jobIdLowerBound= 1; - private int currentStepID = jobIdLowerBound; - private int stepsCount = jobIdLowerBound; - private IJobStepPropertiesControl activeControl = null; - private JobStepData data; - // used to persist state between job step types - private JobStepData runtimeData; - - internal JobStepProperties(CDataContainer dataContainer, JobStepData context) - { - this.DataContainer = dataContainer; - this.data = context; - this.runtimeData = new JobStepData(this.data); - currentStepID = this.data.ID; - stepsCount = this.data.StepCount; - } - - /// - /// Clean up any resources being used. - /// - protected override void Dispose(bool disposing) - { - if (disposing) - { - } - base.Dispose(disposing); - } - - private JobStepSubSystems SubSystems - { - get - { - if (this.subSystems == null) - { - this.subSystems = new JobStepSubSystems(this.DataContainer, this.data); - } - return this.subSystems; - } - } - } -} - - - - - - - - - diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepPropertySheet.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepPropertySheet.cs deleted file mode 100644 index 9ac8835f..00000000 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepPropertySheet.cs +++ /dev/null @@ -1,108 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; -using System.Collections; -using System.Globalization; -using Microsoft.SqlServer.Management.Common; -using Microsoft.SqlServer.Management.Sdk.Sfc; -using Microsoft.SqlServer.Management.Smo; -using Microsoft.SqlServer.Management.Smo.Agent; -using Microsoft.SqlTools.ServiceLayer.Admin; -using Microsoft.SqlTools.ServiceLayer.Management; - -namespace Microsoft.SqlTools.ServiceLayer.Agent -{ - /// - /// Summary description for JobStepPropertySheet. - /// - internal class JobStepPropertySheet : ManagementActionBase - { - private JobStepData data = null; - - public JobStepPropertySheet(CDataContainer dataContainer, JobStepData data) - { - this.DataContainer = dataContainer; - this.data = data; - } - - public void Init() - { - JobStepProperties general = new JobStepProperties(this.DataContainer, this.data); - } - - /// - /// Clean up any resources being used. - /// - protected override void Dispose(bool disposing) - { - if(disposing) - { - } - base.Dispose(disposing); - } - - public bool Create() - { - // Make sure the job step name is not blank. - if (string.IsNullOrWhiteSpace(this.data.Name)) - { - throw new Exception("SRError.JobStepNameCannotBeBlank"); - } - - // Check to make sure that the user has not entered a job step name that already exists. - for (int stepIndex = 0; stepIndex < this.data.Parent.Steps.Count; stepIndex++) - { - // don't compare if the id's are the same. - if(data.ID != ((JobStepData)this.data.Parent.Steps[stepIndex]).ID && data.Name == ((JobStepData)this.data.Parent.Steps[stepIndex]).Name) - { - // Throw an error if the job step name already exists - throw new Exception("JobSR.JobStepNameAlreadyExists(this.data.Name)"); - } - } - - this.data.ApplyChanges(this.GetCurrentJob()); - - // regular execution always takes place - return true; - } - - private Job GetCurrentJob() - { - Job job = null; - string urn = string.Empty; - string jobIdString = null; - STParameters parameters = new STParameters(this.DataContainer.Document); - parameters.GetParam("urn", ref urn); - parameters.GetParam("jobid", ref jobIdString); - - // If JobID is passed in look up by jobID - if (!string.IsNullOrEmpty(jobIdString)) - { - job = this.DataContainer.Server.JobServer.Jobs.ItemById(Guid.Parse(jobIdString)); - } - else - { - // or use urn path to query job - job = this.DataContainer.Server.GetSmoObject(urn) as Job; - } - - return job; - } - - /// - /// We don't own the CDataContainer that we get from our creator. We need to - /// return false here so that the base class won't dispose it in its Dispose method - /// - protected override bool OwnDataContainer - { - get - { - return false; - } - } - - } -} diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepSubSystems.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepSubSystems.cs index 9a5f2d16..7e8299ed 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepSubSystems.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepSubSystems.cs @@ -12,7 +12,6 @@ using System.Linq; using Microsoft.SqlServer.Management.Sdk.Sfc; using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo.Agent; -using Microsoft.SqlTools.ServiceLayer.Admin; using Microsoft.SqlTools.ServiceLayer.Management; namespace Microsoft.SqlTools.ServiceLayer.Agent diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepsActions.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepsActions.cs index 16f410b3..cec82622 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepsActions.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepsActions.cs @@ -4,9 +4,7 @@ // using System; -using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo.Agent; -using Microsoft.SqlTools.ServiceLayer.Admin; using Microsoft.SqlTools.ServiceLayer.Agent.Contracts; using Microsoft.SqlTools.ServiceLayer.Management; diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepsData.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepsData.cs index 1ed50205..5d989a98 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepsData.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobStepsData.cs @@ -7,15 +7,9 @@ using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; -using System.Data; -using System.Globalization; using Microsoft.SqlServer.Management.Common; -using Microsoft.SqlServer.Management.Sdk.Sfc; -using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Smo.Agent; -using Microsoft.SqlTools.ServiceLayer.Admin; using Microsoft.SqlTools.ServiceLayer.Management; -using SMO = Microsoft.SqlServer.Management.Smo; namespace Microsoft.SqlTools.ServiceLayer.Agent { @@ -59,6 +53,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent return this.parent; } } + /// /// Server Version /// @@ -69,6 +64,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent return this.parent.Version; } } + /// /// Mode in which the dialog has been launched /// @@ -86,6 +82,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent } } } + /// /// List of steps in this job /// @@ -96,6 +93,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent return this.jobSteps; } } + /// /// The default start step /// @@ -122,6 +120,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.startStep = value; } } + /// /// List of all available databases on the server /// @@ -133,6 +132,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent return this.databases; } } + /// /// Indicates whether or not the order of the steps has changed /// @@ -152,6 +152,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent return orderChanged; } } + /// /// Indicates whether or not the Job is read only /// @@ -188,6 +189,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent } CommonInit(context, parent, script); } + /// /// Create a new jobsteps data object /// @@ -205,6 +207,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent } CommonInit(context, parent, null); } + /// /// Common initialization routines for constructrs /// @@ -246,6 +249,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.jobSteps.Add(step); RecalculateStepIds(); } + /// /// Insert a jobstep into an existing location /// @@ -256,6 +260,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.jobSteps.Insert(index, step); RecalculateStepIds(); } + /// /// Delete a jobstep /// @@ -275,6 +280,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent } RecalculateStepIds(); } + /// /// Get a JobStepData object for a step id /// @@ -365,6 +371,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent } return unreachableSteps; } + /// /// Checks to see if the Last steps success completion action will change. /// It will if we are editing a job, and the last steps Success Completion @@ -404,6 +411,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent } OnStepOrderChanged(EventArgs.Empty); } + /// /// Delayed loading of database information /// @@ -420,6 +428,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.databases[i] = this.context.Server.Databases[i].Name; } } + /// /// fire the StepOrderChanged event /// @@ -430,6 +439,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent this.StepOrderChanged(this, args); } } + /// /// SMO job object we are manipulating /// @@ -463,6 +473,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent jsd.Name = "1"; this.jobSteps.Add(jsd); } + /// /// Load job steps from the server /// @@ -617,10 +628,3 @@ namespace Microsoft.SqlTools.ServiceLayer.Agent #endregion } } - - - - - - - diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobsReferencingScheduleControl.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobsReferencingScheduleControl.cs index 0bff6635..ff79e2c2 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobsReferencingScheduleControl.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobsReferencingScheduleControl.cs @@ -1,3 +1,4 @@ +#if false // // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. @@ -888,3 +889,4 @@ namespace Microsoft.SqlServer.Management.SqlManagerUI #endregion } } +#endif \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobsReferencingScheduleForm.cs b/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobsReferencingScheduleForm.cs deleted file mode 100644 index cf9f81c7..00000000 --- a/src/Microsoft.SqlTools.ServiceLayer/Agent/Jobs/JobsReferencingScheduleForm.cs +++ /dev/null @@ -1,443 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; -using System.Drawing; -using System.Collections; -using System.ComponentModel; -using Microsoft.SqlServer.Management.Smo.Agent; -using Microsoft.SqlTools.ServiceLayer.Admin; -using Microsoft.SqlTools.ServiceLayer.Management; - -namespace Microsoft.SqlServer.Management.SqlManagerUI -{ - /// - /// Summary description for JobsRefrencingScheduleForm. - /// - public class JobsReferencingScheduleForm - { - #region UI Variables - - // private System.Windows.Forms.Panel panelContainer; - // private Microsoft.SqlServer.Management.Controls.Separator separatorContainerFromButtons; - // private System.Windows.Forms.Button buttonHelp; - // private System.Windows.Forms.Button buttonOK; - // private System.Windows.Forms.Button buttonCancel; - - /// - /// Required designer variable. - /// - private System.ComponentModel.Container components = null; - - #endregion - - #region Other Variables - - private JobsReferencingScheduleControl m_innerControl = null; - private IServiceProvider m_serviceProvider = null; - - #endregion - - #region Public - - public int NoOfSelectedJobs - { - get - { - System.Diagnostics.Debug.Assert(m_innerControl != null); - // System.Diagnostics.Debug.Assert(this.DialogResult == DialogResult.OK, - // "property meaningfull only if dialog dismised with OK"); - return m_innerControl.NoOfSelectedJobs; - } - } - - #endregion - - #region Constructors/Dispose - - /// - /// constructor used so WinForms designer can work - /// - public JobsReferencingScheduleForm() - { - } - - /// - /// actual constuctor invoked from 'ManageSchedules' dialog - /// - /// context describing connection used, etc - similar with context in dbCommanders - /// shared schedule id (used to unique identify the shared schedule since duplicate names are possible) - /// shared schedule for which we should display the jobs (used for display purposes) - /// true if we dont allow user to modify data - /// provider used to show help, msg boxes, etc - public JobsReferencingScheduleForm(CDataContainer context, int scheduleId, string scheduleName, - bool readOnlyMode, IServiceProvider svcProvider) - { - m_serviceProvider = svcProvider; - - // InitializeComponent(); - // InitializeInnerUserControl(context, scheduleId, scheduleName, readOnlyMode); - // InitializeButtonEvents(); - } - - /// - /// Clean up any resources being used. - // /// - // protected override void Dispose(bool disposing) - // { - // if (disposing) - // { - // if (components != null) - // { - // components.Dispose(); - // } - // } - // base.Dispose(disposing); - // } - - #endregion - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - // System.Resources.ResourceManager resources = - // new System.Resources.ResourceManager(typeof (JobsReferencingScheduleForm)); - // this.panelContainer = new System.Windows.Forms.Panel(); - // this.separatorContainerFromButtons = new Microsoft.SqlServer.Management.Controls.Separator(); - // this.buttonHelp = new System.Windows.Forms.Button(); - // this.buttonOK = new System.Windows.Forms.Button(); - // this.buttonCancel = new System.Windows.Forms.Button(); - // this.SuspendLayout(); - // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - // this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - // // - // // panelContainer - // // - // this.panelContainer.AccessibleDescription = resources.GetString("panelContainer.AccessibleDescription"); - // this.panelContainer.AccessibleName = resources.GetString("panelContainer.AccessibleName"); - // this.panelContainer.Anchor = - // ((System.Windows.Forms.AnchorStyles) (resources.GetObject("panelContainer.Anchor"))); - // this.panelContainer.AutoScroll = ((bool) (resources.GetObject("panelContainer.AutoScroll"))); - // this.panelContainer.AutoScrollMargin = - // ((System.Drawing.Size) (resources.GetObject("panelContainer.AutoScrollMargin"))); - // this.panelContainer.AutoScrollMinSize = - // ((System.Drawing.Size) (resources.GetObject("panelContainer.AutoScrollMinSize"))); - // this.panelContainer.BackgroundImage = - // ((System.Drawing.Image) (resources.GetObject("panelContainer.BackgroundImage"))); - // this.panelContainer.Dock = ((System.Windows.Forms.DockStyle) (resources.GetObject("panelContainer.Dock"))); - // this.panelContainer.Enabled = ((bool) (resources.GetObject("panelContainer.Enabled"))); - // this.panelContainer.Font = ((System.Drawing.Font) (resources.GetObject("panelContainer.Font"))); - // this.panelContainer.ImeMode = - // ((System.Windows.Forms.ImeMode) (resources.GetObject("panelContainer.ImeMode"))); - // this.panelContainer.Location = ((System.Drawing.Point) (resources.GetObject("panelContainer.Location"))); - // this.panelContainer.Name = "panelContainer"; - // this.panelContainer.RightToLeft = - // ((System.Windows.Forms.RightToLeft) (resources.GetObject("panelContainer.RightToLeft"))); - // this.panelContainer.Size = ((System.Drawing.Size) (resources.GetObject("panelContainer.Size"))); - // this.panelContainer.TabIndex = ((int) (resources.GetObject("panelContainer.TabIndex"))); - // this.panelContainer.Text = resources.GetString("panelContainer.Text"); - // this.panelContainer.Visible = ((bool) (resources.GetObject("panelContainer.Visible"))); - // // - // // separatorContainerFromButtons - // // - // this.separatorContainerFromButtons.AccessibleDescription = - // resources.GetString("separatorContainerFromButtons.AccessibleDescription"); - // this.separatorContainerFromButtons.AccessibleName = - // resources.GetString("separatorContainerFromButtons.AccessibleName"); - // this.separatorContainerFromButtons.Anchor = - // ((System.Windows.Forms.AnchorStyles) (resources.GetObject("separatorContainerFromButtons.Anchor"))); - // this.separatorContainerFromButtons.AutoSize = - // ((bool) (resources.GetObject("separatorContainerFromButtons.AutoSize"))); - // this.separatorContainerFromButtons.Dock = - // ((System.Windows.Forms.DockStyle) (resources.GetObject("separatorContainerFromButtons.Dock"))); - // this.separatorContainerFromButtons.Enabled = - // ((bool) (resources.GetObject("separatorContainerFromButtons.Enabled"))); - // this.separatorContainerFromButtons.Font = - // ((System.Drawing.Font) (resources.GetObject("separatorContainerFromButtons.Font"))); - // this.separatorContainerFromButtons.ImeMode = - // ((System.Windows.Forms.ImeMode) (resources.GetObject("separatorContainerFromButtons.ImeMode"))); - // this.separatorContainerFromButtons.Location = - // ((System.Drawing.Point) (resources.GetObject("separatorContainerFromButtons.Location"))); - // this.separatorContainerFromButtons.Name = "separatorContainerFromButtons"; - // this.separatorContainerFromButtons.RightToLeft = - // ((System.Windows.Forms.RightToLeft) (resources.GetObject("separatorContainerFromButtons.RightToLeft"))); - // this.separatorContainerFromButtons.Size = - // ((System.Drawing.Size) (resources.GetObject("separatorContainerFromButtons.Size"))); - // this.separatorContainerFromButtons.TabIndex = - // ((int) (resources.GetObject("separatorContainerFromButtons.TabIndex"))); - // this.separatorContainerFromButtons.Text = resources.GetString("separatorContainerFromButtons.Text"); - // this.separatorContainerFromButtons.TextAlign = - // ((System.Drawing.ContentAlignment) (resources.GetObject("separatorContainerFromButtons.TextAlign"))); - // this.separatorContainerFromButtons.Visible = - // ((bool) (resources.GetObject("separatorContainerFromButtons.Visible"))); - // // - // // buttonHelp - // // - // this.buttonHelp.AccessibleDescription = resources.GetString("buttonHelp.AccessibleDescription"); - // this.buttonHelp.AccessibleName = resources.GetString("buttonHelp.AccessibleName"); - // this.buttonHelp.Anchor = ((System.Windows.Forms.AnchorStyles) (resources.GetObject("buttonHelp.Anchor"))); - // this.buttonHelp.BackgroundImage = - // ((System.Drawing.Image) (resources.GetObject("buttonHelp.BackgroundImage"))); - // this.buttonHelp.Dock = ((System.Windows.Forms.DockStyle) (resources.GetObject("buttonHelp.Dock"))); - // this.buttonHelp.Enabled = ((bool) (resources.GetObject("buttonHelp.Enabled"))); - // this.buttonHelp.FlatStyle = ((System.Windows.Forms.FlatStyle) (resources.GetObject("buttonHelp.FlatStyle"))); - // this.buttonHelp.Font = ((System.Drawing.Font) (resources.GetObject("buttonHelp.Font"))); - // this.buttonHelp.Image = ((System.Drawing.Image) (resources.GetObject("buttonHelp.Image"))); - // this.buttonHelp.ImageAlign = - // ((System.Drawing.ContentAlignment) (resources.GetObject("buttonHelp.ImageAlign"))); - // this.buttonHelp.ImageIndex = ((int) (resources.GetObject("buttonHelp.ImageIndex"))); - // this.buttonHelp.ImeMode = ((System.Windows.Forms.ImeMode) (resources.GetObject("buttonHelp.ImeMode"))); - // this.buttonHelp.Location = ((System.Drawing.Point) (resources.GetObject("buttonHelp.Location"))); - // this.buttonHelp.Name = "buttonHelp"; - // this.buttonHelp.RightToLeft = - // ((System.Windows.Forms.RightToLeft) (resources.GetObject("buttonHelp.RightToLeft"))); - // this.buttonHelp.Size = ((System.Drawing.Size) (resources.GetObject("buttonHelp.Size"))); - // this.buttonHelp.TabIndex = ((int) (resources.GetObject("buttonHelp.TabIndex"))); - // this.buttonHelp.Text = resources.GetString("buttonHelp.Text"); - // this.buttonHelp.TextAlign = - // ((System.Drawing.ContentAlignment) (resources.GetObject("buttonHelp.TextAlign"))); - // this.buttonHelp.Visible = ((bool) (resources.GetObject("buttonHelp.Visible"))); - // // - // // buttonOK - // // - // this.buttonOK.AccessibleDescription = resources.GetString("buttonOK.AccessibleDescription"); - // this.buttonOK.AccessibleName = resources.GetString("buttonOK.AccessibleName"); - // this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles) (resources.GetObject("buttonOK.Anchor"))); - // this.buttonOK.BackgroundImage = ((System.Drawing.Image) (resources.GetObject("buttonOK.BackgroundImage"))); - // this.buttonOK.Dock = ((System.Windows.Forms.DockStyle) (resources.GetObject("buttonOK.Dock"))); - // this.buttonOK.Enabled = ((bool) (resources.GetObject("buttonOK.Enabled"))); - // this.buttonOK.FlatStyle = ((System.Windows.Forms.FlatStyle) (resources.GetObject("buttonOK.FlatStyle"))); - // this.buttonOK.Font = ((System.Drawing.Font) (resources.GetObject("buttonOK.Font"))); - // this.buttonOK.Image = ((System.Drawing.Image) (resources.GetObject("buttonOK.Image"))); - // this.buttonOK.ImageAlign = ((System.Drawing.ContentAlignment) (resources.GetObject("buttonOK.ImageAlign"))); - // this.buttonOK.ImageIndex = ((int) (resources.GetObject("buttonOK.ImageIndex"))); - // this.buttonOK.ImeMode = ((System.Windows.Forms.ImeMode) (resources.GetObject("buttonOK.ImeMode"))); - // this.buttonOK.Location = ((System.Drawing.Point) (resources.GetObject("buttonOK.Location"))); - // this.buttonOK.Name = "buttonOK"; - // this.buttonOK.RightToLeft = - // ((System.Windows.Forms.RightToLeft) (resources.GetObject("buttonOK.RightToLeft"))); - // this.buttonOK.Size = ((System.Drawing.Size) (resources.GetObject("buttonOK.Size"))); - // this.buttonOK.TabIndex = ((int) (resources.GetObject("buttonOK.TabIndex"))); - // this.buttonOK.Text = resources.GetString("buttonOK.Text"); - // this.buttonOK.TextAlign = ((System.Drawing.ContentAlignment) (resources.GetObject("buttonOK.TextAlign"))); - // this.buttonOK.Visible = ((bool) (resources.GetObject("buttonOK.Visible"))); - // // - // // buttonCancel - // // - // this.buttonCancel.AccessibleDescription = resources.GetString("buttonCancel.AccessibleDescription"); - // this.buttonCancel.AccessibleName = resources.GetString("buttonCancel.AccessibleName"); - // this.buttonCancel.Anchor = - // ((System.Windows.Forms.AnchorStyles) (resources.GetObject("buttonCancel.Anchor"))); - // this.buttonCancel.BackgroundImage = - // ((System.Drawing.Image) (resources.GetObject("buttonCancel.BackgroundImage"))); - // this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - // this.buttonCancel.Dock = ((System.Windows.Forms.DockStyle) (resources.GetObject("buttonCancel.Dock"))); - // this.buttonCancel.Enabled = ((bool) (resources.GetObject("buttonCancel.Enabled"))); - // this.buttonCancel.FlatStyle = - // ((System.Windows.Forms.FlatStyle) (resources.GetObject("buttonCancel.FlatStyle"))); - // this.buttonCancel.Font = ((System.Drawing.Font) (resources.GetObject("buttonCancel.Font"))); - // this.buttonCancel.Image = ((System.Drawing.Image) (resources.GetObject("buttonCancel.Image"))); - // this.buttonCancel.ImageAlign = - // ((System.Drawing.ContentAlignment) (resources.GetObject("buttonCancel.ImageAlign"))); - // this.buttonCancel.ImageIndex = ((int) (resources.GetObject("buttonCancel.ImageIndex"))); - // this.buttonCancel.ImeMode = ((System.Windows.Forms.ImeMode) (resources.GetObject("buttonCancel.ImeMode"))); - // this.buttonCancel.Location = ((System.Drawing.Point) (resources.GetObject("buttonCancel.Location"))); - // this.buttonCancel.Name = "buttonCancel"; - // this.buttonCancel.RightToLeft = - // ((System.Windows.Forms.RightToLeft) (resources.GetObject("buttonCancel.RightToLeft"))); - // this.buttonCancel.Size = ((System.Drawing.Size) (resources.GetObject("buttonCancel.Size"))); - // this.buttonCancel.TabIndex = ((int) (resources.GetObject("buttonCancel.TabIndex"))); - // this.buttonCancel.Text = resources.GetString("buttonCancel.Text"); - // this.buttonCancel.TextAlign = - // ((System.Drawing.ContentAlignment) (resources.GetObject("buttonCancel.TextAlign"))); - // this.buttonCancel.Visible = ((bool) (resources.GetObject("buttonCancel.Visible"))); - // // - // // JobsReferencingScheduleForm - // // - // this.AcceptButton = this.buttonOK; - // this.AccessibleDescription = resources.GetString("$this.AccessibleDescription"); - // this.AccessibleName = resources.GetString("$this.AccessibleName"); - // this.AutoScaleBaseSize = ((System.Drawing.Size) (resources.GetObject("$this.AutoScaleBaseSize"))); - // this.AutoScroll = ((bool) (resources.GetObject("$this.AutoScroll"))); - // this.AutoScrollMargin = ((System.Drawing.Size) (resources.GetObject("$this.AutoScrollMargin"))); - // this.AutoScrollMinSize = ((System.Drawing.Size) (resources.GetObject("$this.AutoScrollMinSize"))); - // this.BackgroundImage = ((System.Drawing.Image) (resources.GetObject("$this.BackgroundImage"))); - // this.CancelButton = this.buttonCancel; - // this.ClientSize = ((System.Drawing.Size) (resources.GetObject("$this.ClientSize"))); - // this.Controls.Add(this.buttonCancel); - // this.Controls.Add(this.buttonOK); - // this.Controls.Add(this.buttonHelp); - // this.Controls.Add(this.separatorContainerFromButtons); - // this.Controls.Add(this.panelContainer); - // this.Enabled = ((bool) (resources.GetObject("$this.Enabled"))); - // this.Font = ((System.Drawing.Font) (resources.GetObject("$this.Font"))); - // this.Icon = ((System.Drawing.Icon) (resources.GetObject("$this.Icon"))); - // this.ImeMode = ((System.Windows.Forms.ImeMode) (resources.GetObject("$this.ImeMode"))); - // this.Location = ((System.Drawing.Point) (resources.GetObject("$this.Location"))); - // this.MaximumSize = ((System.Drawing.Size) (resources.GetObject("$this.MaximumSize"))); - // this.MinimumSize = ((System.Drawing.Size) (resources.GetObject("$this.MinimumSize"))); - // this.Name = "JobsReferencingScheduleForm"; - // this.RightToLeft = ((System.Windows.Forms.RightToLeft) (resources.GetObject("$this.RightToLeft"))); - // this.StartPosition = ((System.Windows.Forms.FormStartPosition) (resources.GetObject("$this.StartPosition"))); - // this.Text = resources.GetString("$this.Text"); - // this.ResumeLayout(false); - - } - - #endregion - - #region Initialize Inner UserControl - - /// - /// used for estitic purposes only - /// - private void InitializeInnerUserControl() - { - // try - // { - // System.Diagnostics.Debug.Assert(m_innerControl == null, "inner control was already initialized"); - - // this.SuspendLayout(); - // this.panelContainer.SuspendLayout(); - - // System.Diagnostics.Debug.Assert(this.Parent != null); - // if (this.Parent != null) - // { - // this.BackColor = Parent.BackColor; - // this.Font = Parent.Font; - // } - - // m_innerControl = new JobsReferencingScheduleControl(); - // m_innerControl.Dock = DockStyle.Fill; - - // this.panelContainer.Controls.Clear(); - // this.panelContainer.Controls.Add(m_innerControl); - // } - // finally - // { - // this.panelContainer.ResumeLayout(); - // this.ResumeLayout(); - // } - } - - /// - /// actual initialization - /// - private void InitializeInnerUserControl(CDataContainer context, int scheduleId, string scheduleName, - bool readOnlyMode) - { - // try - // { - // System.Diagnostics.Debug.Assert(m_innerControl == null, "inner control was already initialized"); - // this.SuspendLayout(); - // this.panelContainer.SuspendLayout(); - - // m_innerControl = new JobsReferencingScheduleControl(context, scheduleId, scheduleName, readOnlyMode); - // m_innerControl.Dock = DockStyle.Fill; - - // this.panelContainer.Controls.Clear(); - // this.panelContainer.Controls.Add(m_innerControl); - // } - // finally - // { - // this.panelContainer.ResumeLayout(); - // this.ResumeLayout(); - // } - } - - #endregion - - #region Overrides - OnHelpRequested - - /// - /// hook with standard help processing - /// - /// - // protected override void OnHelpRequested(HelpEventArgs hevent) - // { - // ShowHelp(); - - // hevent.Handled = true; - // base.OnHelpRequested(hevent); - // } - - #endregion - - #region Private Implementation - ShowHelp - - // private void ShowHelp() - // { - // //F1 request might come in even when Help button is hidden - // if (m_serviceProvider == null) - // { - // return; - // } - - // string key = AssemblyVersionInfo.VersionHelpKeywordPrefix + ".ag.job.jobsreferencingaschedule.f1"; - // // pick schedule bol link - // ILaunchFormHost2 host2 = m_serviceProvider.GetService(typeof (ILaunchFormHost2)) as ILaunchFormHost2; - // System.Diagnostics.Debug.Assert(host2 != null, - // "Service Provider could not provide us the ILaunchFormHost2 service required for displaying books online"); - - // if (host2 == null) - // { - // return; - // } - - // host2.ShowHelp(key); - // } - - #endregion - - #region Buttons Initialize / Events - - /// - /// normaly this shouold be handled by WinForms designer - /// but currently Rascal and Everett designers are unusuable so hooking them manually - /// - // private void InitializeButtonEvents() - // { - // this.buttonOK.Click += new EventHandler(this.OnButtonOKClick); - // this.buttonCancel.Click += new EventHandler(this.OnButtonCancelClick); - // this.buttonHelp.Click += new EventHandler(this.OnButtonHelpClick); - - // if (m_serviceProvider == null) - // { - // this.buttonHelp.Visible = false; - // } - // } - - // private void OnButtonOKClick(object source, EventArgs args) - // { - // System.Diagnostics.Debug.Assert(m_innerControl != null); - - // m_innerControl.ApplyChanges(); - - // this.DialogResult = m_innerControl.NoOfSelectedJobs != -1 - // ? DialogResult.OK - // : DialogResult.None; - // this.Close(); - // } - - // private void OnButtonCancelClick(object source, EventArgs args) - // { - // this.DialogResult = DialogResult.Cancel; - // this.Close(); - // } - - // private void OnButtonHelpClick(object source, EventArgs args) - // { - // ShowHelp(); - // } - - #endregion - - } -} diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs index c128241a..22562b48 100755 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs @@ -4341,6 +4341,38 @@ namespace Microsoft.SqlTools.ServiceLayer } } + public static string UnexpectedRunType + { + get + { + return Keys.GetString(Keys.UnexpectedRunType); + } + } + + public static string CredentialNoLongerExists + { + get + { + return Keys.GetString(Keys.CredentialNoLongerExists); + } + } + + public static string TargetServerNotSelected + { + get + { + return Keys.GetString(Keys.TargetServerNotSelected); + } + } + + public static string SysadminAccount + { + get + { + return Keys.GetString(Keys.SysadminAccount); + } + } + public static string JobStepNameCannotBeBlank { get @@ -4656,6 +4688,26 @@ namespace Microsoft.SqlTools.ServiceLayer return Keys.GetString(Keys.OperatorProperties, operatorName); } + public static string UnknownSizeUnit(string unit) + { + return Keys.GetString(Keys.UnknownSizeUnit, unit); + } + + public static string UnknownServerType(string serverTypeName) + { + return Keys.GetString(Keys.UnknownServerType, serverTypeName); + } + + public static string SetOwnerFailed(string ownerName) + { + return Keys.GetString(Keys.SetOwnerFailed, ownerName); + } + + public static string ProxyAccountNotFound(string proxyName) + { + return Keys.GetString(Keys.ProxyAccountNotFound, proxyName); + } + public static string JobAlreadyExists(string jobName) { return Keys.GetString(Keys.JobAlreadyExists, jobName); @@ -6437,6 +6489,30 @@ namespace Microsoft.SqlTools.ServiceLayer public const string CategoryDataCollector = "CategoryDataCollector"; + public const string UnknownSizeUnit = "UnknownSizeUnit"; + + + public const string UnexpectedRunType = "UnexpectedRunType"; + + + public const string CredentialNoLongerExists = "CredentialNoLongerExists"; + + + public const string UnknownServerType = "UnknownServerType"; + + + public const string SetOwnerFailed = "SetOwnerFailed"; + + + public const string TargetServerNotSelected = "TargetServerNotSelected"; + + + public const string ProxyAccountNotFound = "ProxyAccountNotFound"; + + + public const string SysadminAccount = "SysadminAccount"; + + public const string JobAlreadyExists = "JobAlreadyExists"; diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx index 99bf277d..2e2fe638 100755 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx @@ -2508,6 +2508,42 @@ Data Collector + + Unknown size unit {0} + . + Parameters: 0 - unit (string) + + + Unexpected run type. + + + + The object does no longer exist on server. + + + + Unknown server type '{0}'. + . + Parameters: 0 - serverTypeName (string) + + + The current login does not have permissions to set the database owner to '{0}' The database was created successfully however. + . + Parameters: 0 - ownerName (string) + + + You must specify the Target Servers on which this multi server job will execute. + + + + Proxy account '{0}' does not exist on the server. + . + Parameters: 0 - proxyName (string) + + + SQL Server Agent Service Account + + A job named '{0}' already exists. Enter a unique name for the job. . diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings index c46dc8ec..b446650c 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings @@ -1052,6 +1052,14 @@ CategoryLogShipping = Log Shipping CategoryDBEngineTuningAdvisor = Database Engine Tuning Advisor CategoryDataCollector = Data Collector +UnknownSizeUnit(unit) = Unknown size unit {0} +UnexpectedRunType = Unexpected run type. +CredentialNoLongerExists = The object does no longer exist on server. +UnknownServerType(string serverTypeName) = Unknown server type '{0}'. +SetOwnerFailed(string ownerName) = The current login does not have permissions to set the database owner to '{0}' The database was created successfully however. +TargetServerNotSelected = You must specify the Target Servers on which this multi server job will execute. +ProxyAccountNotFound(string proxyName) = Proxy account '{0}' does not exist on the server. +SysadminAccount = SQL Server Agent Service Account JobAlreadyExists(string jobName) = A job named '{0}' already exists. Enter a unique name for the job. JobStepNameCannotBeBlank = The name of the job step cannot be blank. JobStepNameAlreadyExists(string jobName) = There is already a step named '{0}' for this job. You must specify a different name. diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf index 4c0f2dea..a51ae56e 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf @@ -3046,6 +3046,50 @@ . Parameters: 0 - scheduleName (string) + + SQL Server Agent Service Account + SQL Server Agent Service Account + + + + Proxy account '{0}' does not exist on the server. + Proxy account '{0}' does not exist on the server. + . + Parameters: 0 - proxyName (string) + + + The object does no longer exist on server. + The object does no longer exist on server. + + + + Unknown server type '{0}'. + Unknown server type '{0}'. + . + Parameters: 0 - serverTypeName (string) + + + The current login does not have permissions to set the database owner to '{0}' The database was created successfully however. + The current login does not have permissions to set the database owner to '{0}' The database was created successfully however. + . + Parameters: 0 - ownerName (string) + + + You must specify the Target Servers on which this multi server job will execute. + You must specify the Target Servers on which this multi server job will execute. + + + + Unexpected run type. + Unexpected run type. + + + + Unknown size unit {0} + Unknown size unit {0} + . + Parameters: 0 - unit (string) + \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/Management/Common/DataContainer.cs b/src/Microsoft.SqlTools.ServiceLayer/Management/Common/DataContainer.cs index 34b4df4b..a7a6ce28 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Management/Common/DataContainer.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Management/Common/DataContainer.cs @@ -669,7 +669,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Management } else { - throw new ArgumentException("SRError.UnknownServerType(serverType.ToString()), serverType"); + throw new ArgumentException(SR.UnknownServerType(serverType.ToString())); } } @@ -697,7 +697,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Management } else { - throw new ArgumentException("SRError.UnknownServerType(serverType.ToString()), serverType"); + throw new ArgumentException(SR.UnknownServerType(serverType.ToString())); } if (xmlParameters != null) diff --git a/src/Microsoft.SqlTools.ServiceLayer/Management/Common/DbSize.cs b/src/Microsoft.SqlTools.ServiceLayer/Management/Common/DbSize.cs index 38fd3f2d..64d62538 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Management/Common/DbSize.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Management/Common/DbSize.cs @@ -85,7 +85,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Management case SizeUnits.TB: return sizeBase*1024.0*1024.0*1024.0*1024.0; } - throw new InvalidOperationException("SR.UnknownSizeUnit(SizeUnit.ToString())"); + throw new InvalidOperationException(SR.UnknownSizeUnit(SizeUnit.ToString())); } } #region Object Overrides diff --git a/src/Microsoft.SqlTools.ServiceLayer/Management/Common/ExecutionHandler.cs b/src/Microsoft.SqlTools.ServiceLayer/Management/Common/ExecutionHandler.cs index e7689e3a..670c12fb 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Management/Common/ExecutionHandler.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Management/Common/ExecutionHandler.cs @@ -76,7 +76,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Management break; default: - throw new InvalidOperationException("SRError.UnexpectedRunType"); + throw new InvalidOperationException(SR.UnexpectedRunType); } if((this.managementAction.LastExecutionResult == ExecutionMode.Failure) || diff --git a/src/Microsoft.SqlTools.ServiceLayer/Security/Contracts/CredentialInfo.cs b/src/Microsoft.SqlTools.ServiceLayer/Security/Contracts/CredentialInfo.cs index 2fbd29d4..b08bfcf3 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Security/Contracts/CredentialInfo.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Security/Contracts/CredentialInfo.cs @@ -14,8 +14,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Security.Contracts /// public class CredentialInfo { - public string Identity { get; set; } public int Id { get; } + public string Identity { get; set; } + public string Name { get; set; } public DateTime DateLastModified { get; } public DateTime CreateDate { get; } public string ProviderName { get; set; } diff --git a/src/Microsoft.SqlTools.ServiceLayer/Security/Contracts/CredentialRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/Security/Contracts/CredentialRequest.cs index 78bda946..16808ade 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Security/Contracts/CredentialRequest.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Security/Contracts/CredentialRequest.cs @@ -22,12 +22,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Security.Contracts /// /// Create Credential result /// - public class CreateCredentialResult + public class CredentialResult : ResultStatus { - - public bool Succeeded { get; set; } - - public string ErrorMessage { get; set; } + public CredentialInfo Credential { get; set; } + } /// @@ -39,41 +37,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Security.Contracts /// Request definition /// public static readonly - RequestType Type = - RequestType.Create("security/createcredential"); - } - - /// - /// Delete Credential params - /// - public class DeleteCredentialParams : GeneralRequestDetails - { - public string OwnerUri { get; set; } - - public CredentialInfo Credential { get; set; } - } - - /// - /// Delete Credential result - /// - public class DeleteCredentialResult - { - public bool Succeeded { get; set; } - - public string ErrorMessage { get; set; } - } - - /// - /// Delete Credential request type - /// - public class DeleteCredentialRequest - { - /// - /// Request definition - /// - public static readonly - RequestType Type = - RequestType.Create("security/deletecredential"); + RequestType Type = + RequestType.Create("security/createcredential"); } /// @@ -86,16 +51,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Security.Contracts public CredentialInfo Credential { get; set; } } - /// - /// Update Credential result - /// - public class UpdateCredentialResult - { - public bool Succeeded { get; set; } - - public string ErrorMessage { get; set; } - } - /// /// Update Credential request type /// @@ -105,7 +60,30 @@ namespace Microsoft.SqlTools.ServiceLayer.Security.Contracts /// Request definition /// public static readonly - RequestType Type = - RequestType.Create("security/updatecredential"); - } + RequestType Type = + RequestType.Create("security/updatecredential"); + } + + /// + /// Delete Credential params + /// + public class DeleteCredentialParams : GeneralRequestDetails + { + public string OwnerUri { get; set; } + + public CredentialInfo Credential { get; set; } + } + + /// + /// Delete Credential request type + /// + public class DeleteCredentialRequest + { + /// + /// Request definition + /// + public static readonly + RequestType Type = + RequestType.Create("security/deletecredential"); + } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/Security/Credential.cs b/src/Microsoft.SqlTools.ServiceLayer/Security/Credential.cs deleted file mode 100644 index 4d742b43..00000000 --- a/src/Microsoft.SqlTools.ServiceLayer/Security/Credential.cs +++ /dev/null @@ -1,98 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using System; -using System.Collections; -using System.ComponentModel; -using System.Data; -using System.Data.SqlClient; -using System.Xml; -using Microsoft.SqlServer.Management.Common; -using Microsoft.SqlServer.Management.Sdk.Sfc; -using Microsoft.SqlServer.Management.Smo; -using Microsoft.SqlServer.Management.Diagnostics; -using Microsoft.SqlTools.ServiceLayer.Management; -using Microsoft.SqlTools.ServiceLayer.Admin; - -namespace Microsoft.SqlTools.ServiceLayer.Security -{ - internal class Credential : ManagementActionBase - { - -#region Constants - private const int MAX_SQL_SYS_NAME_LENGTH = 128; // max sql sys name length -#endregion - -#region Variables - private CredentialData credentialData = null; -#endregion - -#region Constructors / Dispose - /// - /// required when loading from Object Explorer context - /// - /// - public Credential(CDataContainer context) - { - this.DataContainer = context; - this.credentialData = new CredentialData(context); - this.credentialData.Initialize(); - } - - /// - /// Clean up any resources being used. - /// - protected override void Dispose( bool disposing ) - { - base.Dispose( disposing ); - if (disposing == true) - { - if (this.credentialData != null) - { - this.credentialData.Dispose(); - } - } - } -#endregion - - /// - /// called on background thread by the framework to execute the action - /// - /// - public override void OnRunNow(object sender) - { - this.credentialData.SendDataToServer(); - - } - - /// - /// update logic layer based on content of user interface - /// - private void UpdateLogicLayer() - { - - this.credentialData.CredentialName = "this.textBoxCredentialName.Text"; - this.credentialData.CredentialIdentity = "this.textBoxIdentity.Text"; - - - this.credentialData.SecurePassword = CDataContainer.BuildSecureStringFromPassword("password"); - this.credentialData.SecurePasswordConfirm = CDataContainer.BuildSecureStringFromPassword("password"); - - if (this.ServerConnection.ServerVersion.Major >= 10) - { - // need to update only during create time - this.credentialData.IsEncryptionByProvider = true; //this.checkBoxUseProvider.Checked; - if (this.credentialData.IsEncryptionByProvider) - { - this.credentialData.ProviderName = "this.comboBoxProviderName.SelectedItem.ToString()"; - } - else - { - this.credentialData.ProviderName = string.Empty; - } - } - } - } -} diff --git a/src/Microsoft.SqlTools.ServiceLayer/Security/CredentialActions.cs b/src/Microsoft.SqlTools.ServiceLayer/Security/CredentialActions.cs new file mode 100644 index 00000000..f89b6d2f --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/Security/CredentialActions.cs @@ -0,0 +1,78 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; +using Microsoft.SqlTools.ServiceLayer.Management; +using Microsoft.SqlTools.ServiceLayer.Security.Contracts; + +namespace Microsoft.SqlTools.ServiceLayer.Security +{ + internal class CredentialActions : ManagementActionBase + { + +#region Constants + private const int MAX_SQL_SYS_NAME_LENGTH = 128; // max sql sys name length +#endregion + +#region Variables + private CredentialData credentialData = null; + private CredentialInfo credential; + private ConfigAction configAction; +#endregion + +#region Constructors / Dispose + /// + /// required when loading from Object Explorer context + /// + /// + public CredentialActions( + CDataContainer context, + CredentialInfo credential, + ConfigAction configAction) + { + this.DataContainer = context; + this.credential = credential; + this.configAction = configAction; + + this.credentialData = new CredentialData(context, credential); + this.credentialData.Initialize(); + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + base.Dispose( disposing ); + if (disposing == true) + { + if (this.credentialData != null) + { + this.credentialData.Dispose(); + } + } + } +#endregion + + /// + /// called on background thread by the framework to execute the action + /// + /// + public override void OnRunNow(object sender) + { + if (this.configAction == ConfigAction.Drop) + { + if (this.credentialData.Credential != null) + { + this.credentialData.Credential.DropIfExists(); + } + } + else + { + this.credentialData.SendDataToServer(); + } + } + } +} diff --git a/src/Microsoft.SqlTools.ServiceLayer/Security/CredentialData.cs b/src/Microsoft.SqlTools.ServiceLayer/Security/CredentialData.cs index 8ba31b96..350f0955 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Security/CredentialData.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Security/CredentialData.cs @@ -1,4 +1,3 @@ - // // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. @@ -13,38 +12,30 @@ using Microsoft.SqlServer.Management.Common; using Microsoft.SqlServer.Management.Diagnostics; using Microsoft.SqlServer.Management.Sdk.Sfc; using Microsoft.SqlServer.Management.Smo; -using Microsoft.SqlTools.ServiceLayer.Admin; using Microsoft.SqlTools.ServiceLayer.Management; +using Microsoft.SqlTools.ServiceLayer.Security.Contracts; namespace Microsoft.SqlTools.ServiceLayer.Security { - internal class CredentialException : Exception - { - public CredentialException(string message) - : base(message) - { - } - } - - internal class CredentialData : IDisposable - { - #region Properties - private string credentialName = string.Empty; - public string CredentialName + internal class CredentialData : IDisposable + { + #region Properties + private string credentialName = string.Empty; + public string CredentialName { get { return credentialName; } set { credentialName = value; } } - private string credentialIdentity = string.Empty; - public string CredentialIdentity + private string credentialIdentity = string.Empty; + public string CredentialIdentity { get { return credentialIdentity; } set { credentialIdentity = value; } } - private SecureString securePassword; - public SecureString SecurePassword + private SecureString securePassword; + public SecureString SecurePassword { get { return securePassword; } set @@ -54,28 +45,17 @@ namespace Microsoft.SqlTools.ServiceLayer.Security } } - private SecureString securePasswordConfirm; - public SecureString SecurePasswordConfirm - { - get { return securePasswordConfirm; } - set - { - securePasswordConfirm = value; - PasswordWasChanged = true; - } + private bool isPropertiesMode = false; + public bool IsPropertiesMode + { + get + { + return isPropertiesMode; + } } - private bool isPropertiesMode = false; - public bool IsPropertiesMode - { - get - { - return isPropertiesMode; - } - } - - private bool passwordWasChanged = false; - public bool PasswordWasChanged + private bool passwordWasChanged = false; + public bool PasswordWasChanged { get { return passwordWasChanged; } set { passwordWasChanged = value; } @@ -94,52 +74,81 @@ namespace Microsoft.SqlTools.ServiceLayer.Security get { return providerName; } set { providerName = value; } } - #endregion - private const string ENUMERATOR_FIELD_IDENTITY = "Identity"; + public Microsoft.SqlServer.Management.Smo.Credential Credential + { + get + { + return !string.IsNullOrWhiteSpace(this.CredentialName) + ? this.Context.Server.Credentials[this.CredentialName] + : null; + } + } + #endregion + + private const string ENUMERATOR_FIELD_IDENTITY = "Identity"; private const string ENUMERATOR_FIELD_PROVIDER_NAME = "ProviderName"; - #region Constructor - private CDataContainer context = null; - private CDataContainer Context { get { return context; } set { context = value; } } - public CredentialData(CDataContainer ctxt) - { - this.Context = ctxt; - LoadDataFromXmlContext(); - } - #endregion + #region Constructor + private CDataContainer context = null; + private CDataContainer Context { get { return context; } set { context = value; } } + private CredentialInfo credential; - #region Implementation: LoadDataFromXmlContext(), LoadDataFromServer(), SendDataToServer() + public CredentialData(CDataContainer context, CredentialInfo credential) + { + this.Context = context; + this.credential = credential; + LoadDataFromXmlContext(); + } + #endregion - public void Initialize() - { - LoadDataFromXmlContext(); - LoadDataFromServer(); - } + #region Implementation: LoadDataFromXmlContext(), LoadDataFromServer(), SendDataToServer() - /// - /// LoadDataFromXmlContext - /// - /// loads context information from xml - e.g. name of object - /// - private void LoadDataFromXmlContext() - { - this.CredentialName = this.Context.GetDocumentPropertyString("credential"); - this.isPropertiesMode = (this.CredentialName != null) && (this.CredentialName.Length > 0); - } + public void Initialize() + { + LoadDataFromXmlContext(); + LoadDataFromServer(); - /// - /// LoadDataFromServer - /// - /// talks with enumerator an retrieves info that is not available in the xml context but on server - /// - private void LoadDataFromServer() - { - if (this.IsPropertiesMode == true) - { + // apply CredentialInfo properties + this.CredentialIdentity = this.credential.Identity; + this.CredentialName = this.credential.Name; + this.SecurePassword = CDataContainer.BuildSecureStringFromPassword(string.Empty); + + // need to update only during create time + this.IsEncryptionByProvider = false; + if (this.IsEncryptionByProvider) + { + this.ProviderName = string.Empty; // lookup provider here + } + else + { + this.ProviderName = string.Empty; + } + } + + /// + /// LoadDataFromXmlContext + /// + /// loads context information from xml - e.g. name of object + /// + private void LoadDataFromXmlContext() + { + this.CredentialName = this.Context.GetDocumentPropertyString("credential"); + this.isPropertiesMode = (this.CredentialName != null) && (this.CredentialName.Length > 0); + } + + /// + /// LoadDataFromServer + /// + /// talks with enumerator an retrieves info that is not available in the xml context but on server + /// + private void LoadDataFromServer() + { + if (this.IsPropertiesMode == true) + { bool isKatmaiAndNotMatrix = (this.context.Server.Version.Major >= 10); - Urn urn = new Urn("Server/Credential[@Name='" + Urn.EscapeString(this.CredentialName) + "']"); + Urn urn = new Urn("Server/Credential[@Name='" + Urn.EscapeString(this.CredentialName) + "']"); string [] fields; if (isKatmaiAndNotMatrix) { @@ -149,109 +158,105 @@ namespace Microsoft.SqlTools.ServiceLayer.Security { fields = new string[] { ENUMERATOR_FIELD_IDENTITY }; } - Request r = new Request(urn, fields); - System.Data.DataTable dataTable = Enumerator.GetData(this.Context.ConnectionInfo, r); + Request r = new Request(urn, fields); + System.Data.DataTable dataTable = Enumerator.GetData(this.Context.ConnectionInfo, r); - if (dataTable.Rows.Count == 0) - { - throw new Exception("SRError.CredentialNoLongerExists"); - } + if (dataTable.Rows.Count == 0) + { + throw new Exception(SR.CredentialNoLongerExists); + } - System.Data.DataRow dataRow = dataTable.Rows[0]; - this.CredentialIdentity = Convert.ToString(dataRow[ENUMERATOR_FIELD_IDENTITY], System.Globalization.CultureInfo.InvariantCulture); + System.Data.DataRow dataRow = dataTable.Rows[0]; + this.CredentialIdentity = Convert.ToString(dataRow[ENUMERATOR_FIELD_IDENTITY], System.Globalization.CultureInfo.InvariantCulture); if (isKatmaiAndNotMatrix) { this.providerName = Convert.ToString(dataRow[ENUMERATOR_FIELD_PROVIDER_NAME], System.Globalization.CultureInfo.InvariantCulture); this.isEncryptionByProvider = !string.IsNullOrEmpty(providerName); } - } - else - { - this.CredentialName = string.Empty; - this.CredentialIdentity = string.Empty; + } + else + { + this.CredentialName = string.Empty; + this.CredentialIdentity = string.Empty; this.providerName = string.Empty; this.isEncryptionByProvider = false; - } + } - this.SecurePassword = new SecureString(); - this.SecurePasswordConfirm = new SecureString(); + this.SecurePassword = new SecureString(); + this.PasswordWasChanged = false; + } - this.PasswordWasChanged = false; - } + /// + /// SendDataToServer + /// + /// here we talk with server via smo and do the actual data changing + /// + public void SendDataToServer() + { + if (this.IsPropertiesMode == true) + { + SendToServerAlterCredential(); + } + else + { + SendToServerCreateCredential(); + } + } - - /// - /// SendDataToServer - /// - /// here we talk with server via smo and do the actual data changing - /// - public void SendDataToServer() - { - if (this.IsPropertiesMode == true) - { - SendToServerAlterCredential(); - } - else - { - SendToServerCreateCredential(); - } - } - - /// - /// create credential - create mode - /// - private void SendToServerCreateCredential() - { - Microsoft.SqlServer.Management.Smo.Credential smoCredential = new Microsoft.SqlServer.Management.Smo.Credential ( - this.Context.Server, - this.CredentialName); + /// + /// create credential - create mode + /// + private void SendToServerCreateCredential() + { + Microsoft.SqlServer.Management.Smo.Credential smoCredential = new Microsoft.SqlServer.Management.Smo.Credential ( + this.Context.Server, + this.CredentialName); if (this.isEncryptionByProvider) { smoCredential.MappedClassType = MappedClassType.CryptographicProvider; smoCredential.ProviderName = this.providerName; } - smoCredential.Create(this.CredentialIdentity, this.SecurePassword.ToString()); - GC.Collect(); // this.SecurePassword.ToString() just created an immutable string that lives in memory - } + smoCredential.Create(this.CredentialIdentity, this.SecurePassword.ToString()); + GC.Collect(); // this.SecurePassword.ToString() just created an immutable string that lives in memory + } - /// - /// alter credential - properties mode - /// - private void SendToServerAlterCredential() - { - Microsoft.SqlServer.Management.Smo.Credential smoCredential = this.Context.Server.Credentials[this.CredentialName]; + /// + /// alter credential - properties mode + /// + private void SendToServerAlterCredential() + { + Microsoft.SqlServer.Management.Smo.Credential smoCredential = this.Context.Server.Credentials[this.CredentialName]; - if (smoCredential != null) - { - if (this.PasswordWasChanged == false) - { - if (smoCredential.Identity != this.CredentialIdentity) - { - smoCredential.Alter(this.CredentialIdentity); - } - } - else - { - smoCredential.Alter(this.CredentialIdentity, this.SecurePassword.ToString()); - GC.Collect(); // this.SecurePassword.ToString() just created an immutable string that lives in memory - } - } - else - { - throw new Exception("SRError.CredentialNoLongerExists"); - } - } - #endregion + if (smoCredential != null) + { + if (this.PasswordWasChanged == false) + { + if (smoCredential.Identity != this.CredentialIdentity) + { + smoCredential.Alter(this.CredentialIdentity); + } + } + else + { + smoCredential.Alter(this.CredentialIdentity, this.SecurePassword.ToString()); + GC.Collect(); // this.SecurePassword.ToString() just created an immutable string that lives in memory + } + } + else + { + throw new Exception(SR.CredentialNoLongerExists); + } + } + #endregion - #region IDisposable Members + #region IDisposable Members - public void Dispose() - { - this.SecurePassword.Dispose(); - this.SecurePasswordConfirm.Dispose(); - } + public void Dispose() + { + this.SecurePassword.Dispose(); + } - #endregion - } + #endregion + } } diff --git a/src/Microsoft.SqlTools.ServiceLayer/Security/SecurityService.cs b/src/Microsoft.SqlTools.ServiceLayer/Security/SecurityService.cs index 632a4e0f..6bd55631 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Security/SecurityService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Security/SecurityService.cs @@ -11,6 +11,7 @@ using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.Hosting; using Microsoft.SqlTools.ServiceLayer.Management; using Microsoft.SqlTools.ServiceLayer.Security.Contracts; +using Microsoft.SqlTools.ServiceLayer.Utility; namespace Microsoft.SqlTools.ServiceLayer.Security { @@ -86,43 +87,54 @@ namespace Microsoft.SqlTools.ServiceLayer.Security /// /// Handle request to create a credential /// - internal async Task HandleCreateCredentialRequest(CreateCredentialParams parameters, RequestContext requestContext) - { - try - { - var result = new CreateCredentialResult(); - ConnectionInfo connInfo; - ConnectionServiceInstance.TryFindConnection( - parameters.OwnerUri, - out connInfo); + internal async Task HandleCreateCredentialRequest(CreateCredentialParams parameters, RequestContext requestContext) + { + var result = await ConfigureCredential(parameters.OwnerUri, + parameters.Credential, + ConfigAction.Create, + RunType.RunNow); - CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true); - Credential credential = new Credential(dataContainer); - - await requestContext.SendResult(result); - } - catch (Exception e) + await requestContext.SendResult(new CredentialResult() { - await requestContext.SendError(e); - } + Credential = parameters.Credential, + Success = result.Item1, + ErrorMessage = result.Item2 + }); } /// /// Handle request to update a credential /// - internal async Task HandleUpdateCredentialRequest(UpdateCredentialParams parameters, RequestContext requestContext) - { - var result = new UpdateCredentialResult(); - await requestContext.SendResult(result); + internal async Task HandleUpdateCredentialRequest(UpdateCredentialParams parameters, RequestContext requestContext) + { + var result = await ConfigureCredential(parameters.OwnerUri, + parameters.Credential, + ConfigAction.Update, + RunType.RunNow); + + await requestContext.SendResult(new CredentialResult() + { + Credential = parameters.Credential, + Success = result.Item1, + ErrorMessage = result.Item2 + }); } /// /// Handle request to delete a credential /// - internal async Task HandleDeleteCredentialRequest(DeleteCredentialParams parameters, RequestContext requestContext) + internal async Task HandleDeleteCredentialRequest(DeleteCredentialParams parameters, RequestContext requestContext) { - var result = new DeleteCredentialResult(); - await requestContext.SendResult(result); + var result = await ConfigureCredential(parameters.OwnerUri, + parameters.Credential, + ConfigAction.Drop, + RunType.RunNow); + + await requestContext.SendResult(new ResultStatus() + { + Success = result.Item1, + ErrorMessage = result.Item2 + }); } /// @@ -135,5 +147,38 @@ namespace Microsoft.SqlTools.ServiceLayer.Security disposed = true; } } + +#region "Helpers" + + internal async Task> ConfigureCredential( + string ownerUri, + CredentialInfo credential, + ConfigAction configAction, + RunType runType) + { + return await Task>.Run(() => + { + try + { + ConnectionInfo connInfo; + ConnectionServiceInstance.TryFindConnection(ownerUri, out connInfo); + CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true); + + using (CredentialActions actions = new CredentialActions(dataContainer, credential, configAction)) + { + var executionHandler = new ExecutonHandler(actions); + executionHandler.RunNow(runType, this); + } + + return new Tuple(true, string.Empty); + } + catch (Exception ex) + { + return new Tuple(false, ex.ToString()); + } + }); + } + +#endregion // "Helpers" } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Agent/AgentProxyTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Agent/AgentProxyTests.cs index 5c29601b..aac2dc54 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Agent/AgentProxyTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Agent/AgentProxyTests.cs @@ -7,74 +7,89 @@ using System.Threading.Tasks; using Microsoft.SqlTools.Hosting.Protocol; using Microsoft.SqlTools.ServiceLayer.Agent; using Microsoft.SqlTools.ServiceLayer.Agent.Contracts; +using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security; using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility; +using Microsoft.SqlTools.ServiceLayer.Security; +using Microsoft.SqlTools.ServiceLayer.Security.Contracts; using Microsoft.SqlTools.ServiceLayer.Test.Common; using Microsoft.SqlTools.ServiceLayer.Utility; using Moq; using Xunit; +using static Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility.LiveConnectionHelper; namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Agent { public class AgentProxyTests { + /// + /// TestHandleCreateAgentProxyRequest + /// + [Fact] + public async Task TestHandleCreateAgentProxyRequest() + { + using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) + { + // setup + var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath); + var credential = await SecurityTestUtils.SetupCredential(connectionResult); + var service = new AgentService(); + var proxy = AgentTestUtils.GetTestProxyInfo(); + await AgentTestUtils.DeleteAgentProxy(service, connectionResult, proxy); + + // test + await AgentTestUtils.CreateAgentProxy(service, connectionResult, proxy); + + // cleanup + await AgentTestUtils.DeleteAgentProxy(service, connectionResult, proxy); + await SecurityTestUtils.CleanupCredential(connectionResult, credential); + } + } + /// /// Verify the default "update agent alert" request handler with valid parameters /// - //[Fact] + [Fact] public async Task TestHandleUpdateAgentProxyRequest() { using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) { - var createContext = new Mock>(); - var updateContext = new Mock>(); - var deleteContext = new Mock>(); - - var service = new AgentService(); - var proxy = new AgentProxyInfo() - { - Id = 10, - AccountName = "Test Proxy 2", - CredentialName = "User", - Description = "", - IsEnabled = true - }; - + // cleanup var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath); - await service.HandleDeleteAgentProxyRequest(new DeleteAgentProxyParams() - { - OwnerUri = connectionResult.ConnectionInfo.OwnerUri, - Proxy = proxy - }, deleteContext.Object); - - deleteContext.VerifyAll(); - - await service.HandleCreateAgentProxyRequest(new CreateAgentProxyParams - { - OwnerUri = connectionResult.ConnectionInfo.OwnerUri, - Proxy = proxy - }, createContext.Object); - - createContext.VerifyAll(); + var credential = await SecurityTestUtils.SetupCredential(connectionResult); + var service = new AgentService(); + var proxy = AgentTestUtils.GetTestProxyInfo(); + await AgentTestUtils.DeleteAgentProxy(service, connectionResult, proxy); + await AgentTestUtils.CreateAgentProxy(service, connectionResult, proxy); + // test string originalProxyName = proxy.AccountName; proxy.AccountName = proxy.AccountName + " Updated"; - await service.HandleUpdateAgentProxyRequest(new UpdateAgentProxyParams() - { - OwnerUri = connectionResult.ConnectionInfo.OwnerUri, - OriginalProxyName = originalProxyName, - Proxy = proxy - }, updateContext.Object); + await AgentTestUtils.UpdateAgentProxy(service, connectionResult, originalProxyName, proxy); - updateContext.VerifyAll(); - - await service.HandleDeleteAgentProxyRequest(new DeleteAgentProxyParams() - { - OwnerUri = connectionResult.ConnectionInfo.OwnerUri, - Proxy = proxy - }, deleteContext.Object); - - deleteContext.VerifyAll(); + // cleanup + await AgentTestUtils.DeleteAgentProxy(service, connectionResult, proxy); + await SecurityTestUtils.CleanupCredential(connectionResult, credential); } - } + } + + /// + /// TestHandleDeleteAgentProxyRequest + /// + [Fact] + public async Task TestHandleDeleteAgentProxyRequest() + { + using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) + { + // cleanup + var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath); + var credential = await SecurityTestUtils.SetupCredential(connectionResult); + var service = new AgentService(); + var proxy = AgentTestUtils.GetTestProxyInfo(); + + // test + await AgentTestUtils.DeleteAgentProxy(service, connectionResult, proxy); + await SecurityTestUtils.CleanupCredential(connectionResult, credential); + } + } } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Agent/AgentTestUtils.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Agent/AgentTestUtils.cs index f897187f..a1c796f3 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Agent/AgentTestUtils.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Agent/AgentTestUtils.cs @@ -9,6 +9,7 @@ using Microsoft.SqlTools.Hosting.Protocol; using Microsoft.SqlTools.ServiceLayer.Agent; using Microsoft.SqlTools.ServiceLayer.Agent.Contracts; using Microsoft.SqlTools.ServiceLayer.Connection; +using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security; using Microsoft.SqlTools.ServiceLayer.Utility; using Moq; using static Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility.LiveConnectionHelper; @@ -67,6 +68,17 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Agent Name = "Joe DBA", EmailAddress = "test@aol.com" }; + } + + internal static AgentProxyInfo GetTestProxyInfo() + { + return new AgentProxyInfo() + { + AccountName = "Test Proxy", + CredentialName = SecurityTestUtils.TestCredentialName, + Description = "Test proxy description", + IsEnabled = true + }; } internal static async Task CreateAgentJob( @@ -185,7 +197,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Agent Operator = operatorInfo }, context.Object); context.VerifyAll(); - } + } internal static async Task DeleteAgentOperator( AgentService service, @@ -199,7 +211,51 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Agent Operator = operatorInfo }, context.Object); context.VerifyAll(); - } + } + + internal static async Task CreateAgentProxy( + AgentService service, + TestConnectionResult connectionResult, + AgentProxyInfo proxy) + { + var context = new Mock>(); + await service.HandleCreateAgentProxyRequest(new CreateAgentProxyParams + { + OwnerUri = connectionResult.ConnectionInfo.OwnerUri, + Proxy = proxy + }, context.Object); + context.VerifyAll(); + } + + internal static async Task UpdateAgentProxy( + AgentService service, + TestConnectionResult connectionResult, + string originalProxyName, + AgentProxyInfo proxy) + { + var context = new Mock>(); + await service.HandleUpdateAgentProxyRequest(new UpdateAgentProxyParams() + { + OwnerUri = connectionResult.ConnectionInfo.OwnerUri, + OriginalProxyName = originalProxyName, + Proxy = proxy + }, context.Object); + context.VerifyAll(); + } + + internal static async Task DeleteAgentProxy( + AgentService service, + TestConnectionResult connectionResult, + AgentProxyInfo proxy) + { + var context = new Mock>(); + await service.HandleDeleteAgentProxyRequest(new DeleteAgentProxyParams() + { + OwnerUri = connectionResult.ConnectionInfo.OwnerUri, + Proxy = proxy + }, context.Object); + context.VerifyAll(); + } internal static async Task GetAgentAlerts(string connectionUri) { diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/CredentialTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/CredentialTests.cs new file mode 100644 index 00000000..cba15f65 --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/CredentialTests.cs @@ -0,0 +1,92 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.SqlTools.Hosting.Protocol; +using Microsoft.SqlTools.ServiceLayer.Connection; +using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility; +using Microsoft.SqlTools.ServiceLayer.Security; +using Microsoft.SqlTools.ServiceLayer.Security.Contracts; +using Microsoft.SqlTools.ServiceLayer.Test.Common; +using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; +using Moq; +using Xunit; +using static Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility.LiveConnectionHelper; + +namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security +{ + /// + /// Tests for the Credential management component + /// + public class CredentialTests + { + /// + /// TestHandleCreateCredentialRequest + /// + [Fact] + public async Task TestHandleCreateCredentialRequest() + { + using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) + { + // setup + var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath); + var service = new SecurityService(); + var credential = SecurityTestUtils.GetTestCredentialInfo(); + await SecurityTestUtils.DeleteCredential(service, connectionResult, credential); + + // test + await SecurityTestUtils.CreateCredential(service, connectionResult, credential); + + // cleanup + await SecurityTestUtils.DeleteCredential(service, connectionResult, credential); + } + } + + /// + /// TestHandleUpdateCredentialRequest + /// + [Fact] + public async Task TestHandleUpdateCredentialRequest() + { + using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) + { + // setup + var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath); + var service = new SecurityService(); + var credential = SecurityTestUtils.GetTestCredentialInfo(); + await SecurityTestUtils.DeleteCredential(service, connectionResult, credential); + await SecurityTestUtils.CreateCredential(service, connectionResult, credential); + + // test + await SecurityTestUtils.UpdateCredential(service, connectionResult, credential); + + // cleanup + await SecurityTestUtils.DeleteCredential(service, connectionResult, credential); + } + } + + /// + /// TestHandleDeleteCredentialRequest + /// + [Fact] + public async Task TestHandleDeleteCredentialRequest() + { + using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) + { + // setup + var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath); + var service = new SecurityService(); + var credential = SecurityTestUtils.GetTestCredentialInfo(); + await SecurityTestUtils.DeleteCredential(service, connectionResult, credential); + await SecurityTestUtils.CreateCredential(service, connectionResult, credential); + + // test + await SecurityTestUtils.DeleteCredential(service, connectionResult, credential); + } + } + } +} diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/SecurityServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/SecurityServiceTests.cs deleted file mode 100644 index 500f575b..00000000 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/SecurityServiceTests.cs +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// - -using Microsoft.SqlTools.Hosting.Protocol; -using Microsoft.SqlTools.ServiceLayer.Connection; -using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility; -using Microsoft.SqlTools.ServiceLayer.Security; -using Microsoft.SqlTools.ServiceLayer.Security.Contracts; -using Microsoft.SqlTools.ServiceLayer.Test.Common; -using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts; -using Moq; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Xunit; -using static Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility.LiveConnectionHelper; - -namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security -{ - /// - /// Tests for the security service component - /// - public class SecuritygServiceTests - { - /// - /// Verify the script object request - /// - [Fact] - public async Task TestHandleCreateCredentialRequest() - { - using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile()) - { - var createContext = new Mock>(); - var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath); - - var service = new SecurityService(); - var credential = new CredentialInfo() - { - }; - - await service.HandleCreateCredentialRequest(new CreateCredentialParams - { - OwnerUri = connectionResult.ConnectionInfo.OwnerUri, - Credential = credential - }, createContext.Object); - - createContext.VerifyAll(); - } - } - } -} diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/SecurityTestUtils.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/SecurityTestUtils.cs new file mode 100644 index 00000000..09731041 --- /dev/null +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/SecurityTestUtils.cs @@ -0,0 +1,95 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; +using System.Threading.Tasks; +using Microsoft.SqlTools.Hosting.Protocol; +using Microsoft.SqlTools.ServiceLayer.Connection; +using Microsoft.SqlTools.ServiceLayer.Security; +using Microsoft.SqlTools.ServiceLayer.Security.Contracts; +using Microsoft.SqlTools.ServiceLayer.Utility; +using Moq; +using static Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility.LiveConnectionHelper; + +namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security +{ + public static class SecurityTestUtils + { + public static string TestCredentialName = "Current User"; + + internal static string GetCurrentUserIdentity() + { + return string.Format(@"{0}\{1}", Environment.UserDomainName, Environment.UserName); + } + + internal static CredentialInfo GetTestCredentialInfo() + { + return new CredentialInfo() + { + Identity = GetCurrentUserIdentity(), + Name = TestCredentialName + }; + } + + internal static async Task CreateCredential( + SecurityService service, + TestConnectionResult connectionResult, + CredentialInfo credential) + { + var context = new Mock>(); + await service.HandleCreateCredentialRequest(new CreateCredentialParams + { + OwnerUri = connectionResult.ConnectionInfo.OwnerUri, + Credential = credential + }, context.Object); + context.VerifyAll(); + } + + internal static async Task UpdateCredential( + SecurityService service, + TestConnectionResult connectionResult, + CredentialInfo credential) + { + var context = new Mock>(); + await service.HandleUpdateCredentialRequest(new UpdateCredentialParams + { + OwnerUri = connectionResult.ConnectionInfo.OwnerUri, + Credential = credential + }, context.Object); + context.VerifyAll(); + } + + internal static async Task DeleteCredential( + SecurityService service, + TestConnectionResult connectionResult, + CredentialInfo credential) + { + var context = new Mock>(); + await service.HandleDeleteCredentialRequest(new DeleteCredentialParams + { + OwnerUri = connectionResult.ConnectionInfo.OwnerUri, + Credential = credential + }, context.Object); + context.VerifyAll(); + } + + public static async Task SetupCredential(TestConnectionResult connectionResult) + { + var service = new SecurityService(); + var credential = SecurityTestUtils.GetTestCredentialInfo(); + await SecurityTestUtils.DeleteCredential(service, connectionResult, credential); + await SecurityTestUtils.CreateCredential(service, connectionResult, credential); + return credential; + } + + public static async Task CleanupCredential( + TestConnectionResult connectionResult, + CredentialInfo credential) + { + var service = new SecurityService(); + await SecurityTestUtils.DeleteCredential(service, connectionResult, credential); + } + } +}