diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs
index 256f5923..0521326f 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs
@@ -22,6 +22,7 @@ using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
using Microsoft.SqlTools.ServiceLayer.Utility;
using Microsoft.SqlTools.Utility;
using System.Diagnostics;
+using System.Text.RegularExpressions;
namespace Microsoft.SqlTools.ServiceLayer.Connection
{
@@ -1060,6 +1061,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
// Register request and event handlers with the Service Host
serviceHost.SetRequestHandler(ConnectionRequest.Type, HandleConnectRequest);
serviceHost.SetRequestHandler(CancelConnectRequest.Type, HandleCancelConnectRequest);
+ serviceHost.SetRequestHandler(ChangePasswordRequest.Type, HandleChangePasswordRequest);
serviceHost.SetRequestHandler(DisconnectRequest.Type, HandleDisconnectRequest);
serviceHost.SetRequestHandler(ListDatabasesRequest.Type, HandleListDatabasesRequest);
serviceHost.SetRequestHandler(ChangeDatabaseRequest.Type, HandleChangeDatabaseRequest);
@@ -1137,6 +1139,65 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
}).ContinueWithOnFaulted(null);
}
+ ///
+ /// Handle new change password requests
+ ///
+ ///
+ ///
+ ///
+ protected async Task HandleChangePasswordRequest(
+ ChangePasswordParams changePasswordParams,
+ RequestContext requestContext)
+ {
+ Logger.Write(TraceEventType.Verbose, "HandleChangePasswordRequest");
+ PasswordChangeResponse newResponse = new PasswordChangeResponse();
+ try
+ {
+ ChangePassword(changePasswordParams);
+ newResponse.Result = true;
+ }
+ catch (Exception ex)
+ {
+ newResponse.Result = false;
+ newResponse.ErrorMessage = ex.InnerException != null ? (ex.Message + Environment.NewLine + Environment.NewLine + ex.InnerException.Message) : ex.Message;
+ newResponse.ErrorMessage = Regex.Replace(newResponse.ErrorMessage, @"\r?\nChanged database context to '\w+'\.", "");
+ newResponse.ErrorMessage = Regex.Replace(newResponse.ErrorMessage, @"\r?\nChanged language setting to \w+\.", "");
+ if (newResponse.ErrorMessage.Equals(SR.PasswordChangeEmptyPassword))
+ {
+ newResponse.ErrorMessage += Environment.NewLine + Environment.NewLine + SR.PasswordChangeEmptyPasswordRetry;
+ }
+ else if (newResponse.ErrorMessage.Contains(SR.PasswordChangeDNMReqs))
+ {
+ newResponse.ErrorMessage += Environment.NewLine + Environment.NewLine + SR.PasswordChangeDNMReqsRetry;
+ }
+ else if (newResponse.ErrorMessage.Contains(SR.PasswordChangePWCannotBeUsed))
+ {
+ newResponse.ErrorMessage += Environment.NewLine + Environment.NewLine + SR.PasswordChangePWCannotBeUsedRetry;
+ }
+ }
+ await requestContext.SendResult(newResponse);
+ }
+
+ public void ChangePassword(ChangePasswordParams changePasswordParams)
+ {
+ // Empty passwords are not valid.
+ if (string.IsNullOrEmpty(changePasswordParams.NewPassword))
+ {
+ throw new Exception(SR.PasswordChangeEmptyPassword);
+ }
+
+ // result is null if the ConnectParams was successfully validated
+ ConnectionCompleteParams result = ValidateConnectParams(changePasswordParams);
+ if (result != null)
+ {
+ throw new Exception(result.ErrorMessage, new Exception(result.Messages));
+ }
+
+ // Change the password of the connection
+ ServerConnection serverConnection = new ServerConnection(changePasswordParams.Connection.ServerName, changePasswordParams.Connection.UserName, changePasswordParams.Connection.Password);
+ serverConnection.ChangePassword(changePasswordParams.NewPassword);
+ }
+
///
/// Handle cancel connect requests
///
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/ChangePasswordParams.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/ChangePasswordParams.cs
new file mode 100644
index 00000000..4eaa7642
--- /dev/null
+++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/ChangePasswordParams.cs
@@ -0,0 +1,18 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+namespace Microsoft.SqlTools.ServiceLayer.Connection.Contracts
+{
+ ///
+ /// Parameters for the Change Password Request.
+ ///
+ public class ChangePasswordParams : ConnectParams
+ {
+ ///
+ /// The password to change the account of the connection to.
+ ///
+ public string NewPassword { get; set; }
+ }
+}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/ChangePasswordRequest.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/ChangePasswordRequest.cs
new file mode 100644
index 00000000..8bd09313
--- /dev/null
+++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/ChangePasswordRequest.cs
@@ -0,0 +1,19 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+using Microsoft.SqlTools.Hosting.Protocol.Contracts;
+
+namespace Microsoft.SqlTools.ServiceLayer.Connection.Contracts
+{
+ ///
+ /// Connect request mapping entry
+ ///
+ public class ChangePasswordRequest
+ {
+ public static readonly
+ RequestType Type =
+ RequestType.Create("connection/changepassword");
+ }
+}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/PasswordChangeResponse.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/PasswordChangeResponse.cs
new file mode 100644
index 00000000..954171d9
--- /dev/null
+++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/PasswordChangeResponse.cs
@@ -0,0 +1,23 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+namespace Microsoft.SqlTools.ServiceLayer.Connection.Contracts
+{
+ ///
+ /// Parameters to be sent back after a password change attempt.
+ ///
+ public class PasswordChangeResponse
+ {
+ ///
+ /// Status indicating if password change was successful or not.
+ ///
+ public bool Result { get; set; }
+
+ ///
+ /// Error message for the password change, if an error occured.
+ ///
+ public string? ErrorMessage { get; set; }
+ }
+}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs
index 14aff68d..070e8359 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs
@@ -61,6 +61,54 @@ namespace Microsoft.SqlTools.ServiceLayer
}
}
+ public static string PasswordChangeEmptyPassword
+ {
+ get
+ {
+ return Keys.GetString(Keys.PasswordChangeEmptyPassword);
+ }
+ }
+
+ public static string PasswordChangeEmptyPasswordRetry
+ {
+ get
+ {
+ return Keys.GetString(Keys.PasswordChangeEmptyPasswordRetry);
+ }
+ }
+
+ public static string PasswordChangeDNMReqs
+ {
+ get
+ {
+ return Keys.GetString(Keys.PasswordChangeDNMReqs);
+ }
+ }
+
+ public static string PasswordChangeDNMReqsRetry
+ {
+ get
+ {
+ return Keys.GetString(Keys.PasswordChangeDNMReqsRetry);
+ }
+ }
+
+ public static string PasswordChangePWCannotBeUsed
+ {
+ get
+ {
+ return Keys.GetString(Keys.PasswordChangePWCannotBeUsed);
+ }
+ }
+
+ public static string PasswordChangePWCannotBeUsedRetry
+ {
+ get
+ {
+ return Keys.GetString(Keys.PasswordChangePWCannotBeUsedRetry);
+ }
+ }
+
public static string ConnectionParamsValidateNullOwnerUri
{
get
@@ -10082,6 +10130,24 @@ namespace Microsoft.SqlTools.ServiceLayer
public const string ConnectionServiceConnectionCanceled = "ConnectionServiceConnectionCanceled";
+ public const string PasswordChangeEmptyPassword = "PasswordChangeEmptyPassword";
+
+
+ public const string PasswordChangeEmptyPasswordRetry = "PasswordChangeEmptyPasswordRetry";
+
+
+ public const string PasswordChangeDNMReqs = "PasswordChangeDNMReqs";
+
+
+ public const string PasswordChangeDNMReqsRetry = "PasswordChangeDNMReqsRetry";
+
+
+ public const string PasswordChangePWCannotBeUsed = "PasswordChangePWCannotBeUsed";
+
+
+ public const string PasswordChangePWCannotBeUsedRetry = "PasswordChangePWCannotBeUsedRetry";
+
+
public const string ConnectionParamsValidateNullOwnerUri = "ConnectionParamsValidateNullOwnerUri";
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx
index 8669e7ed..a5d8d954 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx
+++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx
@@ -168,6 +168,30 @@
Connection canceled
+
+ New password cannot be empty
+
+
+
+ Press OK to input a new password that is not empty.
+
+
+
+ password does not meet operating system policy requirements
+
+
+
+ Press OK to input a new password that meets operating system policy requirements.
+
+
+
+ password cannot be used at this time
+
+
+
+ Press OK to input a different password.
+
+
OwnerUri cannot be null or empty
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings
index 7a52cb53..07abb28e 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings
+++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings
@@ -45,6 +45,20 @@ ConnectionServiceConnStringInvalidIntent(string intent) = Invalid value '{0}' fo
ConnectionServiceConnectionCanceled = Connection canceled
+### Password Change
+
+PasswordChangeEmptyPassword = New password cannot be empty
+
+PasswordChangeEmptyPasswordRetry = Press OK to input a new password that is not empty.
+
+PasswordChangeDNMReqs = password does not meet operating system policy requirements
+
+PasswordChangeDNMReqsRetry = Press OK to input a new password that meets operating system policy requirements.
+
+PasswordChangePWCannotBeUsed = password cannot be used at this time
+
+PasswordChangePWCannotBeUsedRetry = Press OK to input a different password.
+
### Connection Params Validation Errors
ConnectionParamsValidateNullOwnerUri = OwnerUri cannot be null or empty
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf
index 3de1029f..ba07576f 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf
+++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf
@@ -6505,6 +6505,36 @@ The Query Processor estimates that implementing the following index could improv
Actual CPU Cost
+
+ New password cannot be empty
+ New password cannot be empty
+
+
+
+ Press OK to input a new password that is not empty.
+ Press OK to input a new password that is not empty.
+
+
+
+ password does not meet operating system policy requirements
+ password does not meet operating system policy requirements
+
+
+
+ Press OK to input a new password that meets operating system policy requirements.
+ Press OK to input a new password that meets operating system policy requirements.
+
+
+
+ password cannot be used at this time
+ password cannot be used at this time
+
+
+
+ Press OK to input a different password.
+ Press OK to input a different password.
+
+