mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-21 09:35:39 -05:00
Adding windows account validation api for sql migration extensions. (#1202)
* Adding validate file share api * Making message endpoint camel case * Adding validation for windows username
This commit is contained in:
@@ -11,7 +11,6 @@ using Microsoft.SqlServer.Management.Assessment;
|
||||
using Microsoft.SqlServer.Management.Assessment.Checks;
|
||||
using Microsoft.SqlServer.Migration.Assessment.Common.Contracts.Models;
|
||||
using Microsoft.SqlServer.Migration.Assessment.Common.Engine;
|
||||
using Microsoft.SqlServer.Migration.Assessment.Common.Models;
|
||||
using Microsoft.SqlTools.Hosting.Protocol;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
@@ -19,7 +18,10 @@ using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
||||
using Microsoft.SqlTools.ServiceLayer.Migration.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.SqlAssessment;
|
||||
using Microsoft.SqlTools.ServiceLayer.SqlAssessment.Contracts;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Migration
|
||||
{
|
||||
@@ -27,9 +29,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Migration
|
||||
/// Main class for Migration Service functionality
|
||||
/// </summary>
|
||||
public sealed class MigrationService : IDisposable
|
||||
{
|
||||
{
|
||||
private static ConnectionService connectionService = null;
|
||||
|
||||
|
||||
private static readonly Lazy<MigrationService> instance = new Lazy<MigrationService>(() => new MigrationService());
|
||||
|
||||
private bool disposed;
|
||||
@@ -90,13 +92,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Migration
|
||||
{
|
||||
this.ServiceHost = serviceHost;
|
||||
this.ServiceHost.SetRequestHandler(MigrationAssessmentsRequest.Type, HandleMigrationAssessmentsRequest);
|
||||
this.ServiceHost.SetRequestHandler(ValidateWindowsAccountRequest.Type, HandleValidateWindowsAccountRequest);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle request to start a migration session
|
||||
/// </summary>
|
||||
internal async Task HandleMigrationAssessmentsRequest(
|
||||
MigrationAssessmentsParams parameters,
|
||||
MigrationAssessmentsParams parameters,
|
||||
RequestContext<MigrationAssessmentResult> requestContext)
|
||||
{
|
||||
string randomUri = Guid.NewGuid().ToString();
|
||||
@@ -141,7 +144,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Migration
|
||||
result.Items.AddRange(results);
|
||||
await requestContext.SendResult(result);
|
||||
}
|
||||
catch(Exception e){
|
||||
catch (Exception e)
|
||||
{
|
||||
await requestContext.SendError(e.ToString());
|
||||
}
|
||||
finally
|
||||
@@ -150,7 +154,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Migration
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
internal class AssessmentRequest : IAssessmentRequest
|
||||
{
|
||||
private readonly Check[] checks = null;
|
||||
@@ -182,7 +186,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Migration
|
||||
{
|
||||
DmaEngine engine = new DmaEngine(connectionString);
|
||||
var assessmentResults = await engine.GetTargetAssessmentResultsList();
|
||||
|
||||
|
||||
var result = new List<MigrationAssessmentInfo>();
|
||||
foreach (var r in assessmentResults)
|
||||
{
|
||||
@@ -194,13 +198,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Migration
|
||||
|
||||
var targetName = !string.IsNullOrWhiteSpace(migrationResult.DatabaseName)
|
||||
? $"{target.ServerName}:{migrationResult.DatabaseName}"
|
||||
: target.Name;
|
||||
: target.Name;
|
||||
var ruleId = migrationResult.FeatureId.ToString();
|
||||
|
||||
var item = new MigrationAssessmentInfo()
|
||||
{
|
||||
CheckId = r.Check.Id,
|
||||
Description = r.Check.Description,
|
||||
Description = r.Check.Description,
|
||||
DisplayName = r.Check.DisplayName,
|
||||
HelpLink = r.Check.HelpLink,
|
||||
Level = r.Check.Level.ToString(),
|
||||
@@ -248,5 +252,57 @@ namespace Microsoft.SqlTools.ServiceLayer.Migration
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
|
||||
int dwLogonType, int dwLogonProvider, out SafeAccessTokenHandle phToken);
|
||||
|
||||
internal async Task HandleValidateWindowsAccountRequest(
|
||||
ValidateWindowsAccountRequestParams parameters,
|
||||
RequestContext<ValidateWindowsAccountResult> requestContext)
|
||||
{
|
||||
var domainUserRegex = new Regex(@"^[A-Za-z0-9\\\._-]{7,}$");
|
||||
// Checking if the username string is in 'domain\name' format
|
||||
if (!domainUserRegex.Match(parameters.Username).Success)
|
||||
{
|
||||
await requestContext.SendResult(new ValidateWindowsAccountResult()
|
||||
{
|
||||
Success = false,
|
||||
ErrorMessage = "Invalid user name format. Example: Domain\\username"
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
int separator = parameters.Username.IndexOf("\\");
|
||||
string domainName = (separator > -1) ? parameters.Username.Substring(0, separator) : string.Empty;
|
||||
string userName = (separator > -1) ? parameters.Username.Substring(separator + 1, parameters.Username.Length - separator - 1) : string.Empty;
|
||||
|
||||
const int LOGON32_PROVIDER_DEFAULT = 0;
|
||||
const int LOGON32_LOGON_INTERACTIVE = 2;
|
||||
|
||||
SafeAccessTokenHandle safeAccessTokenHandle;
|
||||
bool returnValue = LogonUser(userName, domainName, parameters.Password,
|
||||
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
|
||||
out safeAccessTokenHandle);
|
||||
|
||||
if (false == returnValue)
|
||||
{
|
||||
int ret = Marshal.GetLastWin32Error();
|
||||
string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
|
||||
await requestContext.SendResult(new ValidateWindowsAccountResult()
|
||||
{
|
||||
Success = returnValue,
|
||||
ErrorMessage = errorMessage
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
await requestContext.SendResult(new ValidateWindowsAccountResult()
|
||||
{
|
||||
Success = true,
|
||||
ErrorMessage = ""
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user