2018-01-18 15:14:05 +01:00
|
|
|
|
/*
|
2019-01-09 11:25:21 +01:00
|
|
|
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
2018-01-18 15:14:05 +01:00
|
|
|
|
*
|
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
2018-06-27 14:02:16 +02:00
|
|
|
|
using SafeExamBrowser.Contracts.Communication.Data;
|
2018-01-18 15:14:05 +01:00
|
|
|
|
using SafeExamBrowser.Contracts.Configuration;
|
2018-12-14 09:50:10 +01:00
|
|
|
|
using SafeExamBrowser.Contracts.Configuration.Cryptography;
|
2018-01-18 15:14:05 +01:00
|
|
|
|
using SafeExamBrowser.Contracts.Configuration.Settings;
|
2018-10-03 14:35:27 +02:00
|
|
|
|
using SafeExamBrowser.Contracts.Core.OperationModel;
|
|
|
|
|
using SafeExamBrowser.Contracts.Core.OperationModel.Events;
|
2018-01-18 15:14:05 +01:00
|
|
|
|
using SafeExamBrowser.Contracts.I18n;
|
|
|
|
|
using SafeExamBrowser.Contracts.Logging;
|
2018-10-03 14:35:27 +02:00
|
|
|
|
using SafeExamBrowser.Runtime.Operations.Events;
|
2018-01-18 15:14:05 +01:00
|
|
|
|
|
2018-08-31 10:06:27 +02:00
|
|
|
|
namespace SafeExamBrowser.Runtime.Operations
|
2018-01-18 15:14:05 +01:00
|
|
|
|
{
|
2018-10-12 11:16:59 +02:00
|
|
|
|
internal class ConfigurationOperation : SessionOperation
|
2018-01-18 15:14:05 +01:00
|
|
|
|
{
|
2018-10-12 11:16:59 +02:00
|
|
|
|
private string[] commandLineArgs;
|
2018-06-29 09:50:20 +02:00
|
|
|
|
private IConfigurationRepository configuration;
|
2018-12-14 09:50:10 +01:00
|
|
|
|
private IHashAlgorithm hashAlgorithm;
|
2018-01-18 15:14:05 +01:00
|
|
|
|
private ILogger logger;
|
|
|
|
|
|
2018-12-14 09:50:10 +01:00
|
|
|
|
private string AppDataFile
|
|
|
|
|
{
|
|
|
|
|
get { return Path.Combine(Context.Next.AppConfig.AppDataFolder, Context.Next.AppConfig.DefaultSettingsFileName); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string ProgramDataFile
|
|
|
|
|
{
|
|
|
|
|
get { return Path.Combine(Context.Next.AppConfig.ProgramDataFolder, Context.Next.AppConfig.DefaultSettingsFileName); }
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-12 11:16:59 +02:00
|
|
|
|
public override event ActionRequiredEventHandler ActionRequired;
|
|
|
|
|
public override event StatusChangedEventHandler StatusChanged;
|
2018-01-18 15:14:05 +01:00
|
|
|
|
|
|
|
|
|
public ConfigurationOperation(
|
2018-10-12 11:16:59 +02:00
|
|
|
|
string[] commandLineArgs,
|
2018-06-29 09:50:20 +02:00
|
|
|
|
IConfigurationRepository configuration,
|
2018-12-14 09:50:10 +01:00
|
|
|
|
IHashAlgorithm hashAlgorithm,
|
2018-01-18 15:14:05 +01:00
|
|
|
|
ILogger logger,
|
2018-10-12 11:16:59 +02:00
|
|
|
|
SessionContext sessionContext) : base(sessionContext)
|
2018-01-18 15:14:05 +01:00
|
|
|
|
{
|
2018-10-12 11:16:59 +02:00
|
|
|
|
this.commandLineArgs = commandLineArgs;
|
2018-06-29 09:50:20 +02:00
|
|
|
|
this.configuration = configuration;
|
2018-12-14 09:50:10 +01:00
|
|
|
|
this.hashAlgorithm = hashAlgorithm;
|
2018-12-11 16:06:10 +01:00
|
|
|
|
this.logger = logger;
|
2018-01-18 15:14:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-10-12 11:16:59 +02:00
|
|
|
|
public override OperationResult Perform()
|
2018-01-18 15:14:05 +01:00
|
|
|
|
{
|
|
|
|
|
logger.Info("Initializing application configuration...");
|
2018-10-03 15:42:50 +02:00
|
|
|
|
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeConfiguration);
|
2018-01-18 15:14:05 +01:00
|
|
|
|
|
2018-11-15 08:45:17 +01:00
|
|
|
|
var result = OperationResult.Failed;
|
2018-06-21 07:56:25 +02:00
|
|
|
|
var isValidUri = TryInitializeSettingsUri(out Uri uri);
|
2018-01-18 15:14:05 +01:00
|
|
|
|
|
|
|
|
|
if (isValidUri)
|
|
|
|
|
{
|
2018-11-15 08:45:17 +01:00
|
|
|
|
result = LoadSettings(uri);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = LoadDefaultSettings();
|
2018-01-18 15:14:05 +01:00
|
|
|
|
}
|
2018-02-28 15:49:06 +01:00
|
|
|
|
|
2018-11-15 08:45:17 +01:00
|
|
|
|
LogOperationResult(result);
|
2018-06-21 07:56:25 +02:00
|
|
|
|
|
2018-11-15 08:45:17 +01:00
|
|
|
|
return result;
|
2018-01-18 15:14:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-10-12 11:16:59 +02:00
|
|
|
|
public override OperationResult Repeat()
|
2018-02-01 08:37:12 +01:00
|
|
|
|
{
|
2018-06-21 07:56:25 +02:00
|
|
|
|
logger.Info("Initializing new application configuration...");
|
2018-10-03 15:42:50 +02:00
|
|
|
|
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeConfiguration);
|
2018-02-28 15:49:06 +01:00
|
|
|
|
|
2018-11-15 08:45:17 +01:00
|
|
|
|
var result = OperationResult.Failed;
|
2018-10-12 11:16:59 +02:00
|
|
|
|
var isValidUri = TryValidateSettingsUri(Context.ReconfigurationFilePath, out Uri uri);
|
2018-06-21 07:56:25 +02:00
|
|
|
|
|
|
|
|
|
if (isValidUri)
|
|
|
|
|
{
|
2018-11-15 08:45:17 +01:00
|
|
|
|
result = LoadSettings(uri);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
logger.Warn($"The resource specified for reconfiguration does not exist or is not valid!");
|
2018-06-21 07:56:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
2018-11-15 08:45:17 +01:00
|
|
|
|
LogOperationResult(result);
|
2018-06-21 07:56:25 +02:00
|
|
|
|
|
2018-11-15 08:45:17 +01:00
|
|
|
|
return result;
|
2018-02-01 08:37:12 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-10-12 11:16:59 +02:00
|
|
|
|
public override OperationResult Revert()
|
2018-01-18 15:14:05 +01:00
|
|
|
|
{
|
2018-10-10 09:19:03 +02:00
|
|
|
|
return OperationResult.Success;
|
2018-01-18 15:14:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-11-15 08:45:17 +01:00
|
|
|
|
private OperationResult LoadDefaultSettings()
|
|
|
|
|
{
|
|
|
|
|
logger.Info("No valid configuration resource specified nor found in PROGRAMDATA or APPDATA - loading default settings...");
|
|
|
|
|
Context.Next.Settings = configuration.LoadDefaultSettings();
|
|
|
|
|
|
|
|
|
|
return OperationResult.Success;
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-21 07:56:25 +02:00
|
|
|
|
private OperationResult LoadSettings(Uri uri)
|
|
|
|
|
{
|
2018-12-14 09:50:10 +01:00
|
|
|
|
var passwordParams = new PasswordParameters { Password = string.Empty, IsHash = true };
|
2018-12-14 15:30:10 +01:00
|
|
|
|
var status = configuration.TryLoadSettings(uri, out var settings, passwordParams);
|
2018-11-28 15:43:30 +01:00
|
|
|
|
|
2018-12-14 09:50:10 +01:00
|
|
|
|
if (status == LoadStatus.PasswordNeeded && Context.Current?.Settings.AdminPasswordHash != null)
|
2018-06-21 07:56:25 +02:00
|
|
|
|
{
|
2018-12-14 09:50:10 +01:00
|
|
|
|
passwordParams.Password = Context.Current.Settings.AdminPasswordHash;
|
|
|
|
|
passwordParams.IsHash = true;
|
2018-06-21 07:56:25 +02:00
|
|
|
|
|
2018-12-14 15:30:10 +01:00
|
|
|
|
status = configuration.TryLoadSettings(uri, out settings, passwordParams);
|
2018-12-14 09:50:10 +01:00
|
|
|
|
}
|
2018-12-11 16:06:10 +01:00
|
|
|
|
|
2018-12-14 09:50:10 +01:00
|
|
|
|
for (int attempts = 0; attempts < 5 && status == LoadStatus.PasswordNeeded; attempts++)
|
|
|
|
|
{
|
|
|
|
|
var success = TryGetPassword(PasswordRequestPurpose.Settings, out var password);
|
2018-12-11 16:06:10 +01:00
|
|
|
|
|
2018-12-14 09:50:10 +01:00
|
|
|
|
if (success)
|
|
|
|
|
{
|
|
|
|
|
passwordParams.Password = password;
|
|
|
|
|
passwordParams.IsHash = false;
|
|
|
|
|
}
|
|
|
|
|
else
|
2018-06-21 07:56:25 +02:00
|
|
|
|
{
|
2018-11-22 14:36:20 +01:00
|
|
|
|
return OperationResult.Aborted;
|
2018-06-21 11:07:46 +02:00
|
|
|
|
}
|
2018-11-22 14:36:20 +01:00
|
|
|
|
|
2018-12-14 15:30:10 +01:00
|
|
|
|
status = configuration.TryLoadSettings(uri, out settings, passwordParams);
|
2018-06-21 07:56:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
2018-12-11 16:06:10 +01:00
|
|
|
|
Context.Next.Settings = settings;
|
|
|
|
|
|
2019-01-23 08:12:15 +01:00
|
|
|
|
if (settings != null)
|
|
|
|
|
{
|
|
|
|
|
logger.LogLevel = settings.LogLevel;
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-14 15:30:10 +01:00
|
|
|
|
return HandleLoadResult(uri, settings, status, passwordParams);
|
2018-12-14 09:50:10 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-12-14 15:30:10 +01:00
|
|
|
|
private OperationResult HandleLoadResult(Uri uri, Settings settings, LoadStatus status, PasswordParameters password)
|
2018-12-14 09:50:10 +01:00
|
|
|
|
{
|
|
|
|
|
if (status == LoadStatus.LoadWithBrowser)
|
2018-10-12 11:16:59 +02:00
|
|
|
|
{
|
2018-12-14 09:50:10 +01:00
|
|
|
|
return HandleBrowserResource(uri);
|
2018-11-09 14:15:56 +01:00
|
|
|
|
}
|
2018-12-11 16:06:10 +01:00
|
|
|
|
|
2018-12-14 09:50:10 +01:00
|
|
|
|
if (status == LoadStatus.Success && settings.ConfigurationMode == ConfigurationMode.ConfigureClient)
|
|
|
|
|
{
|
2018-12-14 15:30:10 +01:00
|
|
|
|
return HandleClientConfiguration(uri, password);
|
2018-12-14 09:50:10 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (status == LoadStatus.Success)
|
2018-11-09 14:15:56 +01:00
|
|
|
|
{
|
2018-12-14 09:50:10 +01:00
|
|
|
|
return OperationResult.Success;
|
2018-10-12 11:16:59 +02:00
|
|
|
|
}
|
|
|
|
|
|
2018-12-11 16:06:10 +01:00
|
|
|
|
ShowFailureMessage(status, uri);
|
|
|
|
|
|
|
|
|
|
return OperationResult.Failed;
|
2018-11-09 14:15:56 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-12-14 09:50:10 +01:00
|
|
|
|
private OperationResult HandleBrowserResource(Uri uri)
|
|
|
|
|
{
|
|
|
|
|
Context.Next.Settings.Browser.StartUrl = uri.AbsoluteUri;
|
|
|
|
|
logger.Info($"The configuration resource needs authentication or is a webpage, using '{uri}' as startup URL for the browser.");
|
|
|
|
|
|
|
|
|
|
return OperationResult.Success;
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-14 15:30:10 +01:00
|
|
|
|
private OperationResult HandleClientConfiguration(Uri resource, PasswordParameters password)
|
2018-12-14 09:50:10 +01:00
|
|
|
|
{
|
|
|
|
|
var isAppDataFile = Path.GetFullPath(resource.AbsolutePath).Equals(AppDataFile, StringComparison.OrdinalIgnoreCase);
|
|
|
|
|
var isProgramDataFile = Path.GetFullPath(resource.AbsolutePath).Equals(ProgramDataFile, StringComparison.OrdinalIgnoreCase);
|
2018-12-21 11:36:20 +01:00
|
|
|
|
var isFirstSession = Context.Current == null;
|
2018-12-14 09:50:10 +01:00
|
|
|
|
|
|
|
|
|
if (!isAppDataFile && !isProgramDataFile)
|
|
|
|
|
{
|
|
|
|
|
var requiresAuthentication = IsAuthenticationRequiredForClientConfiguration(password);
|
|
|
|
|
|
|
|
|
|
logger.Info("Starting client configuration...");
|
|
|
|
|
|
|
|
|
|
if (requiresAuthentication)
|
|
|
|
|
{
|
|
|
|
|
var result = HandleClientConfigurationAuthentication();
|
|
|
|
|
|
|
|
|
|
if (result != OperationResult.Success)
|
|
|
|
|
{
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
logger.Info("Authentication is not required.");
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-14 15:30:10 +01:00
|
|
|
|
var status = configuration.ConfigureClientWith(resource, password);
|
|
|
|
|
|
2018-12-21 11:36:20 +01:00
|
|
|
|
if (status == SaveStatus.Success)
|
|
|
|
|
{
|
|
|
|
|
logger.Info("Client configuration was successful.");
|
|
|
|
|
}
|
|
|
|
|
else
|
2018-12-14 15:30:10 +01:00
|
|
|
|
{
|
|
|
|
|
logger.Error($"Client configuration failed with status '{status}'!");
|
|
|
|
|
ActionRequired?.Invoke(new ClientConfigurationErrorMessageArgs());
|
|
|
|
|
|
|
|
|
|
return OperationResult.Failed;
|
|
|
|
|
}
|
2018-12-14 09:50:10 +01:00
|
|
|
|
|
|
|
|
|
if (isFirstSession)
|
|
|
|
|
{
|
2018-12-14 15:30:10 +01:00
|
|
|
|
var result = HandleClientConfigurationOnStartup();
|
2018-12-14 09:50:10 +01:00
|
|
|
|
|
|
|
|
|
if (result != OperationResult.Success)
|
|
|
|
|
{
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return OperationResult.Success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool IsAuthenticationRequiredForClientConfiguration(PasswordParameters password)
|
|
|
|
|
{
|
|
|
|
|
var requiresAuthentication = Context.Current?.Settings.AdminPasswordHash != null;
|
|
|
|
|
|
|
|
|
|
if (requiresAuthentication)
|
|
|
|
|
{
|
|
|
|
|
var currentPassword = Context.Current.Settings.AdminPasswordHash;
|
|
|
|
|
var nextPassword = Context.Next.Settings.AdminPasswordHash;
|
|
|
|
|
var hasSettingsPassword = password.Password != null;
|
|
|
|
|
var sameAdminPassword = currentPassword.Equals(nextPassword, StringComparison.OrdinalIgnoreCase);
|
|
|
|
|
|
|
|
|
|
requiresAuthentication = !sameAdminPassword;
|
|
|
|
|
|
|
|
|
|
if (requiresAuthentication && hasSettingsPassword)
|
|
|
|
|
{
|
|
|
|
|
var settingsPassword = password.IsHash ? password.Password : hashAlgorithm.GenerateHashFor(password.Password);
|
|
|
|
|
var knowsAdminPassword = currentPassword.Equals(settingsPassword, StringComparison.OrdinalIgnoreCase);
|
|
|
|
|
|
|
|
|
|
requiresAuthentication = !knowsAdminPassword;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return requiresAuthentication;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private OperationResult HandleClientConfigurationAuthentication()
|
|
|
|
|
{
|
|
|
|
|
var currentPassword = Context.Current.Settings.AdminPasswordHash;
|
|
|
|
|
var isSamePassword = false;
|
|
|
|
|
|
|
|
|
|
for (int attempts = 0; attempts < 5 && !isSamePassword; attempts++)
|
|
|
|
|
{
|
|
|
|
|
var success = TryGetPassword(PasswordRequestPurpose.Administrator, out var password);
|
|
|
|
|
|
|
|
|
|
if (success)
|
|
|
|
|
{
|
|
|
|
|
isSamePassword = currentPassword.Equals(hashAlgorithm.GenerateHashFor(password), StringComparison.OrdinalIgnoreCase);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
logger.Info("Authentication was aborted.");
|
|
|
|
|
|
|
|
|
|
return OperationResult.Aborted;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isSamePassword)
|
|
|
|
|
{
|
|
|
|
|
logger.Info("Authentication was successful.");
|
|
|
|
|
|
|
|
|
|
return OperationResult.Success;
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-14 15:30:10 +01:00
|
|
|
|
logger.Info("Authentication has failed!");
|
|
|
|
|
ActionRequired?.Invoke(new InvalidPasswordMessageArgs());
|
|
|
|
|
|
|
|
|
|
return OperationResult.Failed;
|
2018-12-14 09:50:10 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-12-14 15:30:10 +01:00
|
|
|
|
private OperationResult HandleClientConfigurationOnStartup()
|
2018-12-14 09:50:10 +01:00
|
|
|
|
{
|
|
|
|
|
var args = new ConfigurationCompletedEventArgs();
|
|
|
|
|
|
|
|
|
|
ActionRequired?.Invoke(args);
|
2018-12-14 15:30:10 +01:00
|
|
|
|
logger.Info($"The user chose to {(args.AbortStartup ? "abort" : "continue")} startup after successful client configuration.");
|
2018-12-14 09:50:10 +01:00
|
|
|
|
|
|
|
|
|
if (args.AbortStartup)
|
|
|
|
|
{
|
|
|
|
|
return OperationResult.Aborted;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return OperationResult.Success;
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-09 14:15:56 +01:00
|
|
|
|
private void ShowFailureMessage(LoadStatus status, Uri uri)
|
|
|
|
|
{
|
2018-11-08 09:39:52 +01:00
|
|
|
|
switch (status)
|
|
|
|
|
{
|
2018-12-14 09:50:10 +01:00
|
|
|
|
case LoadStatus.PasswordNeeded:
|
2018-12-11 16:06:10 +01:00
|
|
|
|
ActionRequired?.Invoke(new InvalidPasswordMessageArgs());
|
|
|
|
|
break;
|
2018-11-08 09:39:52 +01:00
|
|
|
|
case LoadStatus.InvalidData:
|
|
|
|
|
ActionRequired?.Invoke(new InvalidDataMessageArgs(uri.ToString()));
|
|
|
|
|
break;
|
|
|
|
|
case LoadStatus.NotSupported:
|
|
|
|
|
ActionRequired?.Invoke(new NotSupportedMessageArgs(uri.ToString()));
|
|
|
|
|
break;
|
|
|
|
|
case LoadStatus.UnexpectedError:
|
|
|
|
|
ActionRequired?.Invoke(new UnexpectedErrorMessageArgs(uri.ToString()));
|
|
|
|
|
break;
|
|
|
|
|
}
|
2018-06-21 07:56:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
2018-12-14 09:50:10 +01:00
|
|
|
|
private bool TryGetPassword(PasswordRequestPurpose purpose, out string password)
|
2018-06-21 07:56:25 +02:00
|
|
|
|
{
|
2018-10-03 14:35:27 +02:00
|
|
|
|
var args = new PasswordRequiredEventArgs { Purpose = purpose };
|
2018-06-21 07:56:25 +02:00
|
|
|
|
|
2018-10-03 14:35:27 +02:00
|
|
|
|
ActionRequired?.Invoke(args);
|
2018-12-14 09:50:10 +01:00
|
|
|
|
password = args.Password;
|
2018-12-11 16:06:10 +01:00
|
|
|
|
|
|
|
|
|
return args.Success;
|
2018-06-27 14:02:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
2018-06-21 07:56:25 +02:00
|
|
|
|
private bool TryInitializeSettingsUri(out Uri uri)
|
2018-01-18 15:14:05 +01:00
|
|
|
|
{
|
2018-12-14 09:50:10 +01:00
|
|
|
|
var path = default(string);
|
2018-01-18 15:14:05 +01:00
|
|
|
|
var isValidUri = false;
|
|
|
|
|
|
|
|
|
|
uri = null;
|
|
|
|
|
|
|
|
|
|
if (commandLineArgs?.Length > 1)
|
|
|
|
|
{
|
|
|
|
|
path = commandLineArgs[1];
|
|
|
|
|
isValidUri = Uri.TryCreate(path, UriKind.Absolute, out uri);
|
2018-11-09 14:15:56 +01:00
|
|
|
|
logger.Info($"Found command-line argument for configuration resource: '{path}', the URI is {(isValidUri ? "valid" : "invalid")}.");
|
2018-01-18 15:14:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-12-14 09:50:10 +01:00
|
|
|
|
if (!isValidUri && File.Exists(ProgramDataFile))
|
2018-01-18 15:14:05 +01:00
|
|
|
|
{
|
2018-12-14 09:50:10 +01:00
|
|
|
|
path = ProgramDataFile;
|
2018-01-18 15:14:05 +01:00
|
|
|
|
isValidUri = Uri.TryCreate(path, UriKind.Absolute, out uri);
|
2018-11-09 14:15:56 +01:00
|
|
|
|
logger.Info($"Found configuration file in PROGRAMDATA: '{path}', the URI is {(isValidUri ? "valid" : "invalid")}.");
|
2018-01-18 15:14:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-12-14 09:50:10 +01:00
|
|
|
|
if (!isValidUri && File.Exists(AppDataFile))
|
2018-01-18 15:14:05 +01:00
|
|
|
|
{
|
2018-12-14 09:50:10 +01:00
|
|
|
|
path = AppDataFile;
|
2018-01-18 15:14:05 +01:00
|
|
|
|
isValidUri = Uri.TryCreate(path, UriKind.Absolute, out uri);
|
2018-11-09 14:15:56 +01:00
|
|
|
|
logger.Info($"Found configuration file in APPDATA: '{path}', the URI is {(isValidUri ? "valid" : "invalid")}.");
|
2018-01-18 15:14:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return isValidUri;
|
|
|
|
|
}
|
2018-01-19 14:04:12 +01:00
|
|
|
|
|
2018-06-21 07:56:25 +02:00
|
|
|
|
private bool TryValidateSettingsUri(string path, out Uri uri)
|
2018-03-21 10:23:15 +01:00
|
|
|
|
{
|
2018-06-21 07:56:25 +02:00
|
|
|
|
var isValidUri = Uri.TryCreate(path, UriKind.Absolute, out uri);
|
2018-03-21 10:23:15 +01:00
|
|
|
|
|
2018-06-21 07:56:25 +02:00
|
|
|
|
isValidUri &= uri != null && uri.IsFile;
|
|
|
|
|
isValidUri &= File.Exists(path);
|
2018-03-21 10:23:15 +01:00
|
|
|
|
|
2018-06-21 07:56:25 +02:00
|
|
|
|
return isValidUri;
|
2018-03-21 10:23:15 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-06-21 07:56:25 +02:00
|
|
|
|
private void LogOperationResult(OperationResult result)
|
|
|
|
|
{
|
|
|
|
|
switch (result)
|
|
|
|
|
{
|
|
|
|
|
case OperationResult.Aborted:
|
|
|
|
|
logger.Info("The configuration was aborted by the user.");
|
|
|
|
|
break;
|
|
|
|
|
case OperationResult.Failed:
|
|
|
|
|
logger.Warn("The configuration has failed!");
|
|
|
|
|
break;
|
|
|
|
|
case OperationResult.Success:
|
|
|
|
|
logger.Info("The configuration was successful.");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-01-18 15:14:05 +01:00
|
|
|
|
}
|
|
|
|
|
}
|