change user type implementation (#2036)

* change user type implementation

* fix build errors
This commit is contained in:
Alan Ren
2023-05-01 10:27:00 -07:00
committed by GitHub
parent f66a203c01
commit 5dbed25c40
9 changed files with 68 additions and 82 deletions

View File

@@ -85,12 +85,20 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
UserMapping = new ServerLoginDatabaseUserMapping[0] UserMapping = new ServerLoginDatabaseUserMapping[0]
}; };
var supportedAuthTypes = new List<LoginAuthenticationType>();
supportedAuthTypes.Add(LoginAuthenticationType.Sql);
if (prototype.WindowsAuthSupported)
{
supportedAuthTypes.Add(LoginAuthenticationType.Windows);
}
if (prototype.AADAuthSupported)
{
supportedAuthTypes.Add(LoginAuthenticationType.AAD);
}
var viewInfo = new LoginViewInfo() var viewInfo = new LoginViewInfo()
{ {
ObjectInfo = loginInfo, ObjectInfo = loginInfo,
SupportWindowsAuthentication = prototype.WindowsAuthSupported, AuthenticationTypes = supportedAuthTypes.ToArray(),
SupportAADAuthentication = prototype.AADAuthSupported,
SupportSQLAuthentication = true, // SQL Auth support for login, not necessarily mean SQL Auth support for CONNECT etc.
CanEditLockedOutState = !parameters.IsNewObject && prototype.IsLockedOut, CanEditLockedOutState = !parameters.IsNewObject && prototype.IsLockedOut,
Databases = databases, Databases = databases,
Languages = languages, Languages = languages,

View File

@@ -8,9 +8,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{ {
public class LoginViewInfo : SqlObjectViewInfo public class LoginViewInfo : SqlObjectViewInfo
{ {
public bool SupportWindowsAuthentication { get; set; } public LoginAuthenticationType[] AuthenticationTypes { get; set; }
public bool SupportAADAuthentication { get; set; }
public bool SupportSQLAuthentication { get; set; }
public bool CanEditLockedOutState { get; set; } public bool CanEditLockedOutState { get; set; }
public string[] Databases; public string[] Databases;
public string[] Languages; public string[] Languages;

View File

@@ -70,23 +70,19 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
ExhaustiveUserTypes userType = ExhaustiveUserTypes.LoginMappedUser; ExhaustiveUserTypes userType = ExhaustiveUserTypes.LoginMappedUser;
switch (user.Type) switch (user.Type)
{ {
case DatabaseUserType.WithLogin: case DatabaseUserType.LoginMapped:
userType = ExhaustiveUserTypes.LoginMappedUser; userType = ExhaustiveUserTypes.LoginMappedUser;
break; break;
case DatabaseUserType.WithWindowsGroupLogin: case DatabaseUserType.WindowsUser:
userType = ExhaustiveUserTypes.WindowsUser; userType = ExhaustiveUserTypes.WindowsUser;
break; break;
case DatabaseUserType.Contained: case DatabaseUserType.SqlAuthentication:
if (user.AuthenticationType == ServerAuthenticationType.AzureActiveDirectory) userType = ExhaustiveUserTypes.SqlUserWithPassword;
{
userType = ExhaustiveUserTypes.ExternalUser;
}
else
{
userType = ExhaustiveUserTypes.SqlUserWithPassword;
}
break; break;
case DatabaseUserType.NoConnectAccess: case DatabaseUserType.AADAuthentication:
userType = ExhaustiveUserTypes.ExternalUser;
break;
case DatabaseUserType.NoLoginAccess:
userType = ExhaustiveUserTypes.SqlUserWithoutLogin; userType = ExhaustiveUserTypes.SqlUserWithoutLogin;
break; break;
} }
@@ -95,23 +91,23 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
internal static DatabaseUserType GetDatabaseUserTypeForUserType(ExhaustiveUserTypes userType) internal static DatabaseUserType GetDatabaseUserTypeForUserType(ExhaustiveUserTypes userType)
{ {
DatabaseUserType databaseUserType = DatabaseUserType.WithLogin; DatabaseUserType databaseUserType = DatabaseUserType.LoginMapped;
switch (userType) switch (userType)
{ {
case ExhaustiveUserTypes.LoginMappedUser: case ExhaustiveUserTypes.LoginMappedUser:
databaseUserType = DatabaseUserType.WithLogin; databaseUserType = DatabaseUserType.LoginMapped;
break; break;
case ExhaustiveUserTypes.WindowsUser: case ExhaustiveUserTypes.WindowsUser:
databaseUserType = DatabaseUserType.WithWindowsGroupLogin; databaseUserType = DatabaseUserType.WindowsUser;
break; break;
case ExhaustiveUserTypes.SqlUserWithPassword: case ExhaustiveUserTypes.SqlUserWithPassword:
databaseUserType = DatabaseUserType.Contained; databaseUserType = DatabaseUserType.SqlAuthentication;
break; break;
case ExhaustiveUserTypes.SqlUserWithoutLogin: case ExhaustiveUserTypes.SqlUserWithoutLogin:
databaseUserType = DatabaseUserType.NoConnectAccess; databaseUserType = DatabaseUserType.NoLoginAccess;
break; break;
case ExhaustiveUserTypes.ExternalUser: case ExhaustiveUserTypes.ExternalUser:
databaseUserType = DatabaseUserType.Contained; databaseUserType = DatabaseUserType.AADAuthentication;
break; break;
} }
return databaseUserType; return databaseUserType;

View File

@@ -142,16 +142,12 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
UserType userType = UserType.SqlLogin; UserType userType = UserType.SqlLogin;
switch (userInfo.Type) switch (userInfo.Type)
{ {
case DatabaseUserType.NoConnectAccess: case DatabaseUserType.NoLoginAccess:
userType = UserType.NoLogin; userType = UserType.NoLogin;
break; break;
case DatabaseUserType.Contained: case DatabaseUserType.AADAuthentication:
if (userInfo.AuthenticationType == ServerAuthenticationType.AzureActiveDirectory) userType = UserType.External;
{
userType = UserType.External;
}
break; break;
// all the other user types are using SqlLogin
} }
return userType; return userType;
} }

View File

@@ -78,17 +78,10 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{ {
User existingUser = dataContainer.Server.GetSmoObject(parameters.ObjectUrn) as User; User existingUser = dataContainer.Server.GetSmoObject(parameters.ObjectUrn) as User;
userType = UserActions.GetCurrentUserTypeForExistingUser(existingUser); userType = UserActions.GetCurrentUserTypeForExistingUser(existingUser);
DatabaseUserType databaseUserType = UserActions.GetDatabaseUserTypeForUserType(userType);
// if contained user determine if SQL or AAD auth type
ServerAuthenticationType authenticationType =
(databaseUserType == DatabaseUserType.Contained && userType == ExhaustiveUserTypes.ExternalUser)
? ServerAuthenticationType.AzureActiveDirectory : ServerAuthenticationType.Sql;
userInfo = new UserInfo() userInfo = new UserInfo()
{ {
Type = databaseUserType, Type = UserActions.GetDatabaseUserTypeForUserType(userType),
AuthenticationType = authenticationType,
Name = existingUser.Name, Name = existingUser.Name,
LoginName = existingUser.Login, LoginName = existingUser.Login,
DefaultSchema = existingUser.DefaultSchema, DefaultSchema = existingUser.DefaultSchema,
@@ -168,12 +161,27 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
defaultLanguage = SR.DefaultLanguagePlaceholder; defaultLanguage = SR.DefaultLanguagePlaceholder;
} }
var supportedUserTypes = new List<DatabaseUserType>();
supportedUserTypes.Add(DatabaseUserType.LoginMapped);
if (currentUserPrototype.WindowsAuthSupported)
{
supportedUserTypes.Add(DatabaseUserType.WindowsUser);
}
if (supportsContainedUser)
{
supportedUserTypes.Add(DatabaseUserType.SqlAuthentication);
}
if (currentUserPrototype.AADAuthSupported)
{
supportedUserTypes.Add(DatabaseUserType.AADAuthentication);
}
supportedUserTypes.Add(DatabaseUserType.NoLoginAccess);
UserViewInfo userViewInfo = new UserViewInfo() UserViewInfo userViewInfo = new UserViewInfo()
{ {
ObjectInfo = new UserInfo() ObjectInfo = new UserInfo()
{ {
Type = userInfo?.Type ?? DatabaseUserType.WithLogin, Type = userInfo?.Type ?? DatabaseUserType.LoginMapped,
AuthenticationType = userInfo?.AuthenticationType ?? ServerAuthenticationType.Sql,
Name = currentUserPrototype.Name, Name = currentUserPrototype.Name,
LoginName = loginName, LoginName = loginName,
Password = password, Password = password,
@@ -182,10 +190,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
DatabaseRoles = databaseRoles.ToArray(), DatabaseRoles = databaseRoles.ToArray(),
DefaultLanguage = defaultLanguage DefaultLanguage = defaultLanguage
}, },
SupportContainedUser = supportsContainedUser, UserTypes = supportedUserTypes.ToArray(),
SupportWindowsAuthentication = false,
SupportAADAuthentication = currentUserPrototype.AADAuthSupported,
SupportSQLAuthentication = true,
Languages = languageOptionsList.ToArray(), Languages = languageOptionsList.ToArray(),
Schemas = currentUserPrototype.SchemaNames.ToArray(), Schemas = currentUserPrototype.SchemaNames.ToArray(),
Logins = DatabaseUtils.LoadSqlLogins(dataContainer.ServerConnection), Logins = DatabaseUtils.LoadSqlLogins(dataContainer.ServerConnection),
@@ -246,7 +251,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
} }
internal string ConfigureUser(ServerConnection serverConnection, UserInfo user, ConfigAction configAction, RunType runType, string databaseName, UserPrototypeData originalData) internal string ConfigureUser(ServerConnection serverConnection, UserInfo user, ConfigAction configAction, RunType runType, string databaseName, UserPrototypeData originalData)
{ {
string sqlScript = string.Empty; string sqlScript = string.Empty;
CDataContainer dataContainer = CreateUserDataContainer(serverConnection, user, configAction, databaseName); CDataContainer dataContainer = CreateUserDataContainer(serverConnection, user, configAction, databaseName);
using (var actions = new UserActions(dataContainer, configAction, user, originalData)) using (var actions = new UserActions(dataContainer, configAction, user, originalData))

View File

@@ -9,32 +9,24 @@ using Newtonsoft.Json.Converters;
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{ {
[JsonConverter(typeof(StringEnumConverter))]
public enum ServerAuthenticationType
{
[EnumMember(Value = "Windows")]
Windows,
[EnumMember(Value = "Sql")]
Sql,
[EnumMember(Value = "AAD")]
AzureActiveDirectory
}
[JsonConverter(typeof(StringEnumConverter))] [JsonConverter(typeof(StringEnumConverter))]
public enum DatabaseUserType public enum DatabaseUserType
{ {
// User with a server level login. // Mapped to a server login.
[EnumMember(Value = "WithLogin")] [EnumMember(Value = "LoginMapped")]
WithLogin, LoginMapped,
// User based on a Windows user/group that has no login, but can connect to the Database Engine through membership in a Windows group. // Mapped to a Windows user or group.
[EnumMember(Value = "WithWindowsGroupLogin")] [EnumMember(Value = "WindowsUser")]
WithWindowsGroupLogin, WindowsUser,
// Contained user, authentication is done within the database. // Authenticate with password.
[EnumMember(Value = "Contained")] [EnumMember(Value = "SqlAuthentication")]
Contained, SqlAuthentication,
// Authenticate with Azure Active Directory.
[EnumMember(Value = "AADAuthentication")]
AADAuthentication,
// User that cannot authenticate. // User that cannot authenticate.
[EnumMember(Value = "NoConnectAccess")] [EnumMember(Value = "NoLoginAccess")]
NoConnectAccess NoLoginAccess
} }
@@ -55,8 +47,6 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
public string[]? DatabaseRoles { get; set; } public string[]? DatabaseRoles { get; set; }
public ServerAuthenticationType AuthenticationType { get; set; }
public string? DefaultLanguage { get; set; } public string? DefaultLanguage { get; set; }
} }
} }

View File

@@ -10,13 +10,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
/// </summary> /// </summary>
public class UserViewInfo : SqlObjectViewInfo public class UserViewInfo : SqlObjectViewInfo
{ {
public bool SupportContainedUser { get; set; } public DatabaseUserType[]? UserTypes { get; set; }
public bool SupportWindowsAuthentication { get; set; }
public bool SupportAADAuthentication { get; set; }
public bool SupportSQLAuthentication { get; set; }
public string[]? Languages { get; set; } public string[]? Languages { get; set; }

View File

@@ -80,7 +80,6 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectManagement
return new UserInfo() return new UserInfo()
{ {
Type = userType, Type = userType,
AuthenticationType = ServerAuthenticationType.Sql,
Name = userName ?? "TestUserName_" + new Random().NextInt64(10000000, 90000000).ToString(), Name = userName ?? "TestUserName_" + new Random().NextInt64(10000000, 90000000).ToString(),
LoginName = loginName, LoginName = loginName,
Password = "placeholder" + new Random().NextInt64(10000000, 90000000).ToString() + "!*PLACEHOLDER", Password = "placeholder" + new Random().NextInt64(10000000, 90000000).ToString() + "!*PLACEHOLDER",

View File

@@ -28,7 +28,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectManagement
var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath); var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath);
var connectionUri = connectionResult.ConnectionInfo.OwnerUri; var connectionUri = connectionResult.ConnectionInfo.OwnerUri;
var login = await ObjectManagementTestUtils.CreateTestLogin(connectionUri); var login = await ObjectManagementTestUtils.CreateTestLogin(connectionUri);
var user = await ObjectManagementTestUtils.CreateTestUser(connectionUri, DatabaseUserType.WithLogin, null, login.Name); var user = await ObjectManagementTestUtils.CreateTestUser(connectionUri, DatabaseUserType.LoginMapped, null, login.Name);
var userUrn = ObjectManagementTestUtils.GetUserURN(connectionResult.ConnectionInfo.ConnectionDetails.DatabaseName, user.Name); var userUrn = ObjectManagementTestUtils.GetUserURN(connectionResult.ConnectionInfo.ConnectionDetails.DatabaseName, user.Name);
var parameters = ObjectManagementTestUtils.GetInitializeViewRequestParams(connectionUri, "master", false, SqlObjectType.User, "", userUrn); var parameters = ObjectManagementTestUtils.GetInitializeViewRequestParams(connectionUri, "master", false, SqlObjectType.User, "", userUrn);
await ObjectManagementTestUtils.SaveObject(parameters, user); await ObjectManagementTestUtils.SaveObject(parameters, user);
@@ -48,7 +48,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectManagement
{ {
var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath); var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath);
var connectionUri = connectionResult.ConnectionInfo.OwnerUri; var connectionUri = connectionResult.ConnectionInfo.OwnerUri;
var user = await ObjectManagementTestUtils.CreateTestUser(connectionUri, DatabaseUserType.WithWindowsGroupLogin, $"{Environment.MachineName}\\Administrator"); var user = await ObjectManagementTestUtils.CreateTestUser(connectionUri, DatabaseUserType.WindowsUser, $"{Environment.MachineName}\\Administrator");
await ObjectManagementTestUtils.DropObject(connectionUri, ObjectManagementTestUtils.GetUserURN(connectionResult.ConnectionInfo.ConnectionDetails.DatabaseName, user.Name)); await ObjectManagementTestUtils.DropObject(connectionUri, ObjectManagementTestUtils.GetUserURN(connectionResult.ConnectionInfo.ConnectionDetails.DatabaseName, user.Name));
} }
} }
@@ -64,7 +64,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectManagement
string databaseName = "CRM"; string databaseName = "CRM";
var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync(databaseName, queryTempFile.FilePath); var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync(databaseName, queryTempFile.FilePath);
var connectionUri = connectionResult.ConnectionInfo.OwnerUri; var connectionUri = connectionResult.ConnectionInfo.OwnerUri;
var user = await ObjectManagementTestUtils.CreateTestUser(connectionUri, DatabaseUserType.Contained, var user = await ObjectManagementTestUtils.CreateTestUser(connectionUri, DatabaseUserType.SqlAuthentication,
userName: null, userName: null,
loginName: null, loginName: null,
databaseName: connectionResult.ConnectionInfo.ConnectionDetails.DatabaseName); databaseName: connectionResult.ConnectionInfo.ConnectionDetails.DatabaseName);
@@ -84,7 +84,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectManagement
var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath); var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath);
var connectionUri = connectionResult.ConnectionInfo.OwnerUri; var connectionUri = connectionResult.ConnectionInfo.OwnerUri;
var login = await ObjectManagementTestUtils.CreateTestLogin(connectionUri); var login = await ObjectManagementTestUtils.CreateTestLogin(connectionUri);
var user = await ObjectManagementTestUtils.CreateTestUser(connectionUri, DatabaseUserType.WithLogin, null, login.Name); var user = await ObjectManagementTestUtils.CreateTestUser(connectionUri, DatabaseUserType.LoginMapped, null, login.Name);
var userUrn = ObjectManagementTestUtils.GetUserURN(connectionResult.ConnectionInfo.ConnectionDetails.DatabaseName, user.Name); var userUrn = ObjectManagementTestUtils.GetUserURN(connectionResult.ConnectionInfo.ConnectionDetails.DatabaseName, user.Name);
var parameters = ObjectManagementTestUtils.GetInitializeViewRequestParams(connectionUri, "master", false, SqlObjectType.User, "", userUrn); var parameters = ObjectManagementTestUtils.GetInitializeViewRequestParams(connectionUri, "master", false, SqlObjectType.User, "", userUrn);
await ObjectManagementTestUtils.ScriptObject(parameters, user); await ObjectManagementTestUtils.ScriptObject(parameters, user);