mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-31 09:35:39 -05:00
Adding server metadata to SQL Migration Assessment API (#1222)
* WIP * Adding server metdata to assessment call * Fixed spacing * Sorted imports Added copyright header Changes some class names Fixed description * Fixed assessment result and removing unused imports * Adding assessment result
This commit is contained in:
@@ -3,8 +3,8 @@
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
|
||||
using Microsoft.SqlServer.Migration.Assessment.Common.Contracts.Models;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Migration.Contracts
|
||||
{
|
||||
@@ -16,20 +16,25 @@ namespace Microsoft.SqlTools.ServiceLayer.Migration.Contracts
|
||||
public class MigrationAssessmentResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the collection of assessment results.
|
||||
/// Errors that happen while running the assessment
|
||||
/// </summary>
|
||||
public List<MigrationAssessmentInfo> Items { get; } = new List<MigrationAssessmentInfo>();
|
||||
|
||||
public ErrorModel[] Errors { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating
|
||||
/// if assessment operation was successful.
|
||||
/// Result of the assessment
|
||||
/// </summary>
|
||||
public bool Success { get; set; }
|
||||
|
||||
public ServerAssessmentProperties AssessmentResult { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets an status message for the operation.
|
||||
/// Start time of the assessment
|
||||
/// </summary>
|
||||
public string ErrorMessage { get; set; }
|
||||
public string StartTime { get; set; }
|
||||
/// <summary>
|
||||
/// End time of the assessment
|
||||
/// </summary>
|
||||
public string EndedTime { get; set; }
|
||||
/// <summary>
|
||||
/// Contains the raw assessment response
|
||||
/// </summary>
|
||||
public ISqlMigrationAssessmentModel RawAssessmentResult { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
//
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
//
|
||||
|
||||
using Microsoft.SqlServer.Migration.Assessment.Common.Contracts.TargetAssessment.Models;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Migration.Contracts
|
||||
{
|
||||
public class ServerAssessmentProperties
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of the server
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// Cpu cores for the server host
|
||||
/// </summary>
|
||||
public long CpuCoreCount { get; set; }
|
||||
/// <summary>
|
||||
/// Server host physical memory size
|
||||
/// </summary>
|
||||
public double PhysicalServerMemory { get; set; }
|
||||
/// <summary>
|
||||
/// Host operating system of the SQL server
|
||||
/// </summary>
|
||||
public string ServerHostPlatform { get; set; }
|
||||
/// <summary>
|
||||
/// Version of the SQL server
|
||||
/// </summary>
|
||||
public string ServerVersion { get; set; }
|
||||
/// <summary>
|
||||
/// SQL server engine edition
|
||||
/// </summary>
|
||||
public string ServerEngineEdition { get; set; }
|
||||
/// <summary>
|
||||
/// SQL server edition
|
||||
/// </summary>
|
||||
public string ServerEdition { get; set; }
|
||||
/// <summary>
|
||||
/// We use this flag to indicate if the SQL server is part of the failover cluster
|
||||
/// </summary>
|
||||
public bool IsClustered { get; set; }
|
||||
/// <summary>
|
||||
/// Returns the total number of dbs assessed
|
||||
/// </summary>
|
||||
public long NumberOfUserDatabases { get; set; }
|
||||
/// <summary>
|
||||
/// Returns the assessment status
|
||||
/// </summary>
|
||||
public int SqlAssessmentStatus { get; set; }
|
||||
/// <summary>
|
||||
/// Count of Dbs assessed
|
||||
/// </summary>
|
||||
public long AssessedDatabaseCount{get; set;}
|
||||
/// <summary>
|
||||
/// Give assessed server stats for SQL MI compatibility
|
||||
/// </summary>
|
||||
public IServerTargetReadiness SQLManagedInstanceTargetReadiness { get; set; }
|
||||
/// <summary>
|
||||
/// Server assessment results
|
||||
/// </summary>
|
||||
public MigrationAssessmentInfo[] Items { get; set; }
|
||||
/// <summary>
|
||||
/// Server assessment errors
|
||||
/// </summary>
|
||||
public ErrorModel[] Errors { get; set; }
|
||||
/// <summary>
|
||||
/// List of databases that are assessed
|
||||
/// </summary>
|
||||
public DatabaseAssessmentProperties[] Databases { get; set; }
|
||||
}
|
||||
|
||||
public class DatabaseAssessmentProperties
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of the database
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// Compatibility level of the database
|
||||
/// </summary>
|
||||
public string CompatibilityLevel { get; set; }
|
||||
/// <summary>
|
||||
/// Size of the database
|
||||
/// </summary>
|
||||
public double DatabaseSize { get; set; }
|
||||
/// <summary>
|
||||
/// Flag that indicates if the database is replicated
|
||||
/// </summary>
|
||||
public bool IsReplicationEnabled { get; set; }
|
||||
/// <summary>
|
||||
/// Time taken for assessing the database
|
||||
/// </summary>
|
||||
public double AssessmentTimeInMilliseconds { get; set; }
|
||||
/// <summary>
|
||||
/// Database Assessment Results
|
||||
/// </summary>
|
||||
public MigrationAssessmentInfo[] Items { get; set; }
|
||||
/// <summary>
|
||||
/// Database assessment errors
|
||||
/// </summary>
|
||||
public ErrorModel[] Errors {get; set;}
|
||||
/// <summary>
|
||||
/// Flags that indicate if the database is ready for migration
|
||||
/// </summary>
|
||||
public IDatabaseTargetReadiness SQLManagedInstanceTargetReadiness { get; set; }
|
||||
}
|
||||
|
||||
public class ErrorModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Id of the assessment error
|
||||
/// </summary>
|
||||
public string ErrorId { get; set; }
|
||||
/// <summary>
|
||||
/// Error message
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
/// <summary>
|
||||
/// Summary of the Error
|
||||
/// </summary>
|
||||
public string ErrorSummary { get; set; }
|
||||
/// <summary>
|
||||
/// Possible causes for the error
|
||||
/// </summary>
|
||||
public string PossibleCauses { get; set; }
|
||||
/// <summary>
|
||||
/// Possible mitigation for the error
|
||||
/// </summary>
|
||||
public string Guidance { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -5,27 +5,23 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.SqlServer.Management.Assessment;
|
||||
using Microsoft.SqlServer.DataCollection.Common;
|
||||
using Microsoft.SqlServer.Management.Assessment.Checks;
|
||||
using Microsoft.SqlServer.Management.Assessment;
|
||||
using Microsoft.SqlServer.Migration.Assessment.Common.Contracts.Models;
|
||||
using Microsoft.SqlServer.Migration.Assessment.Common.Engine;
|
||||
using Microsoft.SqlTools.Hosting.Protocol;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
||||
using Microsoft.SqlTools.ServiceLayer.Migration.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.SqlAssessment;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using Microsoft.SqlServer.DataCollection.Common;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Security.Principal;
|
||||
using System.IO;
|
||||
using Microsoft.SqlTools.Utility;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Migration
|
||||
{
|
||||
/// <summary>
|
||||
@@ -95,8 +91,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Migration
|
||||
{
|
||||
this.ServiceHost = serviceHost;
|
||||
this.ServiceHost.SetRequestHandler(MigrationAssessmentsRequest.Type, HandleMigrationAssessmentsRequest);
|
||||
this.ServiceHost.SetRequestHandler(ValidateWindowsAccountRequest.Type, HandleValidateWindowsAccountRequest);
|
||||
this.ServiceHost.SetRequestHandler(ValidateNetworkFileShareRequest.Type, HandleValidateNetworkFileShareRequest);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -143,10 +137,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Migration
|
||||
|
||||
var db = SqlAssessmentService.GetDatabaseLocator(server, connection.Database);
|
||||
var connectionString = ConnectionService.BuildConnectionString(connInfo.ConnectionDetails);
|
||||
var results = await GetAssessmentItems(server, connectionString);
|
||||
var result = new MigrationAssessmentResult();
|
||||
result.Items.AddRange(results);
|
||||
await requestContext.SendResult(result);
|
||||
|
||||
var results = await GetAssessmentItems(connectionString);
|
||||
await requestContext.SendResult(results);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -186,67 +179,124 @@ namespace Microsoft.SqlTools.ServiceLayer.Migration
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task<List<MigrationAssessmentInfo>> GetAssessmentItems(SqlObjectLocator target, string connectionString)
|
||||
internal async Task<MigrationAssessmentResult> GetAssessmentItems(string connectionString)
|
||||
{
|
||||
SqlAssessmentConfiguration.EnableLocalLogging = true;
|
||||
SqlAssessmentConfiguration.EnableReportCreation = true;
|
||||
SqlAssessmentConfiguration.AssessmentReportAndLogsRootFolderPath = Path.GetDirectoryName(Logger.LogFileFullPath);
|
||||
DmaEngine engine = new DmaEngine(connectionString);
|
||||
var assessmentResults = await engine.GetTargetAssessmentResultsList();
|
||||
|
||||
var result = new List<MigrationAssessmentInfo>();
|
||||
foreach (var r in assessmentResults)
|
||||
Dictionary<string, ISqlMigrationAssessmentResult> assessmentResultLookup = new Dictionary<string, ISqlMigrationAssessmentResult>();
|
||||
foreach (ISqlMigrationAssessmentResult r in assessmentResults)
|
||||
{
|
||||
var migrationResult = r as ISqlMigrationAssessmentResult;
|
||||
if (migrationResult == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
assessmentResultLookup.Add(CreateAssessmentResultKey(r as ISqlMigrationAssessmentResult), r as ISqlMigrationAssessmentResult);
|
||||
}
|
||||
ISqlMigrationAssessmentModel contextualizedAssessmentResult = await engine.GetTargetAssessmentResultsList(System.Threading.CancellationToken.None);
|
||||
return new MigrationAssessmentResult()
|
||||
{
|
||||
AssessmentResult = ParseServerAssessmentInfo(contextualizedAssessmentResult.Servers[0], assessmentResultLookup),
|
||||
Errors = ParseAssessmentError(contextualizedAssessmentResult.Errors),
|
||||
StartTime = contextualizedAssessmentResult.StartedOn.ToString(),
|
||||
EndedTime = contextualizedAssessmentResult.EndedOn.ToString(),
|
||||
RawAssessmentResult = contextualizedAssessmentResult
|
||||
};
|
||||
}
|
||||
|
||||
var targetName = !string.IsNullOrWhiteSpace(migrationResult.DatabaseName)
|
||||
? $"{target.ServerName}:{migrationResult.DatabaseName}"
|
||||
: target.Name;
|
||||
var ruleId = migrationResult.FeatureId.ToString();
|
||||
internal ServerAssessmentProperties ParseServerAssessmentInfo(IServerAssessmentInfo server, Dictionary<string, ISqlMigrationAssessmentResult> assessmentResultLookup)
|
||||
{
|
||||
return new ServerAssessmentProperties()
|
||||
{
|
||||
CpuCoreCount = server.Properties.ServerCoreCount,
|
||||
PhysicalServerMemory = server.Properties.MaxServerMemoryInUse,
|
||||
ServerHostPlatform = server.Properties.ServerHostPlatform,
|
||||
ServerVersion = server.Properties.ServerVersion,
|
||||
ServerEngineEdition = server.Properties.ServerEngineEdition,
|
||||
ServerEdition = server.Properties.ServerEdition,
|
||||
IsClustered = server.Properties.IsClustered,
|
||||
NumberOfUserDatabases = server.Properties.NumberOfUserDatabases,
|
||||
SqlAssessmentStatus = (int)server.Status,
|
||||
AssessedDatabaseCount = server.Properties.NumberOfUserDatabases,
|
||||
SQLManagedInstanceTargetReadiness = server.TargetReadinesses[Microsoft.SqlServer.DataCollection.Common.Contracts.Advisor.TargetType.AzureSqlManagedInstance],
|
||||
Errors = ParseAssessmentError(server.Errors),
|
||||
Items = ParseAssessmentResult(server.ServerAssessments, assessmentResultLookup),
|
||||
Databases = ParseDatabaseAssessmentInfo(server.Databases, assessmentResultLookup),
|
||||
Name = server.Properties.ServerName
|
||||
};
|
||||
}
|
||||
|
||||
var item = new MigrationAssessmentInfo()
|
||||
internal DatabaseAssessmentProperties[] ParseDatabaseAssessmentInfo(IList<IDatabaseAssessmentInfo> databases, Dictionary<string, ISqlMigrationAssessmentResult> assessmentResultLookup)
|
||||
{
|
||||
return databases.Select(d =>
|
||||
{
|
||||
return new DatabaseAssessmentProperties()
|
||||
{
|
||||
CheckId = r.Check.Id,
|
||||
Description = r.Check.Description,
|
||||
DisplayName = r.Check.DisplayName,
|
||||
HelpLink = r.Check.HelpLink,
|
||||
Level = r.Check.Level.ToString(),
|
||||
TargetName = targetName,
|
||||
DatabaseName = migrationResult.DatabaseName,
|
||||
ServerName = migrationResult.ServerName,
|
||||
Tags = r.Check.Tags.ToArray(),
|
||||
TargetType = target.Type,
|
||||
Name = d.Properties.Name,
|
||||
CompatibilityLevel = d.Properties.CompatibilityLevel.ToString(),
|
||||
DatabaseSize = d.Properties.SizeMB,
|
||||
IsReplicationEnabled = d.Properties.IsReplicationEnabled,
|
||||
AssessmentTimeInMilliseconds = d.Properties.TSqlScriptAnalysisTimeElapse.TotalMilliseconds,
|
||||
Errors = ParseAssessmentError(d.Errors),
|
||||
Items = ParseAssessmentResult(d.DatabaseAssessments, assessmentResultLookup),
|
||||
SQLManagedInstanceTargetReadiness = d.TargetReadinesses[Microsoft.SqlServer.DataCollection.Common.Contracts.Advisor.TargetType.AzureSqlManagedInstance]
|
||||
};
|
||||
}).ToArray();
|
||||
}
|
||||
internal ErrorModel[] ParseAssessmentError(IList<Microsoft.SqlServer.DataCollection.Common.Contracts.ErrorHandling.IErrorModel> errors)
|
||||
{
|
||||
return errors.Select(e =>
|
||||
{
|
||||
return new ErrorModel()
|
||||
{
|
||||
ErrorId = e.ErrorID.ToString(),
|
||||
Message = e.Message,
|
||||
ErrorSummary = e.ErrorSummary,
|
||||
PossibleCauses = e.PossibleCauses,
|
||||
Guidance = e.Guidance,
|
||||
};
|
||||
}).ToArray();
|
||||
}
|
||||
internal MigrationAssessmentInfo[] ParseAssessmentResult(IList<ISqlMigrationAssessmentResult> assessmentResults, Dictionary<string, ISqlMigrationAssessmentResult> assessmentResultLookup)
|
||||
{
|
||||
return assessmentResults.Select(r =>
|
||||
{
|
||||
var check = assessmentResultLookup[CreateAssessmentResultKey(r)].Check;
|
||||
return new MigrationAssessmentInfo()
|
||||
{
|
||||
CheckId = check.Id,
|
||||
Description = check.Description,
|
||||
DisplayName = check.DisplayName,
|
||||
HelpLink = check.HelpLink,
|
||||
Level = check.Level.ToString(),
|
||||
TargetName = r.AppliesToMigrationTargetPlatform.ToString(),
|
||||
DatabaseName = r.DatabaseName,
|
||||
ServerName = r.ServerName,
|
||||
Tags = check.Tags.ToArray(),
|
||||
RulesetName = Engine.Configuration.DefaultRuleset.Name,
|
||||
RulesetVersion = Engine.Configuration.DefaultRuleset.Version.ToString(),
|
||||
RuleId = ruleId,
|
||||
RuleId = r.FeatureId.ToString(),
|
||||
Message = r.Message,
|
||||
AppliesToMigrationTargetPlatform = migrationResult.AppliesToMigrationTargetPlatform.ToString(),
|
||||
IssueCategory = "Category_Unknown"
|
||||
AppliesToMigrationTargetPlatform = r.AppliesToMigrationTargetPlatform.ToString(),
|
||||
IssueCategory = r.IssueCategory.ToString(),
|
||||
ImpactedObjects = ParseImpactedObjects(r.ImpactedObjects)
|
||||
};
|
||||
|
||||
if (migrationResult.ImpactedObjects != null)
|
||||
}).ToArray();
|
||||
}
|
||||
internal ImpactedObjectInfo[] ParseImpactedObjects(IList<Microsoft.SqlServer.DataCollection.Common.Contracts.Advisor.Models.IImpactedObject> impactedObjects)
|
||||
{
|
||||
return impactedObjects.Select(i =>
|
||||
{
|
||||
return new ImpactedObjectInfo()
|
||||
{
|
||||
ImpactedObjectInfo[] impactedObjects = new ImpactedObjectInfo[migrationResult.ImpactedObjects.Count];
|
||||
for (int i = 0; i < migrationResult.ImpactedObjects.Count; ++i)
|
||||
{
|
||||
var impactedObject = new ImpactedObjectInfo()
|
||||
{
|
||||
Name = migrationResult.ImpactedObjects[i].Name,
|
||||
ImpactDetail = migrationResult.ImpactedObjects[i].ImpactDetail,
|
||||
ObjectType = migrationResult.ImpactedObjects[i].ObjectType
|
||||
};
|
||||
impactedObjects[i] = impactedObject;
|
||||
}
|
||||
item.ImpactedObjects = impactedObjects;
|
||||
}
|
||||
Name = i.Name,
|
||||
ImpactDetail = i.ImpactDetail,
|
||||
ObjectType = i.ObjectType
|
||||
};
|
||||
}).ToArray();
|
||||
}
|
||||
|
||||
result.Add(item);
|
||||
}
|
||||
return result;
|
||||
internal string CreateAssessmentResultKey(ISqlMigrationAssessmentResult assessment)
|
||||
{
|
||||
return assessment.ServerName+assessment.DatabaseName+assessment.FeatureId.ToString()+assessment.IssueCategory.ToString()+assessment.Message + assessment.TargetType.ToString() + assessment.AppliesToMigrationTargetPlatform.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -259,130 +309,5 @@ 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<bool> requestContext)
|
||||
{
|
||||
if (!ValidateWindowsDomainUsername(parameters.Username))
|
||||
{
|
||||
await requestContext.SendError("Invalid user name format. Example: Domain\\username");
|
||||
return;
|
||||
}
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
int separator = parameters.Username.IndexOf("\\");
|
||||
string domainName = parameters.Username.Substring(0, separator);
|
||||
string userName = parameters.Username.Substring(separator + 1, parameters.Username.Length - separator - 1);
|
||||
|
||||
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 (!returnValue)
|
||||
{
|
||||
int ret = Marshal.GetLastWin32Error();
|
||||
string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
|
||||
await requestContext.SendError(errorMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
await requestContext.SendResult(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await requestContext.SendResult(true);
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task HandleValidateNetworkFileShareRequest(
|
||||
ValidateNetworkFileShareRequestParams parameters,
|
||||
RequestContext<bool> requestContext)
|
||||
{
|
||||
if (!ValidateWindowsDomainUsername(parameters.Username))
|
||||
{
|
||||
await requestContext.SendError("Invalid user name format. Example: Domain\\username");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ValidateUNCPath(parameters.Path))
|
||||
{
|
||||
await requestContext.SendError("Invalid network share path. Example: \\\\Servername.domainname.com\\Backupfolder");
|
||||
return;
|
||||
}
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
int separator = parameters.Username.IndexOf("\\");
|
||||
string domainName = parameters.Username.Substring(0, separator);
|
||||
string userName = parameters.Username.Substring(separator + 1, parameters.Username.Length - separator - 1);
|
||||
|
||||
const int LOGON32_PROVIDER_WINNT50 = 3;
|
||||
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
|
||||
|
||||
SafeAccessTokenHandle safeAccessTokenHandle;
|
||||
bool returnValue = LogonUser(
|
||||
userName,
|
||||
domainName,
|
||||
parameters.Password,
|
||||
LOGON32_LOGON_NEW_CREDENTIALS,
|
||||
LOGON32_PROVIDER_WINNT50,
|
||||
out safeAccessTokenHandle);
|
||||
|
||||
if (!returnValue)
|
||||
{
|
||||
int ret = Marshal.GetLastWin32Error();
|
||||
string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
|
||||
await requestContext.SendError(errorMessage);
|
||||
return;
|
||||
}
|
||||
await WindowsIdentity.RunImpersonated(
|
||||
safeAccessTokenHandle,
|
||||
// User action
|
||||
async () =>
|
||||
{
|
||||
if(!Directory.Exists(parameters.Path)){
|
||||
await requestContext.SendError("Cannot connect to file share");
|
||||
} else {
|
||||
await requestContext.SendResult(true);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
await requestContext.SendResult(true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the username is in 'domain\username' format.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal bool ValidateWindowsDomainUsername(string username)
|
||||
{
|
||||
var domainUserRegex = new Regex(@"^(?<domain>[A-Za-z0-9\._-]*)\\(?<username>[A-Za-z0-9\._-]*)$");
|
||||
return domainUserRegex.IsMatch(username);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the file path is in UNC format '\\Servername.domainname.com\Backupfolder'
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
internal bool ValidateUNCPath(string path)
|
||||
{
|
||||
return new Uri(path).IsUnc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user