diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs index d066c9bc..9ee86910 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs @@ -10150,6 +10150,11 @@ namespace Microsoft.SqlTools.ServiceLayer return Keys.GetString(Keys.UnsupportedModelType, type); } + public static string ObjectNotRenamable(string urn) + { + return Keys.GetString(Keys.ObjectNotRenamable, urn); + } + [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Keys { @@ -14043,6 +14048,9 @@ namespace Microsoft.SqlTools.ServiceLayer public const string ErrorConnectionNotFound = "ErrorConnectionNotFound"; + public const string ObjectNotRenamable = "ObjectNotRenamable"; + + public const string DefaultLanguagePlaceholder = "DefaultLanguagePlaceholder"; diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx index 1f0441f6..7e90bc48 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx @@ -5386,6 +5386,11 @@ The Query Processor estimates that implementing the following index could improv The connection could not be found + + The object could not be renamed. URN: '{0}'. + . + Parameters: 0 - urn (string) + <default> diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings index d5167f94..3e8915f6 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings @@ -2443,6 +2443,7 @@ GetUserDefinedObjectsFromModelFailed = Failed to get user defined objects from m #ObjectManagement Service ErrorConnectionNotFound = The connection could not be found +ObjectNotRenamable(string urn) = The object could not be renamed. URN: '{0}'. ############################################################################ # Security Service diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf index c29b7598..4a53a51e 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf +++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf @@ -6576,6 +6576,12 @@ The Query Processor estimates that implementing the following index could improv Reset password for the login while unlocking. + + The object could not be renamed. URN: '{0}'. + The object could not be renamed. URN: '{0}'. + . + Parameters: 0 - urn (string) + \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/Contracts/DropRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/Contracts/DropRequest.cs new file mode 100644 index 00000000..83bb70eb --- /dev/null +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/Contracts/DropRequest.cs @@ -0,0 +1,32 @@ +// +// 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.SqlTools.Hosting.Protocol.Contracts; +using Microsoft.SqlTools.Utility; + +namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement.Contracts +{ + public class DropRequestParams : GeneralRequestDetails + { + /// + /// SFC (SMO) URN identifying the object + /// + public string ObjectUrn { get; set; } + /// + /// Connection uri + /// + public string ConnectionUri { get; set; } + /// + /// Whether to throw an error if the object does not exist. The default value is false. + /// + public bool ThrowIfNotExist { get; set; } = false; + } + + public class DropRequest + { + public static readonly RequestType Type = RequestType.Create("objectManagement/drop"); + } +} \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectManagementService.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectManagementService.cs index 68f7653b..2d8da93b 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectManagementService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectManagement/ObjectManagementService.cs @@ -11,7 +11,9 @@ using Microsoft.SqlServer.Management.Sdk.Sfc; using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlTools.Hosting.Protocol; using Microsoft.SqlTools.ServiceLayer.Connection; +using Microsoft.SqlTools.ServiceLayer.Management; using Microsoft.SqlTools.ServiceLayer.ObjectManagement.Contracts; +using Microsoft.SqlTools.ServiceLayer.Utility; using Microsoft.SqlTools.Utility; namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement @@ -48,6 +50,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement { this.serviceHost = serviceHost; this.serviceHost.SetRequestHandler(RenameRequest.Type, HandleRenameRequest, true); + this.serviceHost.SetRequestHandler(DropRequest.Type, HandleDropRequest, true); } /// @@ -58,40 +61,74 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement /// internal async Task HandleRenameRequest(RenameRequestParams requestParams, RequestContext requestContext) { - Logger.Verbose("Handle Request in HandleProcessRenameEditRequest()"); - ConnectionInfo connInfo; - - if (ConnectionServiceInstance.TryFindConnection( - requestParams.ConnectionUri, - out connInfo)) + Logger.Verbose("Handle Request in HandleRenameRequest()"); + ExecuteActionOnObject(requestParams.ConnectionUri, requestParams.ObjectUrn, (dbObject) => { - ServerConnection serverConnection = ConnectionService.OpenServerConnection(connInfo, ObjectManagementServiceApplicationName); - using (serverConnection.SqlConnectionObject) + var renamable = dbObject as IRenamable; + if (renamable != null) { - IRenamable renameObject = this.GetRenamable(requestParams, serverConnection); - renameObject.Rename(requestParams.NewName); + renamable.Rename(requestParams.NewName); } - } - else - { - Logger.Error($"The connection {requestParams.ConnectionUri} could not be found."); - throw new Exception(SR.ErrorConnectionNotFound); - } - + else + { + throw new Exception(SR.ObjectNotRenamable(requestParams.ObjectUrn)); + } + }); await requestContext.SendResult(true); } /// - /// Method to get the sql object, which should be renamed + /// Method to handle the delete object request /// - /// parameters which are required for the rename operation - /// the server connection on the server to search for the sqlobject - /// the sql object if implements the interface IRenamable, so they can be renamed - private IRenamable GetRenamable(RenameRequestParams requestParams, ServerConnection connection) + /// parameters which are needed to execute deletion operation + /// Request Context + /// + internal async Task HandleDropRequest(DropRequestParams requestParams, RequestContext requestContext) { - Server server = new Server(connection); - SqlSmoObject dbObject = server.GetSmoObject(new Urn(requestParams.ObjectUrn)); - return (IRenamable)dbObject; + Logger.Verbose("Handle Request in HandleDeleteRequest()"); + ConnectionInfo connectionInfo = this.GetConnectionInfo(requestParams.ConnectionUri); + using (CDataContainer dataContainer = CDataContainer.CreateDataContainer(connectionInfo, databaseExists: true)) + { + try + { + dataContainer.SqlDialogSubject = dataContainer.Server?.GetSmoObject(requestParams.ObjectUrn); + DatabaseUtils.DoDropObject(dataContainer); + } + catch (FailedOperationException ex) + { + if (ex.InnerException is MissingObjectException && requestParams.ThrowIfNotExist) + { + throw; + } + } + } + await requestContext.SendResult(true); + } + + private ConnectionInfo GetConnectionInfo(string connectionUri) + { + ConnectionInfo connInfo; + if (ConnectionServiceInstance.TryFindConnection(connectionUri, out connInfo)) + { + return connInfo; + } + else + { + Logger.Error($"The connection with URI '{connectionUri}' could not be found."); + throw new Exception(SR.ErrorConnectionNotFound); + } + } + + private void ExecuteActionOnObject(string connectionUri, string objectUrn, Action action) + { + ConnectionInfo connInfo = this.GetConnectionInfo(connectionUri); + ServerConnection serverConnection = ConnectionService.OpenServerConnection(connInfo, ObjectManagementServiceApplicationName); + using (serverConnection.SqlConnectionObject) + { + Server server = new Server(serverConnection); + SqlSmoObject dbObject = server.GetSmoObject(new Urn(objectUrn)); + action(dbObject); + } } } } \ No newline at end of file diff --git a/src/Microsoft.SqlTools.ServiceLayer/Security/Contracts/LoginRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/Security/Contracts/LoginRequest.cs index 6f93f4e6..6d80867d 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Security/Contracts/LoginRequest.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Security/Contracts/LoginRequest.cs @@ -32,29 +32,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Security.Contracts RequestType.Create("objectManagement/createLogin"); } - /// - /// Delete Login params - /// - public class DeleteLoginParams - { - public string ConnectionUri { get; set; } - - public string Name { get; set; } - } - - /// - /// Delete Login request type - /// - public class DeleteLoginRequest - { - /// - /// Request definition - /// - public static readonly - RequestType Type = - RequestType.Create("objectManagement/deleteLogin"); - } - /// /// Update Login params /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/Security/Contracts/UserRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/Security/Contracts/UserRequest.cs index ba993f4c..2de3dc86 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Security/Contracts/UserRequest.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Security/Contracts/UserRequest.cs @@ -89,31 +89,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Security.Contracts RequestType.Create("objectManagement/updateUser"); } - /// - /// Delete User params - /// - public class DeleteUserParams - { - public string? ConnectionUri { get; set; } - - public string? Database { get; set; } - - public string? Name { get; set; } - } - - /// - /// Delete User request type - /// - public class DeleteUserRequest - { - /// - /// Request definition - /// - public static readonly - RequestType Type = - RequestType.Create("objectManagement/deleteUser"); - } - /// /// Update User params /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/Security/SecurityService.cs b/src/Microsoft.SqlTools.ServiceLayer/Security/SecurityService.cs index 2f2d7ce6..c7109d83 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Security/SecurityService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Security/SecurityService.cs @@ -88,13 +88,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Security // Credential request handlers this.ServiceHost.SetRequestHandler(CreateCredentialRequest.Type, HandleCreateCredentialRequest, true); this.ServiceHost.SetRequestHandler(UpdateCredentialRequest.Type, HandleUpdateCredentialRequest, true); - this.ServiceHost.SetRequestHandler(DeleteCredentialRequest.Type, HandleDeleteCredentialRequest, true); this.ServiceHost.SetRequestHandler(GetCredentialsRequest.Type, HandleGetCredentialsRequest, true); // Login request handlers this.ServiceHost.SetRequestHandler(CreateLoginRequest.Type, HandleCreateLoginRequest, true); this.ServiceHost.SetRequestHandler(UpdateLoginRequest.Type, HandleUpdateLoginRequest, true); - this.ServiceHost.SetRequestHandler(DeleteLoginRequest.Type, HandleDeleteLoginRequest, true); this.ServiceHost.SetRequestHandler(InitializeLoginViewRequest.Type, HandleInitializeLoginViewRequest, true); this.ServiceHost.SetRequestHandler(DisposeLoginViewRequest.Type, HandleDisposeLoginViewRequest, true); @@ -102,12 +100,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Security this.ServiceHost.SetRequestHandler(InitializeUserViewRequest.Type, this.userServiceHandler.HandleInitializeUserViewRequest, true); this.ServiceHost.SetRequestHandler(CreateUserRequest.Type, this.userServiceHandler.HandleCreateUserRequest, true); this.ServiceHost.SetRequestHandler(UpdateUserRequest.Type, this.userServiceHandler.HandleUpdateUserRequest, true); - this.ServiceHost.SetRequestHandler(DeleteUserRequest.Type, this.userServiceHandler.HandleDeleteUserRequest, true); this.ServiceHost.SetRequestHandler(DisposeUserViewRequest.Type, this.userServiceHandler.HandleDisposeUserViewRequest, true); } - #region "Login Handlers" + #region "Login Handlers" /// /// Handle request to create a login @@ -161,31 +158,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Security await requestContext.SendResult(new object()); } - /// - /// Handle request to delete a credential - /// - internal async Task HandleDeleteLoginRequest(DeleteLoginParams parameters, RequestContext requestContext) - { - ConnectionInfo connInfo; - ConnectionServiceInstance.TryFindConnection(parameters.ConnectionUri, out connInfo); - if (connInfo == null) - { - throw new ArgumentException("Invalid ConnectionUri"); - } - - CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true); - Login login = dataContainer.Server?.Logins[parameters.Name]; - - dataContainer.SqlDialogSubject = login; - DatabaseUtils.DoDropObject(dataContainer); - - await requestContext.SendResult(new ResultStatus() - { - Success = true, - ErrorMessage = string.Empty - }); - } - internal async Task HandleUpdateLoginRequest(UpdateLoginParams parameters, RequestContext requestContext) { ConnectionInfo connInfo; @@ -418,24 +390,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Security }); } - /// - /// Handle request to delete a credential - /// - internal async Task HandleDeleteCredentialRequest(DeleteCredentialParams parameters, RequestContext requestContext) - { - var result = await ConfigureCredential(parameters.OwnerUri, - parameters.Credential, - ConfigAction.Drop, - RunType.RunNow); - - await requestContext.SendResult(new ResultStatus() - { - Success = result.Item1, - ErrorMessage = result.Item2 - }); - } - - /// /// Handle request to get all credentials /// diff --git a/src/Microsoft.SqlTools.ServiceLayer/Security/UserActions.cs b/src/Microsoft.SqlTools.ServiceLayer/Security/UserActions.cs index f603a3aa..4014270e 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Security/UserActions.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Security/UserActions.cs @@ -37,7 +37,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security private ConnectionService? connectionService; private Dictionary contextIdToViewState = new Dictionary(); - + /// /// Internal for testing purposes only /// @@ -122,8 +122,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Security } UserPrototypeFactory userPrototypeFactory = UserPrototypeFactory.GetInstance(dataContainer, userInfo, originalData: null); - UserPrototype currentUserPrototype = userPrototypeFactory.GetUserPrototype(ExhaustiveUserTypes.LoginMappedUser); - + UserPrototype currentUserPrototype = userPrototypeFactory.GetUserPrototype(ExhaustiveUserTypes.LoginMappedUser); + IUserPrototypeWithDefaultLanguage defaultLanguagePrototype = currentUserPrototype as IUserPrototypeWithDefaultLanguage; string? defaultLanguageAlias = null; if (defaultLanguagePrototype != null && defaultLanguagePrototype.IsDefaultLanguageSupported) @@ -209,7 +209,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security }; this.contextIdToViewState.Add( - parameters.ContextId, + parameters.ContextId, new UserViewState(parameters.Database, currentUserPrototype.CurrentState)); await requestContext.SendResult(userViewInfo); @@ -282,42 +282,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Security }); } - /// - /// Handle request to delete a user - /// - internal async Task HandleDeleteUserRequest(DeleteUserParams parameters, RequestContext requestContext) - { - ConnectionInfo connInfo; - ConnectionServiceInstance.TryFindConnection(parameters.ConnectionUri, out connInfo); - if (connInfo == null) - { - throw new ArgumentException("Invalid ConnectionUri"); - } - - if (string.IsNullOrWhiteSpace(parameters.Name) || string.IsNullOrWhiteSpace(parameters.Database)) - { - throw new ArgumentException("Invalid null parameter"); - } - - CDataContainer dataContainer = CDataContainer.CreateDataContainer(connInfo, databaseExists: true); - string dbUrn = "Server/Database[@Name='" + Urn.EscapeString(parameters.Database) + "']"; - Database? parent = dataContainer.Server.GetSmoObject(new Urn(dbUrn)) as Database; - User user = parent.Users[parameters.Name]; - dataContainer.SqlDialogSubject = user; - - CheckForSchemaOwnerships(parent, user); - DatabaseUtils.DoDropObject(dataContainer); - - await requestContext.SendResult(new ResultStatus() - { - Success = true, - ErrorMessage = string.Empty - }); - } - internal async Task HandleDisposeUserViewRequest(DisposeUserViewRequestParams parameters, RequestContext requestContext) { - this.ConnectionServiceInstance.Disconnect(new DisconnectParams(){ + this.ConnectionServiceInstance.Disconnect(new DisconnectParams() + { OwnerUri = parameters.ContextId, Type = null }); @@ -335,8 +303,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Security } internal CDataContainer CreateUserDataContainer( - ConnectionInfo connInfo, - UserInfo? user, + ConnectionInfo connInfo, + UserInfo? user, ConfigAction configAction, string databaseName) { @@ -344,7 +312,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security var connectionInfoWithConnection = new SqlConnectionInfoWithConnection(); connectionInfoWithConnection.ServerConnection = serverConnection; - string urn = (configAction == ConfigAction.Update && user != null) + string urn = (configAction == ConfigAction.Update && user != null) ? string.Format(System.Globalization.CultureInfo.InvariantCulture, "Server/Database[@Name='{0}']/User[@Name='{1}']", Urn.EscapeString(databaseName), @@ -361,7 +329,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security containerXml.AddProperty("itemtype", "User"); } - XmlDocument xmlDoc = containerXml.GenerateXmlDocument(); + XmlDocument xmlDoc = containerXml.GenerateXmlDocument(); return CDataContainer.CreateDataContainer(connectionInfoWithConnection, xmlDoc); } @@ -393,30 +361,18 @@ namespace Microsoft.SqlTools.ServiceLayer.Security return new Tuple(true, string.Empty); } - - private void CheckForSchemaOwnerships(Database parentDb, User existingUser) - { - foreach (Schema sch in parentDb.Schemas) - { - var comparer = parentDb.GetStringComparer(); - if (comparer.Compare(sch.Owner, existingUser.Name) == 0) - { - throw new ApplicationException("Cannot drop user since it owns a schema"); - } - } - } } internal class UserActions : ManagementActionBase { -#region Variables + #region Variables //private UserPrototypeData userData; private UserPrototype userPrototype; private UserInfo? user; private ConfigAction configAction; -#endregion + #endregion -#region Constructors / Dispose + #region Constructors / Dispose /// /// required when loading from Object Explorer context /// @@ -442,7 +398,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security // base.Dispose(disposing); // } -#endregion + #endregion /// /// called on background thread by the framework to execute the action @@ -462,7 +418,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Security this.userPrototype.ApplyChanges(); } } - + private UserPrototype InitUserPrototype(CDataContainer dataContainer, UserInfo user, UserPrototypeData? originalData) { ExhaustiveUserTypes currentUserType; @@ -485,8 +441,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Security dataContainer.Server.GetSmoObject(dataContainer.ObjectUrn) as User); } - UserPrototype currentUserPrototype = userPrototypeFactory.GetUserPrototype(currentUserType); - return currentUserPrototype; + UserPrototype currentUserPrototype = userPrototypeFactory.GetUserPrototype(currentUserType); + return currentUserPrototype; } private ExhaustiveUserTypes GetCurrentUserTypeForExistingUser(User? user) @@ -503,25 +459,20 @@ namespace Microsoft.SqlTools.ServiceLayer.Security { if (user.AuthenticationType == AuthenticationType.Windows) { - return ExhaustiveUserTypes.WindowsUser; + return ExhaustiveUserTypes.WindowsUser; } else if (user.AuthenticationType == AuthenticationType.Database) { return ExhaustiveUserTypes.SqlUserWithPassword; } } - return ExhaustiveUserTypes.LoginMappedUser; - case UserType.NoLogin: return ExhaustiveUserTypes.SqlUserWithoutLogin; - case UserType.Certificate: return ExhaustiveUserTypes.CertificateMappedUser; - case UserType.AsymmetricKey: return ExhaustiveUserTypes.AsymmetricKeyMappedUser; - default: return ExhaustiveUserTypes.Unknown; } diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/CredentialTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/CredentialTests.cs index 46da1a4f..87e1ac2d 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/CredentialTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/CredentialTests.cs @@ -30,13 +30,13 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath); var service = new SecurityService(); var credential = SecurityTestUtils.GetTestCredentialInfo(); - await SecurityTestUtils.DeleteCredential(service, connectionResult, credential); + await SecurityTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, SecurityTestUtils.GetCredentialURN(credential.Name)); // test await SecurityTestUtils.CreateCredential(service, connectionResult, credential); // cleanup - await SecurityTestUtils.DeleteCredential(service, connectionResult, credential); + await SecurityTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, SecurityTestUtils.GetCredentialURN(credential.Name)); } } @@ -52,14 +52,14 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath); var service = new SecurityService(); var credential = SecurityTestUtils.GetTestCredentialInfo(); - await SecurityTestUtils.DeleteCredential(service, connectionResult, credential); + await SecurityTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, SecurityTestUtils.GetCredentialURN(credential.Name)); await SecurityTestUtils.CreateCredential(service, connectionResult, credential); // test await SecurityTestUtils.UpdateCredential(service, connectionResult, credential); // cleanup - await SecurityTestUtils.DeleteCredential(service, connectionResult, credential); + await SecurityTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, SecurityTestUtils.GetCredentialURN(credential.Name)); } } @@ -75,11 +75,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath); var service = new SecurityService(); var credential = SecurityTestUtils.GetTestCredentialInfo(); - await SecurityTestUtils.DeleteCredential(service, connectionResult, credential); + await SecurityTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, SecurityTestUtils.GetCredentialURN(credential.Name)); await SecurityTestUtils.CreateCredential(service, connectionResult, credential); // test - await SecurityTestUtils.DeleteCredential(service, connectionResult, credential); + await SecurityTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, SecurityTestUtils.GetCredentialURN(credential.Name)); } } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/LoginTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/LoginTests.cs index 1bea88b3..0068b4d1 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/LoginTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/LoginTests.cs @@ -58,19 +58,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security await service.HandleInitializeLoginViewRequest(initializeLoginViewRequestParams, initializeLoginViewContext.Object); await service.HandleCreateLoginRequest(loginParams, createLoginContext.Object); - // cleanup created login - var deleteParams = new DeleteLoginParams - { - ConnectionUri = connectionResult.ConnectionInfo.OwnerUri, - Name = loginParams.Login.Name - }; - - var deleteContext = new Mock>(); - deleteContext.Setup(x => x.SendResult(It.IsAny())) - .Returns(Task.FromResult(new object())); - - // call the create login method - await service.HandleDeleteLoginRequest(deleteParams, deleteContext.Object); + await SecurityTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, SecurityTestUtils.GetLoginURN(loginParams.Login.Name)); } } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/SecurityTestUtils.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/SecurityTestUtils.cs index 5de6d5c0..b6090787 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/SecurityTestUtils.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/SecurityTestUtils.cs @@ -8,6 +8,8 @@ using System; using System.Threading.Tasks; using Microsoft.SqlTools.Hosting.Protocol; +using Microsoft.SqlTools.ServiceLayer.ObjectManagement; +using Microsoft.SqlTools.ServiceLayer.ObjectManagement.Contracts; using Microsoft.SqlTools.ServiceLayer.Security; using Microsoft.SqlTools.ServiceLayer.Security.Contracts; using Microsoft.SqlTools.ServiceLayer.Utility; @@ -21,23 +23,38 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security public static string TestCredentialName = "Current User"; internal static string GetCurrentUserIdentity() - { + { return string.Format(@"{0}\{1}", Environment.UserDomainName, Environment.UserName); } + internal static string GetLoginURN(string name) + { + return string.Format("Server/Login[@Name='{0}']", name); + } + + internal static string GetUserURN(string database, string name) + { + return string.Format("Server/Database[@Name='{0}']/User[@Name='{1}']", database, name); + } + + internal static string GetCredentialURN(string name) + { + return string.Format("Server/Credential[@Name = '{0}']", name); + } + internal static LoginInfo GetTestLoginInfo() { return new LoginInfo() { - Name = "TestLoginName_" + new Random().NextInt64(10000000,90000000).ToString(), - AuthenticationType= LoginAuthenticationType.Sql, + Name = "TestLoginName_" + new Random().NextInt64(10000000, 90000000).ToString(), + AuthenticationType = LoginAuthenticationType.Sql, WindowsGrantAccess = true, MustChangePassword = false, IsEnabled = false, IsLockedOut = false, EnforcePasswordPolicy = false, EnforcePasswordExpiration = false, - Password = "placeholder", + Password = "placeholder", OldPassword = "placeholder", DefaultLanguage = "English - us_english", DefaultDatabase = "master" @@ -49,7 +66,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security return new UserInfo() { Type = DatabaseUserType.WithLogin, - Name = "TestUserName_" + new Random().NextInt64(10000000,90000000).ToString(), + Name = "TestUserName_" + new Random().NextInt64(10000000, 90000000).ToString(), LoginName = loginName, Password = "placeholder", DefaultSchema = "dbo", @@ -67,7 +84,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security } internal static async Task CreateCredential( - SecurityService service, + SecurityService service, TestConnectionResult connectionResult, CredentialInfo credential) { @@ -81,7 +98,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security } internal static async Task UpdateCredential( - SecurityService service, + SecurityService service, TestConnectionResult connectionResult, CredentialInfo credential) { @@ -94,25 +111,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security context.VerifyAll(); } - internal static async Task DeleteCredential( - SecurityService service, - TestConnectionResult connectionResult, - CredentialInfo credential) - { - var context = new Mock>(); - await service.HandleDeleteCredentialRequest(new DeleteCredentialParams - { - OwnerUri = connectionResult.ConnectionInfo.OwnerUri, - Credential = credential - }, context.Object); - context.VerifyAll(); - } - public static async Task SetupCredential(TestConnectionResult connectionResult) { var service = new SecurityService(); var credential = SecurityTestUtils.GetTestCredentialInfo(); - await SecurityTestUtils.DeleteCredential(service, connectionResult, credential); + await SecurityTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, SecurityTestUtils.GetCredentialURN(credential.Name)); await SecurityTestUtils.CreateCredential(service, connectionResult, credential); return credential; } @@ -122,7 +125,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security CredentialInfo credential) { var service = new SecurityService(); - await SecurityTestUtils.DeleteCredential(service, connectionResult, credential); + await SecurityTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, SecurityTestUtils.GetCredentialURN(credential.Name)); } internal static async Task CreateLogin(SecurityService service, TestConnectionResult connectionResult) @@ -155,26 +158,9 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security return loginParams.Login; } - internal static async Task DeleteLogin(SecurityService service, TestConnectionResult connectionResult, LoginInfo login) - { - // cleanup created login - var deleteParams = new DeleteLoginParams - { - ConnectionUri = connectionResult.ConnectionInfo.OwnerUri, - Name = login.Name - }; - - var deleteContext = new Mock>(); - deleteContext.Setup(x => x.SendResult(It.IsAny())) - .Returns(Task.FromResult(new object())); - - // call the create login method - await service.HandleDeleteLoginRequest(deleteParams, deleteContext.Object); - } - internal static async Task CreateUser( - UserServiceHandlerImpl service, - TestConnectionResult connectionResult, + UserServiceHandlerImpl service, + TestConnectionResult connectionResult, LoginInfo login) { string contextId = System.Guid.NewGuid().ToString(); @@ -220,12 +206,12 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security await service.HandleDisposeUserViewRequest(disposeViewRequestParams, disposeUserViewContext.Object); - return userParams.User; + return userParams.User; } internal static async Task UpdateUser( - UserServiceHandlerImpl service, - TestConnectionResult connectionResult, + UserServiceHandlerImpl service, + TestConnectionResult connectionResult, UserInfo user) { string contextId = System.Guid.NewGuid().ToString(); @@ -257,7 +243,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security // verify the result updateUserContext.Verify(x => x.SendResult(It.Is(p => p.Success))); - var disposeViewRequestParams = new DisposeUserViewRequestParams + var disposeViewRequestParams = new DisposeUserViewRequestParams { ContextId = contextId }; @@ -271,24 +257,20 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security return updateParams.User; } - internal static async Task DeleteUser(UserServiceHandlerImpl service, TestConnectionResult connectionResult, UserInfo user) + internal static async Task DropObject(string connectionUri, string objectUrn) { - // cleanup created user - var deleteParams = new DeleteUserParams + ObjectManagementService objectManagementService = new ObjectManagementService(); + var dropParams = new DropRequestParams { - ConnectionUri = connectionResult.ConnectionInfo.OwnerUri, - Name = user.Name, - Database = connectionResult.ConnectionInfo.ConnectionDetails.DatabaseName + ConnectionUri = connectionUri, + ObjectUrn = objectUrn }; - var deleteContext = new Mock>(); - deleteContext.Setup(x => x.SendResult(It.IsAny())) - .Returns(Task.FromResult(new object())); + var dropRequestContext = new Mock>(); + dropRequestContext.Setup(x => x.SendResult(It.IsAny())) + .Returns(Task.FromResult(true)); - // call the create user method - await service.HandleDeleteUserRequest(deleteParams, deleteContext.Object); - - deleteContext.Verify(x => x.SendResult(It.Is(p => p.Success))); - } + await objectManagementService.HandleDropRequest(dropParams, dropRequestContext.Object); + } } } diff --git a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/UserTests.cs b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/UserTests.cs index b6871c87..8427ae07 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/UserTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.IntegrationTests/Security/UserTests.cs @@ -28,14 +28,14 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security SecurityService service = new SecurityService(); UserServiceHandlerImpl userService = new UserServiceHandlerImpl(); var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", queryTempFile.FilePath); - + var login = await SecurityTestUtils.CreateLogin(service, connectionResult); var user = await SecurityTestUtils.CreateUser(userService, connectionResult, login); - await SecurityTestUtils.DeleteUser(userService, connectionResult, user); + await SecurityTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, SecurityTestUtils.GetUserURN(connectionResult.ConnectionInfo.ConnectionDetails.DatabaseName, user.Name)); - await SecurityTestUtils.DeleteLogin(service, connectionResult, login); + await SecurityTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, SecurityTestUtils.GetLoginURN(login.Name)); } } @@ -58,9 +58,9 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Security await SecurityTestUtils.UpdateUser(userService, connectionResult, user); - await SecurityTestUtils.DeleteUser(userService, connectionResult, user); + await SecurityTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, SecurityTestUtils.GetUserURN(connectionResult.ConnectionInfo.ConnectionDetails.DatabaseName, user.Name)); - await SecurityTestUtils.DeleteLogin(service, connectionResult, login); + await SecurityTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, SecurityTestUtils.GetLoginURN(login.Name)); } } }