mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-18 17:23:52 -05:00
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
This commit is contained in:
@@ -14,8 +14,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Security.Contracts
|
||||
/// </summary>
|
||||
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; }
|
||||
|
||||
@@ -22,12 +22,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Security.Contracts
|
||||
/// <summary>
|
||||
/// Create Credential result
|
||||
/// </summary>
|
||||
public class CreateCredentialResult
|
||||
public class CredentialResult : ResultStatus
|
||||
{
|
||||
|
||||
public bool Succeeded { get; set; }
|
||||
|
||||
public string ErrorMessage { get; set; }
|
||||
public CredentialInfo Credential { get; set; }
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -39,41 +37,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Security.Contracts
|
||||
/// Request definition
|
||||
/// </summary>
|
||||
public static readonly
|
||||
RequestType<CreateCredentialParams, CreateCredentialResult> Type =
|
||||
RequestType<CreateCredentialParams, CreateCredentialResult>.Create("security/createcredential");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete Credential params
|
||||
/// </summary>
|
||||
public class DeleteCredentialParams : GeneralRequestDetails
|
||||
{
|
||||
public string OwnerUri { get; set; }
|
||||
|
||||
public CredentialInfo Credential { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete Credential result
|
||||
/// </summary>
|
||||
public class DeleteCredentialResult
|
||||
{
|
||||
public bool Succeeded { get; set; }
|
||||
|
||||
public string ErrorMessage { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete Credential request type
|
||||
/// </summary>
|
||||
public class DeleteCredentialRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Request definition
|
||||
/// </summary>
|
||||
public static readonly
|
||||
RequestType<DeleteCredentialParams, DeleteCredentialResult> Type =
|
||||
RequestType<DeleteCredentialParams, DeleteCredentialResult>.Create("security/deletecredential");
|
||||
RequestType<CreateCredentialParams, CredentialResult> Type =
|
||||
RequestType<CreateCredentialParams, CredentialResult>.Create("security/createcredential");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -86,16 +51,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Security.Contracts
|
||||
public CredentialInfo Credential { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update Credential result
|
||||
/// </summary>
|
||||
public class UpdateCredentialResult
|
||||
{
|
||||
public bool Succeeded { get; set; }
|
||||
|
||||
public string ErrorMessage { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update Credential request type
|
||||
/// </summary>
|
||||
@@ -105,7 +60,30 @@ namespace Microsoft.SqlTools.ServiceLayer.Security.Contracts
|
||||
/// Request definition
|
||||
/// </summary>
|
||||
public static readonly
|
||||
RequestType<UpdateCredentialParams, UpdateCredentialResult> Type =
|
||||
RequestType<UpdateCredentialParams, UpdateCredentialResult>.Create("security/updatecredential");
|
||||
}
|
||||
RequestType<UpdateCredentialParams, CredentialResult> Type =
|
||||
RequestType<UpdateCredentialParams, CredentialResult>.Create("security/updatecredential");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete Credential params
|
||||
/// </summary>
|
||||
public class DeleteCredentialParams : GeneralRequestDetails
|
||||
{
|
||||
public string OwnerUri { get; set; }
|
||||
|
||||
public CredentialInfo Credential { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete Credential request type
|
||||
/// </summary>
|
||||
public class DeleteCredentialRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Request definition
|
||||
/// </summary>
|
||||
public static readonly
|
||||
RequestType<DeleteCredentialParams, ResultStatus> Type =
|
||||
RequestType<DeleteCredentialParams, ResultStatus>.Create("security/deletecredential");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
/// <summary>
|
||||
/// required when loading from Object Explorer context
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public Credential(CDataContainer context)
|
||||
{
|
||||
this.DataContainer = context;
|
||||
this.credentialData = new CredentialData(context);
|
||||
this.credentialData.Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
protected override void Dispose( bool disposing )
|
||||
{
|
||||
base.Dispose( disposing );
|
||||
if (disposing == true)
|
||||
{
|
||||
if (this.credentialData != null)
|
||||
{
|
||||
this.credentialData.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// called on background thread by the framework to execute the action
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
public override void OnRunNow(object sender)
|
||||
{
|
||||
this.credentialData.SendDataToServer();
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// update logic layer based on content of user interface
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
/// <summary>
|
||||
/// required when loading from Object Explorer context
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
protected override void Dispose( bool disposing )
|
||||
{
|
||||
base.Dispose( disposing );
|
||||
if (disposing == true)
|
||||
{
|
||||
if (this.credentialData != null)
|
||||
{
|
||||
this.credentialData.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// called on background thread by the framework to execute the action
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
public override void OnRunNow(object sender)
|
||||
{
|
||||
if (this.configAction == ConfigAction.Drop)
|
||||
{
|
||||
if (this.credentialData.Credential != null)
|
||||
{
|
||||
this.credentialData.Credential.DropIfExists();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.credentialData.SendDataToServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
/// <summary>
|
||||
/// LoadDataFromXmlContext
|
||||
///
|
||||
/// loads context information from xml - e.g. name of object
|
||||
/// </summary>
|
||||
private void LoadDataFromXmlContext()
|
||||
{
|
||||
this.CredentialName = this.Context.GetDocumentPropertyString("credential");
|
||||
this.isPropertiesMode = (this.CredentialName != null) && (this.CredentialName.Length > 0);
|
||||
}
|
||||
public void Initialize()
|
||||
{
|
||||
LoadDataFromXmlContext();
|
||||
LoadDataFromServer();
|
||||
|
||||
/// <summary>
|
||||
/// LoadDataFromServer
|
||||
///
|
||||
/// talks with enumerator an retrieves info that is not available in the xml context but on server
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// LoadDataFromXmlContext
|
||||
///
|
||||
/// loads context information from xml - e.g. name of object
|
||||
/// </summary>
|
||||
private void LoadDataFromXmlContext()
|
||||
{
|
||||
this.CredentialName = this.Context.GetDocumentPropertyString("credential");
|
||||
this.isPropertiesMode = (this.CredentialName != null) && (this.CredentialName.Length > 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// LoadDataFromServer
|
||||
///
|
||||
/// talks with enumerator an retrieves info that is not available in the xml context but on server
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
/// <summary>
|
||||
/// SendDataToServer
|
||||
///
|
||||
/// here we talk with server via smo and do the actual data changing
|
||||
/// </summary>
|
||||
public void SendDataToServer()
|
||||
{
|
||||
if (this.IsPropertiesMode == true)
|
||||
{
|
||||
SendToServerAlterCredential();
|
||||
}
|
||||
else
|
||||
{
|
||||
SendToServerCreateCredential();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// SendDataToServer
|
||||
///
|
||||
/// here we talk with server via smo and do the actual data changing
|
||||
/// </summary>
|
||||
public void SendDataToServer()
|
||||
{
|
||||
if (this.IsPropertiesMode == true)
|
||||
{
|
||||
SendToServerAlterCredential();
|
||||
}
|
||||
else
|
||||
{
|
||||
SendToServerCreateCredential();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// create credential - create mode
|
||||
/// </summary>
|
||||
private void SendToServerCreateCredential()
|
||||
{
|
||||
Microsoft.SqlServer.Management.Smo.Credential smoCredential = new Microsoft.SqlServer.Management.Smo.Credential (
|
||||
this.Context.Server,
|
||||
this.CredentialName);
|
||||
/// <summary>
|
||||
/// create credential - create mode
|
||||
/// </summary>
|
||||
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
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// alter credential - properties mode
|
||||
/// </summary>
|
||||
private void SendToServerAlterCredential()
|
||||
{
|
||||
Microsoft.SqlServer.Management.Smo.Credential smoCredential = this.Context.Server.Credentials[this.CredentialName];
|
||||
/// <summary>
|
||||
/// alter credential - properties mode
|
||||
/// </summary>
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
/// <summary>
|
||||
/// Handle request to create a credential
|
||||
/// </summary>
|
||||
internal async Task HandleCreateCredentialRequest(CreateCredentialParams parameters, RequestContext<CreateCredentialResult> requestContext)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = new CreateCredentialResult();
|
||||
ConnectionInfo connInfo;
|
||||
ConnectionServiceInstance.TryFindConnection(
|
||||
parameters.OwnerUri,
|
||||
out connInfo);
|
||||
internal async Task HandleCreateCredentialRequest(CreateCredentialParams parameters, RequestContext<CredentialResult> 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
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle request to update a credential
|
||||
/// </summary>
|
||||
internal async Task HandleUpdateCredentialRequest(UpdateCredentialParams parameters, RequestContext<UpdateCredentialResult> requestContext)
|
||||
{
|
||||
var result = new UpdateCredentialResult();
|
||||
await requestContext.SendResult(result);
|
||||
internal async Task HandleUpdateCredentialRequest(UpdateCredentialParams parameters, RequestContext<CredentialResult> 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
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle request to delete a credential
|
||||
/// </summary>
|
||||
internal async Task HandleDeleteCredentialRequest(DeleteCredentialParams parameters, RequestContext<DeleteCredentialResult> requestContext)
|
||||
internal async Task HandleDeleteCredentialRequest(DeleteCredentialParams parameters, RequestContext<ResultStatus> 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
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -135,5 +147,38 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
#region "Helpers"
|
||||
|
||||
internal async Task<Tuple<bool, string>> ConfigureCredential(
|
||||
string ownerUri,
|
||||
CredentialInfo credential,
|
||||
ConfigAction configAction,
|
||||
RunType runType)
|
||||
{
|
||||
return await Task<Tuple<bool, string>>.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<bool, string>(true, string.Empty);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new Tuple<bool, string>(false, ex.ToString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#endregion // "Helpers"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user