mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-14 01:25:40 -05:00
Enable support for Windows users (#1957)
* WIP * Update for Windows user
This commit is contained in:
@@ -60,6 +60,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
/// </summary>
|
||||
internal async Task HandleInitializeUserViewRequest(InitializeUserViewParams parameters, RequestContext<UserViewInfo> requestContext)
|
||||
{
|
||||
// check input parameters
|
||||
if (string.IsNullOrWhiteSpace(parameters.Database))
|
||||
{
|
||||
throw new ArgumentNullException("parameters.Database");
|
||||
@@ -70,13 +71,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
throw new ArgumentNullException("parameters.ContextId");
|
||||
}
|
||||
|
||||
// open a connection for running the user dialog and associated task
|
||||
ConnectionInfo originalConnInfo;
|
||||
ConnectionServiceInstance.TryFindConnection(parameters.ConnectionUri, out originalConnInfo);
|
||||
if (originalConnInfo == null)
|
||||
{
|
||||
throw new ArgumentException("Invalid connection URI '{0}'", parameters.ConnectionUri);
|
||||
}
|
||||
|
||||
string originalDatabaseName = originalConnInfo.ConnectionDetails.DatabaseName;
|
||||
try
|
||||
{
|
||||
@@ -93,26 +94,22 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
{
|
||||
originalConnInfo.ConnectionDetails.DatabaseName = originalDatabaseName;
|
||||
}
|
||||
|
||||
ConnectionInfo connInfo;
|
||||
this.ConnectionServiceInstance.TryFindConnection(parameters.ContextId, out connInfo);
|
||||
CDataContainer dataContainer = CreateUserDataContainer(connInfo, null, ConfigAction.Create, parameters.Database);
|
||||
|
||||
// create a default user data context and database object
|
||||
CDataContainer dataContainer = CreateUserDataContainer(connInfo, null, ConfigAction.Create, parameters.Database);
|
||||
string databaseUrn = string.Format(System.Globalization.CultureInfo.InvariantCulture,
|
||||
"Server/Database[@Name='{0}']", Urn.EscapeString(parameters.Database));
|
||||
Database? parentDb = dataContainer.Server.GetSmoObject(databaseUrn) as Database;
|
||||
|
||||
// if viewing an exisitng user then populate some properties
|
||||
UserInfo? userInfo = null;
|
||||
ExhaustiveUserTypes userType = ExhaustiveUserTypes.LoginMappedUser;
|
||||
if (!parameters.IsNewObject)
|
||||
{
|
||||
User? existingUser = null;
|
||||
string databaseUrn = string.Format(System.Globalization.CultureInfo.InvariantCulture,
|
||||
"Server/Database[@Name='{0}']",
|
||||
Urn.EscapeString(parameters.Database));
|
||||
Database? parentDb = dataContainer.Server.GetSmoObject(databaseUrn) as Database;
|
||||
existingUser = dataContainer.Server.Databases[parentDb.Name].Users[parameters.Name];
|
||||
|
||||
if (string.IsNullOrWhiteSpace(existingUser.Login))
|
||||
{
|
||||
throw new ApplicationException("Only 'User with Login' user type supported");
|
||||
}
|
||||
|
||||
User? existingUser = dataContainer.Server.Databases[parentDb.Name].Users[parameters.Name];
|
||||
userType = UserActions.GetCurrentUserTypeForExistingUser(existingUser);
|
||||
userInfo = new UserInfo()
|
||||
{
|
||||
Name = parameters.Name,
|
||||
@@ -121,9 +118,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
};
|
||||
}
|
||||
|
||||
UserPrototypeFactory userPrototypeFactory = UserPrototypeFactory.GetInstance(dataContainer, userInfo, originalData: null);
|
||||
UserPrototype currentUserPrototype = userPrototypeFactory.GetUserPrototype(ExhaustiveUserTypes.LoginMappedUser);
|
||||
// generate a user prototype
|
||||
UserPrototype currentUserPrototype = UserPrototypeFactory.GetUserPrototype(dataContainer, userInfo, originalData: null, userType);
|
||||
|
||||
// get the default language if available
|
||||
IUserPrototypeWithDefaultLanguage defaultLanguagePrototype = currentUserPrototype as IUserPrototypeWithDefaultLanguage;
|
||||
string? defaultLanguageAlias = null;
|
||||
if (defaultLanguagePrototype != null && defaultLanguagePrototype.IsDefaultLanguageSupported)
|
||||
@@ -140,12 +138,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
}
|
||||
}
|
||||
|
||||
// get the default schema if available
|
||||
string? defaultSchema = null;
|
||||
IUserPrototypeWithDefaultSchema defaultSchemaPrototype = currentUserPrototype as IUserPrototypeWithDefaultSchema;
|
||||
if (defaultSchemaPrototype != null && defaultSchemaPrototype.IsDefaultSchemaSupported)
|
||||
{
|
||||
defaultSchema = defaultSchemaPrototype.DefaultSchema;
|
||||
}
|
||||
|
||||
// IUserPrototypeWithPassword userWithPwdPrototype = currentUserPrototype as IUserPrototypeWithPassword;
|
||||
// if (userWithPwdPrototype != null && !this.DataContainer.IsNewObject)
|
||||
// {
|
||||
@@ -153,6 +153,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
// this.confirmPwdTextBox.Text = FAKE_PASSWORD;
|
||||
// }
|
||||
|
||||
// get the login name if it exists
|
||||
string? loginName = null;
|
||||
IUserPrototypeWithMappedLogin mappedLoginPrototype = currentUserPrototype as IUserPrototypeWithMappedLogin;
|
||||
if (mappedLoginPrototype != null)
|
||||
@@ -160,6 +161,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
loginName = mappedLoginPrototype.LoginName;
|
||||
}
|
||||
|
||||
// populate user's role assignments
|
||||
List<string> databaseRoles = new List<string>();
|
||||
foreach (string role in currentUserPrototype.DatabaseRoleNames)
|
||||
{
|
||||
@@ -169,6 +171,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
}
|
||||
}
|
||||
|
||||
// populate user's schema ownerships
|
||||
List<string> schemaNames = new List<string>();
|
||||
foreach (string schema in currentUserPrototype.SchemaNames)
|
||||
{
|
||||
@@ -178,12 +181,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
}
|
||||
}
|
||||
|
||||
// default to dbo schema, if there isn't already a default
|
||||
if (string.IsNullOrWhiteSpace(defaultSchema) && currentUserPrototype.SchemaNames.Contains("dbo"))
|
||||
{
|
||||
defaultSchema = "dbo";
|
||||
}
|
||||
|
||||
ServerConnection serverConnection = dataContainer.ServerConnection;
|
||||
UserViewInfo userViewInfo = new UserViewInfo()
|
||||
{
|
||||
@@ -198,7 +195,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
DatabaseRoles = databaseRoles.ToArray(),
|
||||
DefaultLanguage = defaultLanguageAlias
|
||||
},
|
||||
SupportContainedUser = false, // support for these will be added later
|
||||
SupportContainedUser = UserActions.IsParentDatabaseContained(parentDb), // support for these will be added later
|
||||
SupportWindowsAuthentication = false,
|
||||
SupportAADAuthentication = false,
|
||||
SupportSQLAuthentication = true,
|
||||
@@ -349,7 +346,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
}
|
||||
|
||||
CDataContainer dataContainer = CreateUserDataContainer(connInfo, user, configAction, databaseName);
|
||||
using (var actions = new UserActions(dataContainer, user, configAction, originalData))
|
||||
using (var actions = new UserActions(dataContainer, configAction, user, originalData))
|
||||
{
|
||||
var executionHandler = new ExecutonHandler(actions);
|
||||
executionHandler.RunNow(runType, this);
|
||||
@@ -379,8 +376,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
/// <param name="context"></param>
|
||||
public UserActions(
|
||||
CDataContainer context,
|
||||
UserInfo? user,
|
||||
ConfigAction configAction,
|
||||
UserInfo? user,
|
||||
UserPrototypeData? originalData)
|
||||
{
|
||||
this.DataContainer = context;
|
||||
@@ -401,19 +398,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// called on background thread by the framework to execute the action
|
||||
/// called by the management actions 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
|
||||
if (this.configAction != ConfigAction.Drop)
|
||||
{
|
||||
this.userPrototype.ApplyChanges();
|
||||
}
|
||||
@@ -422,30 +412,42 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
private UserPrototype InitUserPrototype(CDataContainer dataContainer, UserInfo user, UserPrototypeData? originalData)
|
||||
{
|
||||
ExhaustiveUserTypes currentUserType;
|
||||
UserPrototypeFactory userPrototypeFactory = UserPrototypeFactory.GetInstance(dataContainer, user, originalData);
|
||||
|
||||
if (dataContainer.IsNewObject)
|
||||
{
|
||||
if (dataContainer.Server != null && IsParentDatabaseContained(dataContainer.ParentUrn, dataContainer.Server))
|
||||
{
|
||||
currentUserType = ExhaustiveUserTypes.SqlUserWithPassword;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentUserType = ExhaustiveUserTypes.LoginMappedUser;
|
||||
}
|
||||
currentUserType = GetUserTypeForUserInfo(user);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentUserType = this.GetCurrentUserTypeForExistingUser(
|
||||
currentUserType = UserActions.GetCurrentUserTypeForExistingUser(
|
||||
dataContainer.Server.GetSmoObject(dataContainer.ObjectUrn) as User);
|
||||
}
|
||||
|
||||
UserPrototype currentUserPrototype = userPrototypeFactory.GetUserPrototype(currentUserType);
|
||||
return currentUserPrototype;
|
||||
UserPrototype currentUserPrototype = UserPrototypeFactory.GetUserPrototype(dataContainer, user, originalData, currentUserType);
|
||||
return currentUserPrototype;
|
||||
}
|
||||
|
||||
private ExhaustiveUserTypes GetCurrentUserTypeForExistingUser(User? user)
|
||||
private ExhaustiveUserTypes GetUserTypeForUserInfo(UserInfo user)
|
||||
{
|
||||
ExhaustiveUserTypes userType = ExhaustiveUserTypes.LoginMappedUser;
|
||||
switch (user.Type)
|
||||
{
|
||||
case DatabaseUserType.WithLogin:
|
||||
userType = ExhaustiveUserTypes.LoginMappedUser;
|
||||
break;
|
||||
case DatabaseUserType.WithWindowsGroupLogin:
|
||||
userType = ExhaustiveUserTypes.WindowsUser;
|
||||
break;
|
||||
case DatabaseUserType.Contained:
|
||||
userType = ExhaustiveUserTypes.SqlUserWithPassword;
|
||||
break;
|
||||
case DatabaseUserType.NoConnectAccess:
|
||||
userType = ExhaustiveUserTypes.SqlUserWithoutLogin;
|
||||
break;
|
||||
}
|
||||
return userType;
|
||||
}
|
||||
|
||||
internal static ExhaustiveUserTypes GetCurrentUserTypeForExistingUser(User? user)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
@@ -478,18 +480,16 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsParentDatabaseContained(Urn parentDbUrn, Server server)
|
||||
internal static bool IsParentDatabaseContained(Urn parentDbUrn, Server server)
|
||||
{
|
||||
string parentDbName = parentDbUrn.GetNameForType("Database");
|
||||
Database parentDatabase = server.Databases[parentDbName];
|
||||
return IsParentDatabaseContained(server.Databases[parentDbName]);
|
||||
}
|
||||
|
||||
if (parentDatabase.IsSupportedProperty("ContainmentType")
|
||||
&& parentDatabase.ContainmentType == ContainmentType.Partial)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
internal static bool IsParentDatabaseContained(Database parentDatabase)
|
||||
{
|
||||
return parentDatabase.IsSupportedProperty("ContainmentType")
|
||||
&& parentDatabase.ContainmentType == ContainmentType.Partial;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -763,12 +763,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
{
|
||||
base.SaveProperties(user);
|
||||
|
||||
if (!this.Exists || (user.Login != this.currentState.mappedLoginName))
|
||||
bool isValidLoginName = !string.IsNullOrWhiteSpace(this.currentState.mappedLoginName);
|
||||
bool isCreatingOrUpdatingLogin = !this.Exists || user.Login != this.currentState.mappedLoginName;
|
||||
if (isValidLoginName && isCreatingOrUpdatingLogin)
|
||||
{
|
||||
user.Login = this.currentState.mappedLoginName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class UserPrototypeForWindowsUser : UserPrototypeForSqlUserWithLogin,
|
||||
IUserPrototypeWithDefaultLanguage
|
||||
@@ -985,107 +987,47 @@ namespace Microsoft.SqlTools.ServiceLayer.Security
|
||||
|
||||
/// <summary>
|
||||
/// Used to create or return required UserPrototype objects for a user type.
|
||||
/// This factory class also helps us in maintaining a single set of current data
|
||||
/// and original data mapped to all UserPrototypes.
|
||||
///
|
||||
/// Also this UserPrototypeFactory is a Singleton object for one datacontainer object.
|
||||
/// Making it Singleton helps us in using same factory object inside other pages too.
|
||||
/// </summary>
|
||||
internal class UserPrototypeFactory
|
||||
internal static class UserPrototypeFactory
|
||||
{
|
||||
private static UserPrototypeFactory? singletonInstance;
|
||||
|
||||
private UserPrototypeData currentData;
|
||||
private UserPrototypeData originalData;
|
||||
private CDataContainer context;
|
||||
|
||||
private UserPrototype? asymmetricKeyMappedUser;
|
||||
private UserPrototype? certificateMappedUser;
|
||||
private UserPrototype? loginMappedUser;
|
||||
private UserPrototype? noLoginUser;
|
||||
private UserPrototype? sqlUserWithPassword;
|
||||
private UserPrototype? windowsUser;
|
||||
|
||||
private UserPrototype? currentPrototype;
|
||||
|
||||
public UserPrototype CurrentPrototype
|
||||
{
|
||||
get
|
||||
{
|
||||
currentPrototype ??= new UserPrototype(this.context,
|
||||
this.currentData,
|
||||
this.originalData);
|
||||
return currentPrototype;
|
||||
}
|
||||
}
|
||||
|
||||
private UserPrototypeFactory(CDataContainer context, UserInfo user, UserPrototypeData? originalData)
|
||||
{
|
||||
this.context = context;
|
||||
|
||||
this.currentData = new UserPrototypeData(this.context, user);
|
||||
this.originalData = originalData ?? this.currentData.Clone();
|
||||
}
|
||||
|
||||
public static UserPrototypeFactory GetInstance(CDataContainer context, UserInfo? user, UserPrototypeData? originalData)
|
||||
{
|
||||
if (singletonInstance != null
|
||||
&& singletonInstance.context != context)
|
||||
{
|
||||
singletonInstance = null;
|
||||
}
|
||||
|
||||
singletonInstance ??= new UserPrototypeFactory(context, user, originalData);
|
||||
|
||||
return singletonInstance;
|
||||
}
|
||||
|
||||
public UserPrototype GetUserPrototype(ExhaustiveUserTypes userType)
|
||||
public static UserPrototype GetUserPrototype(
|
||||
CDataContainer context, UserInfo? user,
|
||||
UserPrototypeData? originalData, ExhaustiveUserTypes userType)
|
||||
{
|
||||
UserPrototype currentPrototype = null;
|
||||
UserPrototypeData currentData = new UserPrototypeData(context, user);
|
||||
switch (userType)
|
||||
{
|
||||
case ExhaustiveUserTypes.AsymmetricKeyMappedUser:
|
||||
currentData.userType = UserType.AsymmetricKey;
|
||||
this.asymmetricKeyMappedUser ??= new UserPrototype(this.context, this.currentData, this.originalData);
|
||||
this.currentPrototype = asymmetricKeyMappedUser;
|
||||
currentPrototype ??= new UserPrototype(context, currentData, originalData);
|
||||
break;
|
||||
|
||||
case ExhaustiveUserTypes.CertificateMappedUser:
|
||||
currentData.userType = UserType.Certificate;
|
||||
this.certificateMappedUser ??= new UserPrototype(this.context, this.currentData, this.originalData);
|
||||
this.currentPrototype = certificateMappedUser;
|
||||
currentPrototype ??= new UserPrototype(context, currentData, originalData);
|
||||
break;
|
||||
|
||||
case ExhaustiveUserTypes.LoginMappedUser:
|
||||
currentData.userType = UserType.SqlUser;
|
||||
this.loginMappedUser ??= new UserPrototypeForSqlUserWithLogin(this.context, this.currentData, this.originalData);
|
||||
this.currentPrototype = loginMappedUser;
|
||||
currentPrototype ??= new UserPrototypeForSqlUserWithLogin(context, currentData, originalData);
|
||||
break;
|
||||
|
||||
case ExhaustiveUserTypes.SqlUserWithoutLogin:
|
||||
currentData.userType = UserType.NoLogin;
|
||||
this.noLoginUser ??= new UserPrototypeWithDefaultSchema(this.context, this.currentData, this.originalData);
|
||||
this.currentPrototype = noLoginUser;
|
||||
currentPrototype ??= new UserPrototypeWithDefaultSchema(context, currentData, originalData);
|
||||
break;
|
||||
|
||||
case ExhaustiveUserTypes.SqlUserWithPassword:
|
||||
currentData.userType = UserType.SqlUser;
|
||||
this.sqlUserWithPassword ??= new UserPrototypeForSqlUserWithPassword(this.context, this.currentData, this.originalData);
|
||||
this.currentPrototype = sqlUserWithPassword;
|
||||
currentPrototype ??= new UserPrototypeForSqlUserWithPassword(context, currentData, originalData);
|
||||
break;
|
||||
|
||||
case ExhaustiveUserTypes.WindowsUser:
|
||||
currentData.userType = UserType.SqlUser;
|
||||
this.windowsUser ??= new UserPrototypeForWindowsUser(this.context, this.currentData, this.originalData);
|
||||
this.currentPrototype = windowsUser;
|
||||
currentPrototype ??= new UserPrototypeForWindowsUser(context, currentData, originalData);
|
||||
break;
|
||||
|
||||
default:
|
||||
System.Diagnostics.Debug.Assert(false, "Unknown UserType provided.");
|
||||
this.currentPrototype = null;
|
||||
currentPrototype = null;
|
||||
break;
|
||||
}
|
||||
return this.currentPrototype;
|
||||
return currentPrototype;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,12 +61,12 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security
|
||||
};
|
||||
}
|
||||
|
||||
internal static UserInfo GetTestUserInfo(string loginName)
|
||||
internal static UserInfo GetTestUserInfo(DatabaseUserType userType, string userName = null, string loginName = null)
|
||||
{
|
||||
return new UserInfo()
|
||||
{
|
||||
Type = DatabaseUserType.WithLogin,
|
||||
Name = "TestUserName_" + new Random().NextInt64(10000000, 90000000).ToString(),
|
||||
Type = userType,
|
||||
Name = userName ?? "TestUserName_" + new Random().NextInt64(10000000, 90000000).ToString(),
|
||||
LoginName = loginName,
|
||||
Password = "placeholder",
|
||||
DefaultSchema = "dbo",
|
||||
@@ -161,7 +161,9 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security
|
||||
internal static async Task<UserInfo> CreateUser(
|
||||
UserServiceHandlerImpl service,
|
||||
TestConnectionResult connectionResult,
|
||||
LoginInfo login)
|
||||
DatabaseUserType userType,
|
||||
string userName = null,
|
||||
string loginName = null)
|
||||
{
|
||||
string contextId = System.Guid.NewGuid().ToString();
|
||||
var initializeViewRequestParams = new InitializeUserViewParams
|
||||
@@ -181,7 +183,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security
|
||||
var userParams = new CreateUserParams
|
||||
{
|
||||
ContextId = contextId,
|
||||
User = SecurityTestUtils.GetTestUserInfo(login.Name)
|
||||
User = SecurityTestUtils.GetTestUserInfo(userType, userName, loginName)
|
||||
};
|
||||
|
||||
var createUserContext = new Mock<RequestContext<CreateUserResult>>();
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
|
||||
using Microsoft.SqlTools.ServiceLayer.Security;
|
||||
using Microsoft.SqlTools.ServiceLayer.Security.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Test.Common;
|
||||
using NUnit.Framework;
|
||||
|
||||
@@ -31,7 +33,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security
|
||||
|
||||
var login = await SecurityTestUtils.CreateLogin(service, connectionResult);
|
||||
|
||||
var user = await SecurityTestUtils.CreateUser(userService, connectionResult, login);
|
||||
var user = await SecurityTestUtils.CreateUser(userService, connectionResult, DatabaseUserType.WithLogin, null, login.Name);
|
||||
|
||||
await SecurityTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, SecurityTestUtils.GetUserURN(connectionResult.ConnectionInfo.ConnectionDetails.DatabaseName, user.Name));
|
||||
|
||||
@@ -39,6 +41,29 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the basic Create User method handler
|
||||
/// </summary>
|
||||
// [Test] - Windows-only
|
||||
public async Task TestHandleCreateUserWithWindowsGroup()
|
||||
{
|
||||
using (SelfCleaningTempFile queryTempFile = new SelfCleaningTempFile())
|
||||
{
|
||||
// setup
|
||||
SecurityService service = new SecurityService();
|
||||
UserServiceHandlerImpl userService = new UserServiceHandlerImpl();
|
||||
var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath);
|
||||
|
||||
var user = await SecurityTestUtils.CreateUser(
|
||||
userService,
|
||||
connectionResult,
|
||||
DatabaseUserType.WithWindowsGroupLogin,
|
||||
$"{Environment.MachineName}\\Administrator");
|
||||
|
||||
await SecurityTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, SecurityTestUtils.GetUserURN(connectionResult.ConnectionInfo.ConnectionDetails.DatabaseName, user.Name));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the basic Update User method handler
|
||||
/// </summary>
|
||||
@@ -54,7 +79,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security
|
||||
|
||||
var login = await SecurityTestUtils.CreateLogin(service, connectionResult);
|
||||
|
||||
var user = await SecurityTestUtils.CreateUser(userService, connectionResult, login);
|
||||
var user = await SecurityTestUtils.CreateUser(userService, connectionResult, DatabaseUserType.WithLogin, null, login.Name);
|
||||
|
||||
await SecurityTestUtils.UpdateUser(userService, connectionResult, user);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user