From bec0877e32ce86e259e7452c24243e01cab3ba58 Mon Sep 17 00:00:00 2001 From: Hai Cao Date: Thu, 2 Mar 2023 17:51:31 -0800 Subject: [PATCH] [User Management] Fix login handlers (#1896) * fix default language * fix update * fix server role error with azure --- .../Localization/sr.cs | 11 ++++++ .../Localization/sr.resx | 4 +++ .../Localization/sr.strings | 7 +++- .../Localization/sr.xlf | 5 +++ .../Security/LoginData.cs | 34 +++++++++++++++++- .../Security/SecurityService.cs | 35 +++++++++++++------ 6 files changed, 83 insertions(+), 13 deletions(-) diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs index d626cd0d..613fa1e7 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs @@ -9709,6 +9709,14 @@ namespace Microsoft.SqlTools.ServiceLayer } } + public static string DefaultLanguagePlaceholder + { + get + { + return Keys.GetString(Keys.DefaultLanguagePlaceholder); + } + } + public static string ConnectionServiceListDbErrorNotConnected(string uri) { return Keys.GetString(Keys.ConnectionServiceListDbErrorNotConnected, uri); @@ -14027,6 +14035,9 @@ namespace Microsoft.SqlTools.ServiceLayer public const string ErrorConnectionNotFound = "ErrorConnectionNotFound"; + public const string DefaultLanguagePlaceholder = "DefaultLanguagePlaceholder"; + + private Keys() { } diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx index a9fc61ba..c557cc89 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx @@ -5386,4 +5386,8 @@ The Query Processor estimates that implementing the following index could improv The connection could not be found + + <default> + + diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings index 830320bf..00d5df71 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings @@ -2442,4 +2442,9 @@ UnsupportedModelType(string type) = Unsupported model type: {0}. GetUserDefinedObjectsFromModelFailed = Failed to get user defined objects from model. #ObjectManagement Service -ErrorConnectionNotFound = The connection could not be found \ No newline at end of file +ErrorConnectionNotFound = The connection could not be found + +############################################################################ +# Security Service +DefaultLanguagePlaceholder = + diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf index aa847071..06175fa7 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf @@ -6566,6 +6566,11 @@ The Query Processor estimates that implementing the following index could improv The Enclave Attestation URL must not be specified with Attestation Protocol 'None'. Either set appropriate Attestation Protocol or remove Attestation URL from connection properties. + + <default> + <default> + + \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/Security/LoginData.cs b/src/Microsoft.SqlTools.ServiceLayer/Security/LoginData.cs index d19e9896..390c433d 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Security/LoginData.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Security/LoginData.cs @@ -1363,6 +1363,7 @@ INNER JOIN sys.sql_logins AS sql_logins { this.server = server; this.login = login; + LoadData(); } /// @@ -2087,7 +2088,10 @@ INNER JOIN sys.sql_logins AS sql_logins this.SqlPassword = login.Password; this.OldPassword = login.OldPassword; this.LoginType = GetLoginType(login); - this.DefaultLanguage = login.DefaultLanguage; + if (this.DefaultLanguage != null && 0 != String.Compare(login.DefaultLanguage, SR.DefaultLanguagePlaceholder, StringComparison.Ordinal)) + { + this.DefaultLanguage = login.DefaultLanguage.Split(" - ")[1]; + } this.DefaultDatabase = login.DefaultDatabase; this.EnforcePolicy = login.EnforcePasswordPolicy; this.EnforceExpiration = login.EnforcePasswordPolicy ? login.EnforcePasswordExpiration : false; @@ -2350,6 +2354,12 @@ INNER JOIN sys.sql_logins AS sql_logins // get the login Login login = server.Logins[this.LoginName]; + if (server.DatabaseEngineType == DatabaseEngineType.SqlAzureDatabase) + { + ApplyServerRoleChangesForAzure(server); + return; + } + // foreach server role foreach (ServerRole role in server.Roles) { @@ -2374,6 +2384,28 @@ INNER JOIN sys.sql_logins AS sql_logins } } + private void ApplyServerRoleChangesForAzure(Microsoft.SqlServer.Management.Smo.Server server) + { + // foreach server role + foreach (string role in this.ServerRoles.ServerRoleNames) + { + bool wasOriginallyARoleMember = this.originalState.ServerRoles.IsMember(role); + bool isCurrentlyARoleMember = this.currentState.ServerRoles.IsMember(role); + + + // if the login is currently a member of the role, but wasn't originally a member, add the login to the role + if (isCurrentlyARoleMember && !wasOriginallyARoleMember) + { + //run query to add + } + // if the login is not currently a member of the role, but originally was a member, remove the login from the role + else if (!isCurrentlyARoleMember && wasOriginallyARoleMember) + { + //run query to drop + } + } + } + /// /// Set the login's database role membership /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/Security/SecurityService.cs b/src/Microsoft.SqlTools.ServiceLayer/Security/SecurityService.cs index 3527f1da..0597ce65 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Security/SecurityService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Security/SecurityService.cs @@ -200,7 +200,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Security var login = parameters.Login; prototype.SqlPassword = login.Password; - prototype.DefaultLanguage = login.DefaultLanguage; + if (0 != String.Compare(login.DefaultLanguage, SR.DefaultLanguagePlaceholder, StringComparison.Ordinal)) + { + prototype.DefaultLanguage = login.DefaultLanguage.Split(" - ")[1]; + } prototype.DefaultDatabase = login.DefaultDatabase; prototype.EnforcePolicy = login.EnforcePasswordPolicy; prototype.EnforceExpiration = login.EnforcePasswordPolicy ? login.EnforcePasswordExpiration : false; @@ -257,12 +260,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Security { databases[i] = dataContainer.Server.Databases[i].Name; } - string[] languages = new string[dataContainer.Server.Languages.Count]; - for (int i = 0; i < dataContainer.Server.Languages.Count; i++) - { - languages[i] = dataContainer.Server.Languages[i].Name; - } + var languageOptions = GetDefaultLanguageOptions(dataContainer); + var languageOptionsList = languageOptions.Select(FormatLanguageDisplay).ToList(); + if (parameters.IsNewObject) + { + languageOptionsList.Insert(0, SR.DefaultLanguagePlaceholder); + } + string[] languages = languageOptionsList.ToArray(); LoginPrototype prototype = parameters.IsNewObject ? new LoginPrototype(dataContainer.Server) : new LoginPrototype(dataContainer.Server, dataContainer.Server.Logins[parameters.Name]); @@ -286,7 +291,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security EnforcePasswordPolicy = prototype.EnforcePolicy, MustChangePassword = prototype.MustChange, DefaultDatabase = prototype.DefaultDatabase, - DefaultLanguage = prototype.DefaultDatabase, + DefaultLanguage = FormatLanguageDisplay(languageOptions.FirstOrDefault(o => o?.Language.Name == prototype.DefaultLanguage || o?.Language.Alias == prototype.DefaultLanguage, null)), ServerRoles = loginServerRoles.ToArray(), ConnectPermission = prototype.WindowsGrantAccess, IsEnabled = !prototype.IsDisabled, @@ -330,6 +335,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Security { await requestContext.SendResult(new object()); } + + private string FormatLanguageDisplay(LanguageDisplay? l) + { + if (l == null) return null; + return string.Format("{0} - {1}", l.Language.Alias, l.Language.Name); + } #endregion #region "User Handlers" @@ -556,7 +567,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security }); } - private void GetDefaultLanguageOptions(CDataContainer dataContainer) + private IList GetDefaultLanguageOptions(CDataContainer dataContainer) { // this.defaultLanguageComboBox.Items.Clear(); // this.defaultLanguageComboBox.Items.Add(defaultLanguagePlaceholder); @@ -574,11 +585,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Security } } - // add the language display objects to the combo box - foreach (LanguageDisplay languageDisplay in sortedLanguages.Values) + IList res = new List(); + foreach (LanguageDisplay ld in sortedLanguages.Values) { - //this.defaultLanguageComboBox.Items.Add(languageDisplay); + res.Add(ld); } + + return res; } // code needs to be ported into the useraction class