예제 #1
0
        /// <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);
            }
        }
예제 #2
0
        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.");
        }
예제 #8
0
        /// <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);
            }
        }
예제 #9
0
        /// <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.
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        /// <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);
            }
        }