/// <summary> /// Connects a NET USE session. /// </summary> /// <param name="netSource"></param> /// <param name="netPass"></param> /// <param name="netUser"></param> private bool TryConnectNetUse(NetworkSourceLocation netSource, string netUser, string netPass) { bool authenticated = !string.IsNullOrWhiteSpace(netUser) && !string.IsNullOrWhiteSpace(netPass); var process = new Process(); var startInfo = new ProcessStartInfo() { FileName = "NET", Arguments = authenticated ? string.Format("USE {0} /USER:{1} {2}", netSource.Path, netUser, netPass) : string.Format("USE {0}", netSource.Path), RedirectStandardError = true, UseShellExecute = false }; process.StartInfo = startInfo; process.Start(); process.WaitForExit(); var stdErr = process.StandardError.ReadToEnd(); if (process.ExitCode != 0 && !string.IsNullOrWhiteSpace(stdErr)) { string err = string.Format("Failed to connect a network source location: {0}. An error occurred calling NET USE. Error: {1}", netSource.Path, stdErr); Logger.WriteTraceError(err); return(false); } else { return(true); } }
public void StartArchivialNetworkSourceRescanCommand_ThrowsIfSourceIsNotFound() { var mockedDb = new Mock <IClientDatabase>(); NetworkSourceLocation databaseCommitedObject = null; mockedDb.Setup(x => x.GetSourceLocationsAsync()).ReturnsAsync( new SourceLocations() { new NetworkSourceLocation() { ID = 1 } } ); mockedDb.Setup(x => x.RescanSourceLocationAsync(It.IsAny <NetworkSourceLocation>())) .Returns(Task.CompletedTask) .Callback <NetworkSourceLocation>(x => databaseCommitedObject = x); var mockedCoreSettings = new Mock <ICoreSettings>(); var depedencies = new CmdletDependencies() { ClientDatabase = mockedDb.Object, CoreSettings = mockedCoreSettings.Object }; var command = new StartArchivialNetworkSourceRescanCommand(depedencies) { SourceID = 2 }; var result = command.Invoke().GetEnumerator().MoveNext(); }
public void NetworkSourceLocationValidatePassesValidExample1() { var loc = new NetworkSourceLocation(); loc.Path = "\\\\test-computer\\\\uncpath"; loc.CredentialName = "test-creds"; loc.RevisionCount = 1; loc.ID = 1; loc.ValidateParameters(); Assert.IsTrue(true); }
public void NetworkSourceLocationValidateThrowsWhenInvalidCredentialNameIsProvided() { var loc = new NetworkSourceLocation(); loc.Path = "\\\\test-computer\\\\uncpath"; loc.CredentialName = null; // missing credential name loc.RevisionCount = 1; loc.ID = 1; loc.ValidateParameters(); Assert.IsTrue(true); }
public void NetworkSourceLocationValidateThrowsWhenInvalidUncPathIsProvided2() { var loc = new NetworkSourceLocation(); loc.Path = "C:\\users\\test"; // not a UNC path loc.CredentialName = "test-creds"; loc.RevisionCount = 1; loc.ID = 1; loc.ValidateParameters(); Assert.IsTrue(true); }
public void NetworkSourceLocationValidateThrowsWhenInvalidUncPathIsProvided1() { var loc = new NetworkSourceLocation(); loc.Path = null; // missing path loc.CredentialName = "test-creds"; loc.RevisionCount = 1; loc.ID = 1; loc.ValidateParameters(); Assert.IsTrue(true); }
protected override void ProcessRecord() { FileBackupPriority priorityEnum; if (!Enum.TryParse(Priority, out priorityEnum)) { throw new ArgumentException(nameof(Priority) + " value was not valid."); } if (MatchFilter == null) { MatchFilter = ArchivialLibrary.Constants.CommandLine.DefaultSourceMatchFilter; } var db = GetDatabaseConnection(); WriteVerbose("Querying for existing scan sources to check for duplicates."); var allSources = db.GetSourceLocationsAsync().GetAwaiter().GetResult(); var allNetSources = allSources.Where(x => x is NetworkSourceLocation).ToList(); if (allNetSources.Any(x => string.Equals(x.Path, UncPath, StringComparison.CurrentCultureIgnoreCase) && string.Equals(x.FileMatchFilter, MatchFilter, StringComparison.CurrentCultureIgnoreCase))) { // there already exists a source with this folder location and match filter. throw new SourceLocationException("Unable to add source: the specified folder and match filter combination is already listed as a source."); } else { WriteVerbose("No duplicate sources found."); } var newSource = new NetworkSourceLocation(); newSource.Path = UncPath; newSource.CredentialName = CredentialName; newSource.FileMatchFilter = MatchFilter; newSource.RevisionCount = Revisions; newSource.Priority = priorityEnum; WriteVerbose("Validating the source parameters are acceptable."); newSource.ValidateParameters(); WriteVerbose("The specified scan source has normal parameters."); WriteVerbose("Saving the source to the database."); db.SetSourceLocationAsync(newSource).GetAwaiter().GetResult(); WriteVerbose("Successfully saved source to the database."); }
/// <summary> /// Updates the network source connection state in the database. /// </summary> /// <param name="netSource"></param> /// <param name="isConnected"></param> /// <param name="isFailed"></param> private async Task UpdateNetSourceConnectionStateAsync(NetworkSourceLocation netSource, bool isConnected, bool isFailed) { try { netSource.IsConnected = isConnected; netSource.IsFailed = isFailed; netSource.LastConnectionCheck = DateTime.Now; await Database.SetSourceLocationAsync(netSource).ConfigureAwait(false); } catch (Exception ex) { string err = "Failed to save source locations to the database."; Logger.WriteSystemEvent(err, ex, Logger.GenerateFullContextStackTrace(), Constants.EventIDs.FailedToSaveScanSources, true); } }
/// <summary> /// Disconnects a NET USE session. /// </summary> /// <param name="netSource"></param> private void DisconnectNetUse(NetworkSourceLocation netSource) { var process = new Process(); var startInfo = new ProcessStartInfo() { FileName = "NET", Arguments = string.Format("USE /DELETE {0}", netSource.Path), }; process.StartInfo = startInfo; process.Start(); process.WaitForExit(); // we don't actually care what happens here, in terms of exit code or stderr. // net use will write to stderr if the connection doesn't exist, which is fine/normal for this use case. }
public void StartArchivialNetworkSourceRescanCommand_CanQueueRescan_FromSourceObject() { var mockedDb = new Mock <IClientDatabase>(); NetworkSourceLocation databaseCommitedObject = null; mockedDb.Setup(x => x.GetSourceLocationsAsync()).ReturnsAsync( new SourceLocations() { new NetworkSourceLocation() { ID = 1 } } ); mockedDb.Setup(x => x.RescanSourceLocationAsync(It.IsAny <NetworkSourceLocation>())) .Returns(Task.CompletedTask) .Callback <NetworkSourceLocation>(x => databaseCommitedObject = x); var mockedCoreSettings = new Mock <ICoreSettings>(); var depedencies = new CmdletDependencies() { ClientDatabase = mockedDb.Object, CoreSettings = mockedCoreSettings.Object }; var command = new StartArchivialNetworkSourceRescanCommand(depedencies) { NetworkSource = new NetworkSourceLocation() { ID = 1 } }; var result = command.Invoke().GetEnumerator().MoveNext(); mockedDb.Verify(x => x.RescanSourceLocationAsync(It.IsAny <NetworkSourceLocation>()), Times.Once); Assert.IsNotNull(databaseCommitedObject); Assert.AreEqual(1, databaseCommitedObject.ID); }
public void AddArchivialNetworkSourceCommand_CanSaveNewNetworkSource() { var mockedDb = new Mock <IClientDatabase>(); NetworkSourceLocation databaseCommitedObject = null; mockedDb.Setup(x => x.GetSourceLocationsAsync()).ReturnsAsync(new SourceLocations()); mockedDb.Setup(x => x.SetSourceLocationAsync(It.IsAny <NetworkSourceLocation>())) .Returns(Task.CompletedTask) .Callback <NetworkSourceLocation>(x => databaseCommitedObject = x); var mockedCoreSettings = new Mock <ICoreSettings>(); var depedencies = new CmdletDependencies() { ClientDatabase = mockedDb.Object, CoreSettings = mockedCoreSettings.Object }; var command = new AddArchivialNetworkSourceCommand(depedencies) { UncPath = "\\\\network\\path\\to\\folder", Priority = "Low", Revisions = 1, MatchFilter = "*", CredentialName = "creds" }; var result = command.Invoke().GetEnumerator().MoveNext(); mockedDb.Verify(x => x.SetSourceLocationAsync(It.IsAny <NetworkSourceLocation>()), Times.Once); Assert.IsNotNull(databaseCommitedObject); Assert.AreEqual("\\\\network\\path\\to\\folder", databaseCommitedObject.Path); Assert.AreEqual(FileBackupPriority.Low, databaseCommitedObject.Priority); Assert.AreEqual(1, databaseCommitedObject.RevisionCount); Assert.AreEqual("*", databaseCommitedObject.FileMatchFilter); }
/// <summary> /// Safely verifies a network source connection state. /// </summary> /// <remarks> /// This function is marked as safe and should not throw exceptions. /// </remarks> /// <param name="netSource"></param> /// <returns></returns> private async Task SafeVerifyNetSourceConnectionStateAsync(NetworkSourceLocation netSource) { var dir = new DirectoryInfo(netSource.Path); if (dir.Exists) { // we are already connected or have access. // this is either an unauthenticated location or we have already establish a connection through net use. await UpdateNetSourceConnectionStateAsync(netSource, true, false).ConfigureAwait(false); return; } // force disconnect and reconnect if (netSource.CredentialName == null) { Logger.WriteTraceError(string.Format( "Unable to connect to network source location: {0}.", netSource.Path, netSource.CredentialName)); await UpdateNetSourceConnectionStateAsync(netSource, false, true).ConfigureAwait(false); return; } Logger.WriteTraceMessage("Attempting to connect to network source location: " + netSource.Path); var creds = await GetNetSourceCredentialsAsync(netSource.CredentialName).ConfigureAwait(false); if (creds == null) { Logger.WriteTraceError(string.Format( "Unable to connect to network source location: {0}. The specified credential ({1}) was not found in the stored credentials.", netSource.Path, netSource.CredentialName)); await UpdateNetSourceConnectionStateAsync(netSource, false, true).ConfigureAwait(false); return; } DisconnectNetUse(netSource); if (!TryConnectNetUse(netSource, creds.Item1, creds.Item2)) { await UpdateNetSourceConnectionStateAsync(netSource, false, true).ConfigureAwait(false); return; } // validate again: do we have access now after disconnect/reconnect? // if we dont have access after running net use, then we can consider this connection failed. var freshDir = new DirectoryInfo(netSource.Path); if (freshDir.Exists) { Logger.WriteTraceMessage("Successfully connected to network source location: " + netSource.Path); await UpdateNetSourceConnectionStateAsync(netSource, true, false).ConfigureAwait(false); } else { Logger.WriteTraceMessage("Failed to connect to network source location. The directory is still not accessible after running NET USE command: " + netSource.Path); await UpdateNetSourceConnectionStateAsync(netSource, false, true).ConfigureAwait(false); } }