mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-19 01:25:40 -05:00
Port code for Application Role, Database Role, Permission Data and Securable search (#1992)
* port code for db role and app role * port permissionData (wip) * port securable search data
This commit is contained in:
1191
src/Microsoft.SqlTools.ServiceLayer/Security/AppRoleGeneral.cs
Normal file
1191
src/Microsoft.SqlTools.ServiceLayer/Security/AppRoleGeneral.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,925 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
#nullable disable
|
||||
|
||||
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Xml;
|
||||
using System.Data;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlTools.ServiceLayer.Management;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
|
||||
{
|
||||
/// <summary>
|
||||
/// DatabaseRoleGeneral - main panel for database role
|
||||
/// </summary>
|
||||
internal class DatabaseRoleGeneral
|
||||
{
|
||||
#region Members
|
||||
|
||||
private IServiceProvider serviceProvider = null;
|
||||
|
||||
/// <summary>
|
||||
/// data container member that contains data specific information like
|
||||
/// connection infor, SMO server object or an AMO server object as well
|
||||
/// as a hash table where one can manipulate custom data
|
||||
/// </summary>
|
||||
private CDataContainer dataContainer = null;
|
||||
|
||||
//SMO Server connection that MUST be used for all enumerator calls
|
||||
//We'll get this object out of CDataContainer, that must be initialized
|
||||
//property by the initialization code
|
||||
private ServerConnection serverConnection;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// execution mode by default for now is success
|
||||
/// </summary>
|
||||
private ExecutionMode m_executionMode = ExecutionMode.Success;
|
||||
|
||||
/// <summary>
|
||||
/// should UI be enabled?
|
||||
/// </summary>
|
||||
private bool executeEnabled = true;
|
||||
|
||||
/// <summary>
|
||||
/// should script buttons be enabled?
|
||||
/// </summary>
|
||||
private bool scriptEnabled = true;
|
||||
|
||||
/// <summary>
|
||||
/// F1 keyword to be passed to books on-line
|
||||
/// </summary>
|
||||
private string helpF1Keyword = null;
|
||||
private RunType runType;
|
||||
|
||||
//if derived class tries to call a protected method that relies on service provider,
|
||||
//and the service provider hasn't been set yet, we will cache the values and will
|
||||
//propagate them when we get the provider set
|
||||
private System.Drawing.Icon cachedIcon = null;
|
||||
private string cachedCaption = null;
|
||||
|
||||
//whether or not try to auto resize grid columns inside OnLoad method
|
||||
private bool attemtGridAutoResize = true;
|
||||
#endregion
|
||||
|
||||
#region Trace support
|
||||
private const string componentName = "DatabaseRoleGeneral";
|
||||
|
||||
public string ComponentName
|
||||
{
|
||||
get
|
||||
{
|
||||
return componentName;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private class SchemaOwnership
|
||||
{
|
||||
public bool initiallyOwned;
|
||||
public bool currentlyOwned;
|
||||
|
||||
public SchemaOwnership(bool initiallyOwned)
|
||||
{
|
||||
this.initiallyOwned = initiallyOwned;
|
||||
this.currentlyOwned = initiallyOwned;
|
||||
}
|
||||
}
|
||||
|
||||
private class RoleMembership
|
||||
{
|
||||
public bool initiallyAMember;
|
||||
public bool currentlyAMember;
|
||||
|
||||
public RoleMembership(bool initiallyAMember)
|
||||
{
|
||||
this.initiallyAMember = initiallyAMember;
|
||||
this.currentlyAMember = initiallyAMember;
|
||||
}
|
||||
|
||||
public RoleMembership(bool initiallyAMember, bool currentlyAMember)
|
||||
{
|
||||
this.initiallyAMember = initiallyAMember;
|
||||
this.currentlyAMember = currentlyAMember;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region Constants - urn fields, etc...
|
||||
private const string ownerField = "Owner";
|
||||
private const string schemaOwnerField = "Owner";
|
||||
private const string schemaNameField = "Name";
|
||||
private const string memberNameField = "Name";
|
||||
private const string memberUrnField = "Urn";
|
||||
#endregion
|
||||
|
||||
#region Constants - grid columns positions, etc...
|
||||
private const int colSchemasChecked = 0;
|
||||
private const int colSchemasOwnedSchemas = 1;
|
||||
|
||||
private const int colMembershipBitmap = 0;
|
||||
private const int colMembershipRoleMembers = 1;
|
||||
|
||||
private const int sizeCheckboxColumn = 20;
|
||||
private const int sizeBitmapColumn = 20;
|
||||
#endregion
|
||||
|
||||
#region Non-UI variables
|
||||
|
||||
private System.Xml.XmlDocument document = null;
|
||||
private bool panelInitialized = false;
|
||||
|
||||
// info extracted from context
|
||||
private string serverName;
|
||||
private string databaseName;
|
||||
private string dbroleName;
|
||||
private string dbroleUrn;
|
||||
|
||||
// initial values loaded from server
|
||||
private string initialOwner;
|
||||
|
||||
private string ownerName = String.Empty;
|
||||
private string roleName = String.Empty;
|
||||
private HybridDictionary schemaOwnership = null;
|
||||
private HybridDictionary roleMembers = null;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties: CreateNew/Properties mode
|
||||
private bool IsPropertiesMode
|
||||
{
|
||||
get
|
||||
{
|
||||
return(dbroleName!=null) && (dbroleName.Trim().Length != 0);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructors / Dispose
|
||||
public DatabaseRoleGeneral()
|
||||
{
|
||||
// This call is required by the Windows.Forms Form Designer.
|
||||
// InitializeComponent();
|
||||
}
|
||||
|
||||
public DatabaseRoleGeneral(CDataContainer context)
|
||||
{
|
||||
// InitializeComponent();
|
||||
dataContainer = context;
|
||||
|
||||
if (dataContainer != null)
|
||||
{
|
||||
document = dataContainer.Document;
|
||||
}
|
||||
else
|
||||
{
|
||||
document = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation: LoadData(), InitProp(), SendDataToServer()
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// LoadData
|
||||
///
|
||||
/// loads connection parameters from an xml
|
||||
/// </summary>
|
||||
/// <param name="doc"></param>
|
||||
private void LoadData(XmlDocument doc)
|
||||
{
|
||||
// STrace.Params(ComponentName, "LoadData", "XmlDocument doc=\"{0}\"", doc.OuterXml);
|
||||
|
||||
STParameters param;
|
||||
bool bStatus;
|
||||
|
||||
param = new STParameters();
|
||||
|
||||
param.SetDocument(doc);
|
||||
|
||||
bStatus = param.GetParam("servername", ref this.serverName);
|
||||
bStatus = param.GetParam("database", ref this.databaseName);
|
||||
|
||||
bStatus = param.GetParam("role", ref this.dbroleName);
|
||||
bStatus = param.GetParam("urn", ref this.dbroleUrn);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// InitProp
|
||||
///
|
||||
/// talks with enumerator an retrievives info
|
||||
/// </summary>
|
||||
private void InitProp()
|
||||
{
|
||||
// STrace.Params(ComponentName, "InitProp", "", null);
|
||||
|
||||
System.Diagnostics.Debug.Assert(this.serverName!=null);
|
||||
System.Diagnostics.Debug.Assert((this.databaseName!=null) && (this.databaseName.Trim().Length!=0));
|
||||
|
||||
|
||||
// InitializeSchemasGridColumns();
|
||||
if (this.dataContainer.Server.Information.Version.Major >= 9)
|
||||
{
|
||||
LoadSchemas();
|
||||
// FillSchemasGrid();
|
||||
}
|
||||
else
|
||||
{
|
||||
// panelSchema.Enabled = false;
|
||||
}
|
||||
|
||||
LoadMembership();
|
||||
// InitializeMembershipGridColumns();
|
||||
// FillMembershipGrid();
|
||||
|
||||
if (this.IsPropertiesMode == true)
|
||||
{
|
||||
// initialize from enumerator in properties mode
|
||||
System.Diagnostics.Debug.Assert(this.dbroleName!=null);
|
||||
System.Diagnostics.Debug.Assert(this.dbroleName.Trim().Length !=0);
|
||||
System.Diagnostics.Debug.Assert(this.dbroleUrn!=null);
|
||||
System.Diagnostics.Debug.Assert(this.dbroleUrn.Trim().Length != 0);
|
||||
|
||||
// this.textBoxDbRoleName.Text = this.dbroleName;
|
||||
|
||||
Enumerator en = new Enumerator();
|
||||
Request req = new Request();
|
||||
req.Fields = new String [] {DatabaseRoleGeneral.ownerField};
|
||||
|
||||
if ((this.dbroleUrn!=null) && (this.dbroleUrn.Trim().Length != 0))
|
||||
{
|
||||
req.Urn = this.dbroleUrn;
|
||||
}
|
||||
else
|
||||
{
|
||||
req.Urn = "Server/Database[@Name='" + Urn.EscapeString(this.databaseName) + "']/Role[@Name='" + Urn.EscapeString(this.dbroleName) + "]";
|
||||
}
|
||||
|
||||
DataTable dt = en.Process(serverConnection,req);
|
||||
System.Diagnostics.Debug.Assert(dt!=null);
|
||||
System.Diagnostics.Debug.Assert(dt.Rows.Count==1);
|
||||
|
||||
if (dt.Rows.Count==0)
|
||||
{
|
||||
throw new Exception("DatabaseRoleSR.ErrorDbRoleNotFound");
|
||||
}
|
||||
|
||||
DataRow dr = dt.Rows[0];
|
||||
this.initialOwner = Convert.ToString(dr[DatabaseRoleGeneral.ownerField],System.Globalization.CultureInfo.InvariantCulture);
|
||||
// this.textBoxOwner.Text = this.initialOwner;
|
||||
}
|
||||
else
|
||||
{
|
||||
// initialize with empty values in create new mode
|
||||
// this.textBoxDbRoleName.Text = String.Empty;
|
||||
// this.textBoxOwner.Text = String.Empty;
|
||||
}
|
||||
|
||||
// update UI enable/disable controls
|
||||
// EnableDisableControls();
|
||||
}
|
||||
|
||||
|
||||
// public override void OnGatherUiInformation(RunType runType)
|
||||
// {
|
||||
// base.OnGatherUiInformation(runType);
|
||||
|
||||
// this.ownerName = this.textBoxOwner.Text;
|
||||
// this.roleName = this.textBoxDbRoleName.Text;
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// SendDataToServer
|
||||
///
|
||||
/// here we talk with server via smo and do the actual data changing
|
||||
/// </summary>
|
||||
private void SendDataToServer()
|
||||
{
|
||||
// STrace.Params(ComponentName, "SendDataToServer", "", null);
|
||||
|
||||
// STrace.Assert(this.databaseName != null && this.databaseName.Trim().Length != 0, "database name is empty");
|
||||
// STrace.Assert(this.DataContainer.Server != null, "server is null");
|
||||
|
||||
Database database = this.dataContainer.Server.Databases[this.databaseName];
|
||||
// STrace.Assert(database!= null, "database is null");
|
||||
|
||||
DatabaseRole role = null;
|
||||
|
||||
if (this.IsPropertiesMode == true) // in properties mode -> alter role
|
||||
{
|
||||
// STrace.Assert(this.dbroleName != null && this.dbroleName.Trim().Length != 0, "role name is empty");
|
||||
|
||||
role = database.Roles[this.dbroleName];
|
||||
// STrace.Assert(role != null, "role is null");
|
||||
|
||||
if (0 != String.Compare(this.ownerName, this.initialOwner, StringComparison.Ordinal))
|
||||
{
|
||||
role.Owner = this.ownerName;
|
||||
role.Alter();
|
||||
}
|
||||
}
|
||||
else // not in properties mode -> create role
|
||||
{
|
||||
role = new DatabaseRole(database, this.roleName);
|
||||
if (this.ownerName.Length != 0)
|
||||
{
|
||||
role.Owner = this.ownerName;
|
||||
}
|
||||
|
||||
role.Create();
|
||||
}
|
||||
|
||||
SendToServerSchemaOwnershipChanges(database, role);
|
||||
SendToServerMembershipChanges(database, role);
|
||||
|
||||
this.dataContainer.ObjectName = role.Name;
|
||||
this.dataContainer.SqlDialogSubject = role; // needed by extended properties page
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// #region Update UI enable/disable controls
|
||||
// private void EnableDisableControls()
|
||||
// {
|
||||
// if (this.DataContainer.Server.Information.Version.Major<9)
|
||||
// {
|
||||
// panelSchema.Enabled = false;
|
||||
// }
|
||||
|
||||
// if (this.IsPropertiesMode == true)
|
||||
// {
|
||||
// this.textBoxDbRoleName.Enabled = false;
|
||||
|
||||
// this.AllUIEnabled = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// this.textBoxDbRoleName.Enabled = true;
|
||||
|
||||
// this.AllUIEnabled = (this.textBoxDbRoleName.Text.Trim().Length!=0);
|
||||
// }
|
||||
|
||||
// buttonRemove.Enabled = (gridRoleMembership.SelectedRow>=0);
|
||||
// }
|
||||
// #endregion
|
||||
|
||||
// #region ISupportValidation Members
|
||||
|
||||
// bool ISupportValidation.Validate()
|
||||
// {
|
||||
// if (IsPropertiesMode == false)
|
||||
// {
|
||||
// if (this.textBoxDbRoleName.Text.Trim().Length==0)
|
||||
// {
|
||||
// System.Exception e = new System.Exception(DatabaseRoleSR.Error_SpecifyAName);
|
||||
// this.DisplayExceptionMessage(e);
|
||||
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region Component Designer generated code
|
||||
// /// <summary>
|
||||
// /// Required method for Designer support - do not modify
|
||||
// /// the contents of this method with the code editor.
|
||||
// /// </summary>
|
||||
// private void InitializeComponent()
|
||||
// {
|
||||
// System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DatabaseRoleGeneral));
|
||||
// this.panelEntireUserControl = new System.Windows.Forms.Panel();
|
||||
// this.panelSchema = new System.Windows.Forms.Panel();
|
||||
// this.gridSchemasOwned = new Microsoft.SqlServer.Management.SqlManagerUI.SqlManagerUIDlgGrid();
|
||||
// this.labelSchemasOwnedByDbRole = new System.Windows.Forms.Label();
|
||||
// this.panelMembership = new System.Windows.Forms.Panel();
|
||||
// this.buttonRemove = new System.Windows.Forms.Button();
|
||||
// this.buttonAdd = new System.Windows.Forms.Button();
|
||||
// this.gridRoleMembership = new Microsoft.SqlServer.Management.SqlManagerUI.SqlManagerUIDlgGrid();
|
||||
// this.labelMembersOfDbRole = new System.Windows.Forms.Label();
|
||||
// this.panelDbRoleGeneralInfo = new System.Windows.Forms.Panel();
|
||||
// this.buttonSearchOwner = new System.Windows.Forms.Button();
|
||||
// this.textBoxOwner = new System.Windows.Forms.TextBox();
|
||||
// this.labelDbRoleOwner = new System.Windows.Forms.Label();
|
||||
// this.textBoxDbRoleName = new System.Windows.Forms.TextBox();
|
||||
// this.labelDbRoleName = new System.Windows.Forms.Label();
|
||||
// this.panelEntireUserControl.SuspendLayout();
|
||||
// this.panelSchema.SuspendLayout();
|
||||
// ((System.ComponentModel.ISupportInitialize)(this.gridSchemasOwned)).BeginInit();
|
||||
// this.panelMembership.SuspendLayout();
|
||||
// ((System.ComponentModel.ISupportInitialize)(this.gridRoleMembership)).BeginInit();
|
||||
// this.panelDbRoleGeneralInfo.SuspendLayout();
|
||||
// this.SuspendLayout();
|
||||
// this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
// this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
// //
|
||||
// // panelEntireUserControl
|
||||
// //
|
||||
// this.panelEntireUserControl.Controls.Add(this.panelSchema);
|
||||
// this.panelEntireUserControl.Controls.Add(this.panelMembership);
|
||||
// this.panelEntireUserControl.Controls.Add(this.panelDbRoleGeneralInfo);
|
||||
// resources.ApplyResources(this.panelEntireUserControl, "panelEntireUserControl");
|
||||
// this.panelEntireUserControl.Name = "panelEntireUserControl";
|
||||
// //
|
||||
// // panelSchema
|
||||
// //
|
||||
// resources.ApplyResources(this.panelSchema, "panelSchema");
|
||||
// this.panelSchema.Controls.Add(this.gridSchemasOwned);
|
||||
// this.panelSchema.Controls.Add(this.labelSchemasOwnedByDbRole);
|
||||
// this.panelSchema.Name = "panelSchema";
|
||||
// //
|
||||
// // gridSchemasOwned
|
||||
// //
|
||||
// resources.ApplyResources(this.gridSchemasOwned, "gridSchemasOwned");
|
||||
// this.gridSchemasOwned.BackColor = System.Drawing.SystemColors.Window;
|
||||
// this.gridSchemasOwned.ForceEnabled = false;
|
||||
// this.gridSchemasOwned.Name = "gridSchemasOwned";
|
||||
// this.gridSchemasOwned.MouseButtonClicked += new Microsoft.SqlServer.Management.UI.Grid.MouseButtonClickedEventHandler(this.gridSchemasOwned_MouseButtonClicked);
|
||||
// //
|
||||
// // labelSchemasOwnedByDbRole
|
||||
// //
|
||||
// resources.ApplyResources(this.labelSchemasOwnedByDbRole, "labelSchemasOwnedByDbRole");
|
||||
// this.labelSchemasOwnedByDbRole.Name = "labelSchemasOwnedByDbRole";
|
||||
// //
|
||||
// // panelMembership
|
||||
// //
|
||||
// resources.ApplyResources(this.panelMembership, "panelMembership");
|
||||
// this.panelMembership.Controls.Add(this.buttonRemove);
|
||||
// this.panelMembership.Controls.Add(this.buttonAdd);
|
||||
// this.panelMembership.Controls.Add(this.gridRoleMembership);
|
||||
// this.panelMembership.Controls.Add(this.labelMembersOfDbRole);
|
||||
// this.panelMembership.Name = "panelMembership";
|
||||
// //
|
||||
// // buttonRemove
|
||||
// //
|
||||
// resources.ApplyResources(this.buttonRemove, "buttonRemove");
|
||||
// this.buttonRemove.Name = "buttonRemove";
|
||||
// this.buttonRemove.Click += new System.EventHandler(this.buttonRemove_Click);
|
||||
// //
|
||||
// // buttonAdd
|
||||
// //
|
||||
// resources.ApplyResources(this.buttonAdd, "buttonAdd");
|
||||
// this.buttonAdd.Name = "buttonAdd";
|
||||
// this.buttonAdd.Click += new System.EventHandler(this.buttonAdd_Click);
|
||||
// //
|
||||
// // gridRoleMembership
|
||||
// //
|
||||
// resources.ApplyResources(this.gridRoleMembership, "gridRoleMembership");
|
||||
// this.gridRoleMembership.BackColor = System.Drawing.SystemColors.Window;
|
||||
// this.gridRoleMembership.ForceEnabled = false;
|
||||
// this.gridRoleMembership.Name = "gridRoleMembership";
|
||||
// this.gridRoleMembership.SelectionChanged += new Microsoft.SqlServer.Management.UI.Grid.SelectionChangedEventHandler(this.gridRoleMembership_SelectionChanged);
|
||||
// //
|
||||
// // labelMembersOfDbRole
|
||||
// //
|
||||
// resources.ApplyResources(this.labelMembersOfDbRole, "labelMembersOfDbRole");
|
||||
// this.labelMembersOfDbRole.Name = "labelMembersOfDbRole";
|
||||
// //
|
||||
// // panelDbRoleGeneralInfo
|
||||
// //
|
||||
// resources.ApplyResources(this.panelDbRoleGeneralInfo, "panelDbRoleGeneralInfo");
|
||||
// this.panelDbRoleGeneralInfo.Controls.Add(this.buttonSearchOwner);
|
||||
// this.panelDbRoleGeneralInfo.Controls.Add(this.textBoxOwner);
|
||||
// this.panelDbRoleGeneralInfo.Controls.Add(this.labelDbRoleOwner);
|
||||
// this.panelDbRoleGeneralInfo.Controls.Add(this.textBoxDbRoleName);
|
||||
// this.panelDbRoleGeneralInfo.Controls.Add(this.labelDbRoleName);
|
||||
// this.panelDbRoleGeneralInfo.Name = "panelDbRoleGeneralInfo";
|
||||
// //
|
||||
// // buttonSearchOwner
|
||||
// //
|
||||
// resources.ApplyResources(this.buttonSearchOwner, "buttonSearchOwner");
|
||||
// this.buttonSearchOwner.Name = "buttonSearchOwner";
|
||||
// this.buttonSearchOwner.Click += new System.EventHandler(this.buttonSearchOwner_Click);
|
||||
// //
|
||||
// // textBoxOwner
|
||||
// //
|
||||
// resources.ApplyResources(this.textBoxOwner, "textBoxOwner");
|
||||
// this.textBoxOwner.Name = "textBoxOwner";
|
||||
// //
|
||||
// // labelDbRoleOwner
|
||||
// //
|
||||
// resources.ApplyResources(this.labelDbRoleOwner, "labelDbRoleOwner");
|
||||
// this.labelDbRoleOwner.Name = "labelDbRoleOwner";
|
||||
// //
|
||||
// // textBoxDbRoleName
|
||||
// //
|
||||
// resources.ApplyResources(this.textBoxDbRoleName, "textBoxDbRoleName");
|
||||
// this.textBoxDbRoleName.Name = "textBoxDbRoleName";
|
||||
// //
|
||||
// // labelDbRoleName
|
||||
// //
|
||||
// resources.ApplyResources(this.labelDbRoleName, "labelDbRoleName");
|
||||
// this.labelDbRoleName.Name = "labelDbRoleName";
|
||||
// //
|
||||
// // DatabaseRoleGeneral
|
||||
// //
|
||||
// this.Controls.Add(this.panelEntireUserControl);
|
||||
// this.Name = "DatabaseRoleGeneral";
|
||||
// resources.ApplyResources(this, "$this");
|
||||
// this.panelEntireUserControl.ResumeLayout(false);
|
||||
// this.panelSchema.ResumeLayout(false);
|
||||
// ((System.ComponentModel.ISupportInitialize)(this.gridSchemasOwned)).EndInit();
|
||||
// this.panelMembership.ResumeLayout(false);
|
||||
// ((System.ComponentModel.ISupportInitialize)(this.gridRoleMembership)).EndInit();
|
||||
// this.panelDbRoleGeneralInfo.ResumeLayout(false);
|
||||
// this.panelDbRoleGeneralInfo.PerformLayout();
|
||||
// this.ResumeLayout(false);
|
||||
|
||||
// }
|
||||
// #endregion
|
||||
|
||||
#region Schemas - general operations with ...
|
||||
/// <summary>
|
||||
/// loads initial schemas from server together with information about the schema owner
|
||||
/// </summary>
|
||||
private void LoadSchemas()
|
||||
{
|
||||
this.schemaOwnership = new HybridDictionary();
|
||||
|
||||
Enumerator en = new Enumerator();
|
||||
Request req = new Request();
|
||||
req.Fields = new String [] {DatabaseRoleGeneral.schemaNameField, DatabaseRoleGeneral.schemaOwnerField};
|
||||
req.Urn = "Server/Database[@Name='" + Urn.EscapeString(this.databaseName) + "']/Schema";
|
||||
|
||||
DataTable dt = en.Process(serverConnection,req);
|
||||
// STrace.Assert((dt != null) && (0 < dt.Rows.Count), "enumerator did not return schemas");
|
||||
// STrace.Assert(!this.IsPropertiesMode || (this.dbroleName.Length != 0), "role name is not known");
|
||||
|
||||
foreach (DataRow dr in dt.Rows)
|
||||
{
|
||||
string schemaName = Convert.ToString(dr[DatabaseRoleGeneral.schemaNameField],System.Globalization.CultureInfo.InvariantCulture);
|
||||
string schemaOwner = Convert.ToString(dr[DatabaseRoleGeneral.schemaOwnerField],System.Globalization.CultureInfo.InvariantCulture);
|
||||
bool roleOwnsSchema =
|
||||
this.IsPropertiesMode &&
|
||||
(0 == String.Compare(this.dbroleName, schemaOwner, StringComparison.Ordinal));
|
||||
|
||||
this.schemaOwnership[schemaName] = new SchemaOwnership(roleOwnsSchema);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// initializes the columns and headers of schema grid - but doesnt populate grid with any data
|
||||
/// </summary>
|
||||
// private void InitializeSchemasGridColumns()
|
||||
// {
|
||||
// Microsoft.SqlServer.Management.UI.Grid.DlgGridControl grid = this.gridSchemasOwned;
|
||||
|
||||
// if (grid.RowsNumber != 0)
|
||||
// {
|
||||
// grid.DeleteAllRows();
|
||||
// }
|
||||
|
||||
// while (grid.ColumnsNumber != 0)
|
||||
// {
|
||||
// grid.DeleteColumn(0);
|
||||
// }
|
||||
|
||||
// GridColumnInfo colInfo = null;
|
||||
|
||||
// // checkbox owned/not-owned
|
||||
// colInfo = new GridColumnInfo();
|
||||
// colInfo.ColumnWidth = sizeCheckboxColumn;
|
||||
// colInfo.WidthType = GridColumnWidthType.InPixels;
|
||||
// colInfo.ColumnType = GridColumnType.Checkbox;
|
||||
// grid.AddColumn(colInfo);
|
||||
|
||||
// // schema name
|
||||
// colInfo = new GridColumnInfo();
|
||||
// colInfo.ColumnWidth = grid.Width - sizeCheckboxColumn - 2;
|
||||
// colInfo.WidthType = GridColumnWidthType.InPixels;
|
||||
// grid.AddColumn(colInfo);
|
||||
|
||||
// grid.SetHeaderInfo(colSchemasOwnedSchemas, DatabaseRoleSR.HeaderOwnedSchemas, null);
|
||||
|
||||
// grid.SelectionType = GridSelectionType.SingleRow;
|
||||
// grid.UpdateGrid();
|
||||
// }
|
||||
|
||||
// private void FillSchemasGrid()
|
||||
// {
|
||||
// Microsoft.SqlServer.Management.UI.Grid.DlgGridControl grid = this.gridSchemasOwned;
|
||||
|
||||
// grid.BeginInit();
|
||||
// grid.DeleteAllRows();
|
||||
|
||||
// IDictionaryEnumerator enumerator = this.schemaOwnership.GetEnumerator();
|
||||
// enumerator.Reset();
|
||||
// while (enumerator.MoveNext())
|
||||
// {
|
||||
// DictionaryEntry entry = enumerator.Entry;
|
||||
// GridCellCollection row = new GridCellCollection();
|
||||
// GridCell cell = null;
|
||||
|
||||
// string schemaName = entry.Key.ToString();
|
||||
// bool roleCurrentlyOwnsSchema = ((SchemaOwnership)entry.Value).currentlyOwned;
|
||||
|
||||
// // grid is filled either
|
||||
// // a) disabled-checked checkboxes: Indeterminate - if already owning schema - we cannot renounce ownership
|
||||
// // b) enabled-unchecked checkboxes: Unchecked - user can check / uncheck them and we read final state
|
||||
// cell = new GridCell(roleCurrentlyOwnsSchema ? GridCheckBoxState.Indeterminate : GridCheckBoxState.Unchecked);
|
||||
// row.Add(cell);
|
||||
|
||||
// cell = new GridCell(schemaName);
|
||||
// row.Add(cell);
|
||||
|
||||
// grid.AddRow(row);
|
||||
// }
|
||||
|
||||
// grid.EndInit();
|
||||
|
||||
// if (grid.RowsNumber > 0)
|
||||
// {
|
||||
// grid.SelectedRow = 0;
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// sends to server changes related to schema ownership
|
||||
/// </summary>
|
||||
private void SendToServerSchemaOwnershipChanges(Database db, DatabaseRole dbrole)
|
||||
{
|
||||
if (9 <= this.dataContainer.Server.Information.Version.Major)
|
||||
{
|
||||
IDictionaryEnumerator enumerator = this.schemaOwnership.GetEnumerator();
|
||||
enumerator.Reset();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
DictionaryEntry de = enumerator.Entry;
|
||||
string schemaName = de.Key.ToString();
|
||||
SchemaOwnership ownership = (SchemaOwnership)de.Value;
|
||||
|
||||
// If we are creating a new role, then no schema will have been initially owned by this role.
|
||||
// If we are modifying an existing role, we can only take ownership of roles. (Ownership can't
|
||||
// be renounced, it can only be positively assigned to a principal.)
|
||||
if (ownership.currentlyOwned && !ownership.initiallyOwned)
|
||||
{
|
||||
Schema schema = db.Schemas[schemaName];
|
||||
schema.Owner = dbrole.Name;
|
||||
schema.Alter();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// private void gridSchemasOwned_MouseButtonClicked(object sender, Microsoft.SqlServer.Management.UI.Grid.MouseButtonClickedEventArgs args)
|
||||
// {
|
||||
// if ((args.Button == MouseButtons.Left) &&
|
||||
// (colSchemasChecked == args.ColumnIndex))
|
||||
// {
|
||||
// int row = (int) args.RowIndex;
|
||||
// string schemaName = this.gridSchemasOwned.GetCellInfo(row, colSchemasOwnedSchemas).CellData.ToString();
|
||||
// GridCheckBoxState newState = this.FlipCheckbox(this.gridSchemasOwned, row, colSchemasChecked);
|
||||
// bool nowOwned = ((GridCheckBoxState.Checked == newState) || (GridCheckBoxState.Indeterminate == newState));
|
||||
|
||||
// ((SchemaOwnership) this.schemaOwnership[schemaName]).currentlyOwned = nowOwned;
|
||||
// }
|
||||
// }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Membership - general operations with ...
|
||||
|
||||
/// <summary>
|
||||
/// loads from server initial membership information
|
||||
/// </summary>
|
||||
private void LoadMembership()
|
||||
{
|
||||
this.roleMembers = new HybridDictionary();
|
||||
|
||||
if (this.IsPropertiesMode)
|
||||
{
|
||||
Enumerator enumerator = new Enumerator();
|
||||
Urn urn = String.Format(System.Globalization.CultureInfo.InvariantCulture,
|
||||
"Server/Database[@Name='{0}']/Role[@Name='{1}']/Member",
|
||||
Urn.EscapeString(this.databaseName),
|
||||
Urn.EscapeString(this.dbroleName));
|
||||
string[] fields = new string[] { DatabaseRoleGeneral.memberNameField};
|
||||
OrderBy[] orderBy = new OrderBy[] { new OrderBy(DatabaseRoleGeneral.memberNameField, OrderBy.Direction.Asc)};
|
||||
Request request = new Request(urn, fields, orderBy);
|
||||
DataTable dt = enumerator.Process(this.serverConnection, request);
|
||||
|
||||
foreach (DataRow dr in dt.Rows)
|
||||
{
|
||||
string memberName = dr[DatabaseRoleGeneral.memberNameField].ToString();
|
||||
this.roleMembers[memberName] = new RoleMembership(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// initialize grid column headers, but not the content
|
||||
/// </summary>
|
||||
// private void InitializeMembershipGridColumns()
|
||||
// {
|
||||
// Microsoft.SqlServer.Management.UI.Grid.DlgGridControl grid = this.gridRoleMembership;
|
||||
|
||||
// if (grid.RowsNumber != 0)
|
||||
// {
|
||||
// grid.DeleteAllRows();
|
||||
// }
|
||||
|
||||
// while (grid.ColumnsNumber != 0)
|
||||
// {
|
||||
// grid.DeleteColumn(0);
|
||||
// }
|
||||
|
||||
// GridColumnInfo colInfo = null;
|
||||
|
||||
// // bitmap member type
|
||||
// colInfo = new GridColumnInfo();
|
||||
// colInfo.ColumnWidth = sizeBitmapColumn;
|
||||
// colInfo.WidthType = GridColumnWidthType.InPixels;
|
||||
// colInfo.ColumnType = GridColumnType.Bitmap;
|
||||
// grid.AddColumn(colInfo);
|
||||
|
||||
// // member name
|
||||
// colInfo = new GridColumnInfo();
|
||||
// colInfo.ColumnWidth = grid.Width - sizeBitmapColumn - 2;
|
||||
// colInfo.WidthType = GridColumnWidthType.InPixels;
|
||||
// grid.AddColumn(colInfo);
|
||||
|
||||
// grid.SetHeaderInfo(colMembershipRoleMembers, DatabaseRoleSR.HeaderRoleMembers, null);
|
||||
|
||||
// grid.SelectionType = GridSelectionType.SingleRow;
|
||||
// grid.UpdateGrid();
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// fills the membership grid with data (bitmaps, names, etc)
|
||||
/// </summary>
|
||||
// private void FillMembershipGrid()
|
||||
// {
|
||||
// Microsoft.SqlServer.Management.UI.Grid.DlgGridControl grid = this.gridRoleMembership;
|
||||
|
||||
// grid.BeginInit();
|
||||
// grid.DeleteAllRows();
|
||||
|
||||
// IDictionaryEnumerator enumerator = this.roleMembers.GetEnumerator();
|
||||
// enumerator.Reset();
|
||||
// while (enumerator.MoveNext())
|
||||
// {
|
||||
// DictionaryEntry entry = enumerator.Entry;
|
||||
// string memberName = entry.Key.ToString();
|
||||
// RoleMembership membership = (RoleMembership) entry.Value;
|
||||
|
||||
// if (membership.currentlyAMember)
|
||||
// {
|
||||
// GridCellCollection row = new GridCellCollection();
|
||||
// GridCell cell = null;
|
||||
|
||||
// cell = new GridCell(bitmapMember);
|
||||
// row.Add(cell);
|
||||
|
||||
// cell = new GridCell(memberName);
|
||||
// row.Add(cell);
|
||||
|
||||
// grid.AddRow(row);
|
||||
// }
|
||||
// }
|
||||
|
||||
// grid.EndInit();
|
||||
|
||||
// if (grid.RowsNumber > 0)
|
||||
// {
|
||||
// grid.SelectedRow = 0;
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// sends to server user changes related to membership
|
||||
/// </summary>
|
||||
private void SendToServerMembershipChanges(Database db, DatabaseRole dbrole)
|
||||
{
|
||||
IDictionaryEnumerator enumerator = this.roleMembers.GetEnumerator();
|
||||
enumerator.Reset();
|
||||
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
DictionaryEntry entry = enumerator.Entry;
|
||||
string memberName = entry.Key.ToString();
|
||||
RoleMembership membership = (RoleMembership) entry.Value;
|
||||
|
||||
if (!membership.initiallyAMember && membership.currentlyAMember)
|
||||
{
|
||||
dbrole.AddMember(memberName);
|
||||
}
|
||||
else if (membership.initiallyAMember && !membership.currentlyAMember)
|
||||
{
|
||||
dbrole.DropMember(memberName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// private void gridRoleMembership_SelectionChanged(object sender, Microsoft.SqlServer.Management.UI.Grid.SelectionChangedEventArgs args)
|
||||
// {
|
||||
// EnableDisableControls();
|
||||
// }
|
||||
|
||||
// private void buttonAdd_Click(object sender, System.EventArgs e)
|
||||
// {
|
||||
|
||||
// using (SqlObjectSearch dlg = new SqlObjectSearch(
|
||||
// this.Font,
|
||||
// iconSearchRolesAndUsers,
|
||||
// this.HelpProvider,
|
||||
// DatabaseRoleSR.Add_DialogTitle,
|
||||
// this.DataContainer.ConnectionInfo,
|
||||
// this.databaseName,
|
||||
// new SearchableObjectTypeCollection(SearchableObjectType.User, SearchableObjectType.DatabaseRole),
|
||||
// new SearchableObjectTypeCollection(SearchableObjectType.User, SearchableObjectType.DatabaseRole),
|
||||
// false))
|
||||
// {
|
||||
// if (DialogResult.OK == dlg.ShowDialog(this.FindForm()))
|
||||
// {
|
||||
// bool memberAdded = false;
|
||||
|
||||
// this.gridRoleMembership.BeginInit();
|
||||
|
||||
// foreach (SearchableObject principal in dlg.SearchResults)
|
||||
// {
|
||||
// if (!this.roleMembers.Contains(principal.Name))
|
||||
// {
|
||||
// this.roleMembers[principal.Name] = new RoleMembership(false, true);
|
||||
// memberAdded = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// RoleMembership membership = (RoleMembership) this.roleMembers[principal.Name];
|
||||
|
||||
// if (!membership.currentlyAMember)
|
||||
// {
|
||||
// membership.currentlyAMember = true;
|
||||
// memberAdded = true;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (memberAdded)
|
||||
// {
|
||||
// GridCellCollection row = new GridCellCollection();
|
||||
// GridCell cell = null;
|
||||
|
||||
// cell = new GridCell(bitmapMember);
|
||||
// row.Add(cell);
|
||||
|
||||
// cell = new GridCell(principal.Name);
|
||||
// row.Add(cell);
|
||||
|
||||
// this.gridRoleMembership.AddRow(row);
|
||||
// }
|
||||
// }
|
||||
|
||||
// this.gridRoleMembership.EndInit();
|
||||
|
||||
// if (memberAdded)
|
||||
// {
|
||||
// this.gridRoleMembership.SelectedRow = this.gridRoleMembership.RowsNumber - 1;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// private void buttonRemove_Click(object sender, System.EventArgs e)
|
||||
// {
|
||||
// DlgGridControl grid = this.gridRoleMembership;
|
||||
|
||||
// int row = this.gridRoleMembership.SelectedRow;
|
||||
// STrace.Assert(0 <= row, "unexpected row number");
|
||||
|
||||
// if (0 <= row)
|
||||
// {
|
||||
// string memberName = this.gridRoleMembership.GetCellInfo(row, colMembershipRoleMembers).CellData.ToString();
|
||||
// RoleMembership membership = (RoleMembership) this.roleMembers[memberName];
|
||||
|
||||
// if (membership.initiallyAMember)
|
||||
// {
|
||||
// membership.currentlyAMember = false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// this.roleMembers.Remove(memberName);
|
||||
// }
|
||||
|
||||
// this.gridRoleMembership.DeleteRow(row);
|
||||
// }
|
||||
// }
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
212
src/Microsoft.SqlTools.ServiceLayer/Security/NetStandardUtils.cs
Normal file
212
src/Microsoft.SqlTools.ServiceLayer/Security/NetStandardUtils.cs
Normal file
@@ -0,0 +1,212 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using SMO = Microsoft.SqlServer.Management.Smo;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// NetStandard compatible helpers
|
||||
/// </summary>
|
||||
#if NETCOREAPP2_0
|
||||
public class Utils
|
||||
#else
|
||||
internal partial class Utils
|
||||
#endif
|
||||
{
|
||||
private Utils() { }
|
||||
|
||||
public static bool IsKatmaiOrLater(int version)
|
||||
{
|
||||
return (10 <= version);
|
||||
}
|
||||
|
||||
public static bool IsKjOrLater(ServerVersion version)
|
||||
{
|
||||
return (version.Major > 10
|
||||
|| (version.Major == 10 && version.Minor >= 50));
|
||||
}
|
||||
|
||||
public static bool IsSql11OrLater(ServerVersion version)
|
||||
{
|
||||
return IsSql11OrLater(version.Major);
|
||||
}
|
||||
|
||||
public static bool IsSql11OrLater(int versionMajor)
|
||||
{
|
||||
return (versionMajor >= 11);
|
||||
}
|
||||
|
||||
public static bool IsSql12OrLater(ServerVersion version)
|
||||
{
|
||||
return IsSql12OrLater(version.Major);
|
||||
}
|
||||
|
||||
public static bool IsSql12OrLater(int versionMajor)
|
||||
{
|
||||
return (versionMajor >= 12);
|
||||
}
|
||||
|
||||
public static bool IsSql13OrLater(ServerVersion version)
|
||||
{
|
||||
return IsSql13OrLater(version.Major);
|
||||
}
|
||||
|
||||
public static bool IsSql13OrLater(int versionMajor)
|
||||
{
|
||||
return (versionMajor >= 13);
|
||||
}
|
||||
|
||||
public static bool IsSql14OrLater(ServerVersion version)
|
||||
{
|
||||
return IsSql14OrLater(version.Major);
|
||||
}
|
||||
|
||||
public static bool IsSql14OrLater(int versionMajor)
|
||||
{
|
||||
return (versionMajor >= 14);
|
||||
}
|
||||
|
||||
public static bool IsSql15OrLater(ServerVersion version)
|
||||
{
|
||||
return IsSql15OrLater(version.Major);
|
||||
}
|
||||
|
||||
public static bool IsSql15OrLater(int versionMajor)
|
||||
{
|
||||
return (versionMajor >= 15);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Check if the version is SQL 2019 CU4 or later.
|
||||
/// </summary>
|
||||
/// <param name="version"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// SQL2019 CU3 is going to be 4023; CU4 is going to be 4033
|
||||
/// SQL2019 CU4 (before the snap to the release branch) is 4028.
|
||||
/// </remarks>
|
||||
public static bool IsSql15OCU4OrLater(Version version)
|
||||
{
|
||||
return(version >= new Version(15, 0, 4028));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the version is SQL 2016 SP1 or later.
|
||||
/// </summary>
|
||||
/// <param name="version"></param>
|
||||
/// <returns>true if the version is SQL 2016 SP1 or later, false otherwise</returns>
|
||||
public static bool IsSql13SP1OrLater(Version version)
|
||||
{
|
||||
return (version >= new Version(13, 0, 3510));
|
||||
}
|
||||
|
||||
public static bool IsXTPSupportedOnServer(SMO.Server server)
|
||||
{
|
||||
if(server.DatabaseEngineEdition == DatabaseEngineEdition.SqlOnDemand)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool isXTPSupported = false;
|
||||
|
||||
if (server.ConnectionContext.ExecuteScalar("SELECT SERVERPROPERTY('IsXTPSupported')") != DBNull.Value)
|
||||
{
|
||||
isXTPSupported = server.IsXTPSupported;
|
||||
}
|
||||
|
||||
return isXTPSupported;
|
||||
}
|
||||
|
||||
public static bool IsPolybasedInstalledOnServer(SMO.Server server)
|
||||
{
|
||||
bool isPolybaseInstalled = false;
|
||||
|
||||
if (server.IsSupportedProperty("IsPolyBaseInstalled"))
|
||||
{
|
||||
isPolybaseInstalled = server.IsPolyBaseInstalled;
|
||||
}
|
||||
|
||||
return isPolybaseInstalled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if current user has given permission on given server.
|
||||
/// </summary>
|
||||
/// <param name="server"></param>
|
||||
/// <param name="permissionName"></param>
|
||||
/// <returns></returns>
|
||||
public static bool HasPermissionOnServer(SMO.Server server, string permissionName)
|
||||
{
|
||||
return Convert.ToBoolean(server.ConnectionContext.ExecuteScalar(
|
||||
string.Format(CultureInfo.InvariantCulture,
|
||||
"SELECT HAS_PERMS_BY_NAME(null, null, '{0}');",
|
||||
permissionName)));
|
||||
}
|
||||
|
||||
public static bool FilestreamEnabled(SMO.Server svr)
|
||||
{
|
||||
bool result = false;
|
||||
if (svr != null)
|
||||
{
|
||||
if (IsKatmaiOrLater(svr.Information.Version.Major)
|
||||
&& svr.ServerType != DatabaseEngineType.SqlAzureDatabase) //Azure doesn't support filestream
|
||||
{
|
||||
if (svr.Configuration.FilestreamAccessLevel.RunValue != 0)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool IsYukonOrAbove(SMO.Server server)
|
||||
{
|
||||
return server.Version.Major >= 9;
|
||||
}
|
||||
|
||||
public static bool IsBelowYukon(SMO.Server server)
|
||||
{
|
||||
return server.Version.Major < 9;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Some calendars, such as the UmAlQuraCalendar, support an upper date range that is earlier than MaxValue.
|
||||
/// In these cases, trying to access MaxValue in variable assignments or formatting and parsing operations can throw
|
||||
/// an ArgumentOutOfRangeException. Rather than retrieving the value of DateTime.MaxValue, you can retrieve the value
|
||||
/// of the specified culture's latest valid date value from the
|
||||
/// System.Globalization.CultureInfo.DateTimeFormat.Calendar.MaxSupportedDateTime property.
|
||||
/// http://msdn.microsoft.com/en-us/library/system.datetime.maxvalue(v=VS.90).aspx
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static DateTime GetMaxCultureDateTime()
|
||||
{
|
||||
CultureInfo currentCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
|
||||
return currentCulture.DateTimeFormat.Calendar.MaxSupportedDateTime;
|
||||
}
|
||||
|
||||
public static string MakeSqlBracket(string s)
|
||||
{
|
||||
return "[" + s.Replace("]", "]]") + "]";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the server is in AS Azure
|
||||
/// </summary>
|
||||
/// <param name="serverName"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsASAzure(string serverName)
|
||||
{
|
||||
return !string.IsNullOrEmpty(serverName) && serverName.StartsWith("asazure://", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
10876
src/Microsoft.SqlTools.ServiceLayer/Security/PermissionsData.cs
Normal file
10876
src/Microsoft.SqlTools.ServiceLayer/Security/PermissionsData.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
{
|
||||
internal static class PermissionsDataExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether this SecurableType is a valid Schema-Scoped Securable for the given server version, engine edition and engine type
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="serverVersion"></param>
|
||||
/// <param name="databaseEngineEdition"></param>
|
||||
/// <param name="databaseEngineType"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsValidSchemaBoundSecurable(this SecurableType type, ServerVersion serverVersion, DatabaseEngineEdition databaseEngineEdition, DatabaseEngineType databaseEngineType)
|
||||
{
|
||||
return
|
||||
type.GetType().GetField(type.ToString())
|
||||
.GetCustomAttributes(typeof (SchemaScopedSecurableAttribute), true)
|
||||
.Cast<SchemaScopedSecurableAttribute>()
|
||||
.Any(attr => attr.IsValid(serverVersion, databaseEngineType, databaseEngineEdition));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Schema-Scoped URN for this SecurableType
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="schema"></param>
|
||||
/// <param name="databaseName"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetSchemaScopedUrn(this SecurableType type, string schema, string databaseName)
|
||||
{
|
||||
SchemaScopedSecurableAttribute attr =
|
||||
type.GetType().GetField(type.ToString())
|
||||
.GetCustomAttributes(typeof (SchemaScopedSecurableAttribute), true)
|
||||
.Cast<SchemaScopedSecurableAttribute>()
|
||||
.FirstOrDefault() ?? throw new InvalidOperationException("Type {0} did not define a SchemaScopedSecurableUrn attribute");
|
||||
return attr.GetUrn(schema, databaseName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Microsoft.SqlServer.Management.Common;
|
||||
using Microsoft.SqlServer.Management.Sdk.Sfc;
|
||||
using Microsoft.SqlServer.Management.Smo;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// An attribute for sqlmgmt\src\permissionsdata.cs!SecurableType that maps it to the corresponding SMO
|
||||
/// type. This allows us to use that type to decide whether that securable is valid for a given server
|
||||
/// version/engine edition/engine type combo and to get the URN suffix value for that type using SMO
|
||||
/// instead of duplicating it in SqlMgmt.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
internal class SchemaScopedSecurableAttribute : Attribute
|
||||
{
|
||||
private readonly Type _smoType;
|
||||
private readonly string _urnSuffix;
|
||||
private readonly string _additionalParam;
|
||||
|
||||
/// <summary>
|
||||
/// Basic public constructor
|
||||
/// </summary>
|
||||
/// <param name="smoType">The SMO Type this Securable is mapped to</param>
|
||||
/// <param name="additionalParamName">(Optional) The name of an additional param</param>
|
||||
/// <param name="additionalParamValue">(Optional) The value of an additional param</param>
|
||||
public SchemaScopedSecurableAttribute(Type smoType, string additionalParamName = "", object additionalParamValue = null )
|
||||
{
|
||||
_smoType = smoType;
|
||||
//The additional param is optional - just ignore if we don't have a valid name
|
||||
_additionalParam = string.IsNullOrEmpty(additionalParamName)
|
||||
? String.Empty
|
||||
: string.Format("@{0}='{1}'", additionalParamName, Urn.EscapeString(additionalParamValue.ToString()));
|
||||
PropertyInfo urnSuffixProperty = _smoType.GetProperty("UrnSuffix", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public) ?? throw new InvalidArgumentException(string.Format("Type {0} did not have expected UrnSuffix property defined", smoType.Name));
|
||||
_urnSuffix = urnSuffixProperty.GetValue(null, null).ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The SMO Type that this securable is mapped to
|
||||
/// </summary>
|
||||
public Type SmoType
|
||||
{
|
||||
get { return _smoType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether this Securable is valid for the given server version/engine type/engine edition combo.
|
||||
/// </summary>
|
||||
/// <param name="serverVersion"></param>
|
||||
/// <param name="databaseEngineType"></param>
|
||||
/// <param name="databaseEngineEdition"></param>
|
||||
/// <returns></returns>
|
||||
public bool IsValid(ServerVersion serverVersion, DatabaseEngineType databaseEngineType, DatabaseEngineEdition databaseEngineEdition)
|
||||
{
|
||||
return SmoUtility.IsSupportedObject(_smoType, serverVersion, databaseEngineType, databaseEngineEdition);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds the URN for this Securable using the specified schema name (with optional database name for db-scoped securables)
|
||||
/// </summary>
|
||||
/// <param name="schemaName"></param>
|
||||
/// <param name="databaseName"></param>
|
||||
/// <returns></returns>
|
||||
public string GetUrn(string schemaName, string databaseName = "")
|
||||
{
|
||||
StringBuilder urn = new StringBuilder("Server");
|
||||
if (!string.IsNullOrEmpty(databaseName))
|
||||
{
|
||||
urn.AppendFormat("/Database[@Name='{0}']", Urn.EscapeString(databaseName));
|
||||
}
|
||||
urn.AppendFormat("/{0}[{1}{2}@Schema='{3}']",
|
||||
_urnSuffix,
|
||||
_additionalParam,
|
||||
string.IsNullOrEmpty(_additionalParam) ? string.Empty : " and ",
|
||||
Urn.EscapeString(schemaName));
|
||||
return urn.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
2328
src/Microsoft.SqlTools.ServiceLayer/Security/SqlObjectSearchData.cs
Normal file
2328
src/Microsoft.SqlTools.ServiceLayer/Security/SqlObjectSearchData.cs
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user