mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-17 02:51:45 -05:00
Fix scripting of users on SQL DB (#2014)
* Fix scripting of users on SQL DB * Minor typos * Add null checks
This commit is contained in:
@@ -31,6 +31,17 @@ namespace Microsoft.SqlTools.ServiceLayer.Management
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private ExecutionMode m_executionMode = ExecutionMode.Success;
|
private ExecutionMode m_executionMode = ExecutionMode.Success;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// indicates that this is a database level operation, which on SQL DB will require an alternate
|
||||||
|
/// execution manager to capture sql for scripting
|
||||||
|
/// </summary>
|
||||||
|
private bool isDatabaseOperation = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parent database object to use for database operations
|
||||||
|
/// </summary>
|
||||||
|
private Database parentDb = null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// data container with initialization-related information
|
/// data container with initialization-related information
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -255,6 +266,26 @@ namespace Microsoft.SqlTools.ServiceLayer.Management
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected bool IsDatabaseOperation
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.isDatabaseOperation;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.isDatabaseOperation = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Database ParentDb
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.parentDb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SMO Server connection that MUST be used for all enumerator calls
|
/// SMO Server connection that MUST be used for all enumerator calls
|
||||||
/// We'll get this object out of CDataContainer, that must be initialized
|
/// We'll get this object out of CDataContainer, that must be initialized
|
||||||
@@ -385,6 +416,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Management
|
|||||||
sc = sqlDialogSubject.ExecutionManager.ConnectionContext.CapturedSql.Text;
|
sc = sqlDialogSubject.ExecutionManager.ConnectionContext.CapturedSql.Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for SQL DB database-level operations the script could be on the database object's execution manager
|
||||||
|
if (sc.Count == 0 && this.isDatabaseOperation && this.parentDb != null
|
||||||
|
&& this.DataContainer.Server.ServerType == DatabaseEngineType.SqlAzureDatabase)
|
||||||
|
{
|
||||||
|
sc = this.parentDb.ExecutionManager.ConnectionContext.CapturedSql.Text;
|
||||||
|
}
|
||||||
|
|
||||||
StringBuilder script = new StringBuilder(4096);
|
StringBuilder script = new StringBuilder(4096);
|
||||||
if (sc != null)
|
if (sc != null)
|
||||||
{
|
{
|
||||||
@@ -452,6 +490,15 @@ namespace Microsoft.SqlTools.ServiceLayer.Management
|
|||||||
sqlDialogSubject.ExecutionManager.ConnectionContext.SqlExecutionModes = newMode;
|
sqlDialogSubject.ExecutionManager.ConnectionContext.SqlExecutionModes = newMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.isDatabaseOperation)
|
||||||
|
{
|
||||||
|
this.parentDb = this.DataContainer.Server.GetSmoObject(this.DataContainer.ParentUrn) as Database;
|
||||||
|
if (this.parentDb != null && this.DataContainer.Server.ServerType == DatabaseEngineType.SqlAzureDatabase)
|
||||||
|
{
|
||||||
|
this.parentDb.ExecutionManager.ConnectionContext.SqlExecutionModes = newMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
executionResult = DoPreProcessExecutionAndRunViews(executionInfo.RunType);
|
executionResult = DoPreProcessExecutionAndRunViews(executionInfo.RunType);
|
||||||
|
|
||||||
if (isScripting)
|
if (isScripting)
|
||||||
@@ -465,10 +512,18 @@ namespace Microsoft.SqlTools.ServiceLayer.Management
|
|||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
GetServerConnectionForScript().SqlExecutionModes = executionModeOriginal;
|
GetServerConnectionForScript().SqlExecutionModes = executionModeOriginal;
|
||||||
|
if (this.parentDb != null && this.isDatabaseOperation && this.DataContainer.Server.ServerType == DatabaseEngineType.SqlAzureDatabase)
|
||||||
|
{
|
||||||
|
this.parentDb.ExecutionManager.ConnectionContext.SqlExecutionModes = executionModeOriginal;
|
||||||
|
}
|
||||||
|
|
||||||
if (isScripting)
|
if (isScripting)
|
||||||
{
|
{
|
||||||
GetServerConnectionForScript().CapturedSql.Clear();
|
GetServerConnectionForScript().CapturedSql.Clear();
|
||||||
|
if (this.parentDb != null && this.isDatabaseOperation && this.DataContainer.Server.ServerType == DatabaseEngineType.SqlAzureDatabase)
|
||||||
|
{
|
||||||
|
this.parentDb.ExecutionManager.ConnectionContext.CapturedSql.Clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sqlDialogSubject != null)
|
if (sqlDialogSubject != null)
|
||||||
|
|||||||
@@ -441,6 +441,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
|||||||
UserPrototypeData? originalData)
|
UserPrototypeData? originalData)
|
||||||
{
|
{
|
||||||
this.DataContainer = dataContainer;
|
this.DataContainer = dataContainer;
|
||||||
|
this.IsDatabaseOperation = true;
|
||||||
this.configAction = configAction;
|
this.configAction = configAction;
|
||||||
|
|
||||||
ExhaustiveUserTypes currentUserType;
|
ExhaustiveUserTypes currentUserType;
|
||||||
@@ -475,7 +476,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
|||||||
{
|
{
|
||||||
if (this.configAction != ConfigAction.Drop)
|
if (this.configAction != ConfigAction.Drop)
|
||||||
{
|
{
|
||||||
this.userPrototype.ApplyChanges();
|
this.userPrototype.ApplyChanges(this.ParentDb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -550,9 +550,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public User ApplyChanges()
|
public User ApplyChanges(Database parentDb)
|
||||||
{
|
{
|
||||||
User user = this.GetUser();
|
User user = this.GetUser(parentDb);
|
||||||
|
|
||||||
if (this.ChangesExist())
|
if (this.ChangesExist())
|
||||||
{
|
{
|
||||||
@@ -564,10 +564,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
|||||||
//it will again generate the script corresponding to that.
|
//it will again generate the script corresponding to that.
|
||||||
user.Refresh();
|
user.Refresh();
|
||||||
|
|
||||||
this.ApplySchemaOwnershipChanges(user);
|
this.ApplySchemaOwnershipChanges(parentDb, user);
|
||||||
this.IsSchemaOwnershipChangesApplied = true;
|
this.IsSchemaOwnershipChangesApplied = true;
|
||||||
|
|
||||||
this.ApplyRoleMembershipChanges(user);
|
this.ApplyRoleMembershipChanges(parentDb, user);
|
||||||
this.IsRoleMembershipChangesApplied = true;
|
this.IsRoleMembershipChangesApplied = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,7 +586,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplySchemaOwnershipChanges(User user)
|
private void ApplySchemaOwnershipChanges(Database parentDb, User user)
|
||||||
{
|
{
|
||||||
IEnumerator<KeyValuePair<string, bool>>? enumerator = this.currentState.isSchemaOwned?.GetEnumerator();
|
IEnumerator<KeyValuePair<string, bool>>? enumerator = this.currentState.isSchemaOwned?.GetEnumerator();
|
||||||
if (enumerator != null)
|
if (enumerator != null)
|
||||||
@@ -604,7 +604,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
|||||||
{
|
{
|
||||||
System.Diagnostics.Debug.Assert(!this.Exists || userIsOwner, "shouldn't have to unset ownership for new users");
|
System.Diagnostics.Debug.Assert(!this.Exists || userIsOwner, "shouldn't have to unset ownership for new users");
|
||||||
|
|
||||||
Schema schema = this.parent.Schemas[schemaName];
|
Schema schema = parentDb.Schemas[schemaName];
|
||||||
schema.Owner = userIsOwner ? user.Name : nullString;
|
schema.Owner = userIsOwner ? user.Name : nullString;
|
||||||
schema.Alter();
|
schema.Alter();
|
||||||
}
|
}
|
||||||
@@ -612,7 +612,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyRoleMembershipChanges(User user)
|
private void ApplyRoleMembershipChanges(Database parentDb, User user)
|
||||||
{
|
{
|
||||||
IEnumerator<KeyValuePair<string, bool>>? enumerator = this.currentState.isMember?.GetEnumerator();
|
IEnumerator<KeyValuePair<string, bool>>? enumerator = this.currentState.isMember?.GetEnumerator();
|
||||||
if (enumerator != null)
|
if (enumerator != null)
|
||||||
@@ -628,7 +628,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
|||||||
{
|
{
|
||||||
System.Diagnostics.Debug.Assert(this.Exists || userIsMember, "shouldn't have to unset membership for new users");
|
System.Diagnostics.Debug.Assert(this.Exists || userIsMember, "shouldn't have to unset membership for new users");
|
||||||
|
|
||||||
DatabaseRole role = this.parent.Roles[roleName];
|
DatabaseRole role = parentDb.Roles[roleName];
|
||||||
|
|
||||||
if (userIsMember)
|
if (userIsMember)
|
||||||
{
|
{
|
||||||
@@ -663,14 +663,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public User GetUser()
|
public User GetUser(Database parentDb)
|
||||||
{
|
{
|
||||||
User result;
|
User result;
|
||||||
|
|
||||||
// if we think we exist, get the SMO user object
|
// if we think we exist, get the SMO user object
|
||||||
if (this.Exists)
|
if (this.Exists)
|
||||||
{
|
{
|
||||||
result = this.parent.Users[this.originalState.name];
|
result = parentDb.Users[this.originalState.name];
|
||||||
result?.Refresh();
|
result?.Refresh();
|
||||||
|
|
||||||
System.Diagnostics.Debug.Assert(0 == string.Compare(this.originalState.name, this.currentState.name, StringComparison.Ordinal), "name of existing user has changed");
|
System.Diagnostics.Debug.Assert(0 == string.Compare(this.originalState.name, this.currentState.name, StringComparison.Ordinal), "name of existing user has changed");
|
||||||
@@ -681,7 +681,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = new User(this.parent, this.Name);
|
result = new User(parentDb, this.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -824,8 +824,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
Database? parentDb = this.context.Server.GetSmoObject(this.context.ParentUrn) as Database;
|
||||||
|
User user = this.GetUser(parentDb);
|
||||||
|
|
||||||
// Default Schema was not supported before Denali for windows group.
|
// Default Schema was not supported before Denali for windows group.
|
||||||
User user = this.GetUser();
|
|
||||||
if (this.Exists && user.LoginType == Microsoft.SqlServer.Management.Smo.LoginType.WindowsGroup)
|
if (this.Exists && user.LoginType == Microsoft.SqlServer.Management.Smo.LoginType.WindowsGroup)
|
||||||
{
|
{
|
||||||
return SqlMgmtUtils.IsSql11OrLater(this.context.Server.ConnectionContext.ServerVersion);
|
return SqlMgmtUtils.IsSql11OrLater(this.context.Server.ConnectionContext.ServerVersion);
|
||||||
|
|||||||
Reference in New Issue
Block a user