diff --git a/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs b/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs
index c5860cf4..ae35ed93 100644
--- a/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs
+++ b/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs
@@ -16,8 +16,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
{
internal class DataValues
{
- private const string BASE_ADDRESS = "net.pipe://localhost/safeexambrowser";
- private const string DEFAULT_FILE_NAME = "SebClientSettings.seb";
+ private const string DEFAULT_CONFIGURATION_NAME = "SebClientSettings.seb";
private AppConfig appConfig;
private string executablePath;
@@ -48,26 +47,26 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
var logFilePrefix = startTime.ToString("yyyy-MM-dd\\_HH\\hmm\\mss\\s");
appConfig = new AppConfig();
- appConfig.AppDataFilePath = Path.Combine(appDataRoamingFolder, DEFAULT_FILE_NAME);
+ appConfig.AppDataFilePath = Path.Combine(appDataRoamingFolder, DEFAULT_CONFIGURATION_NAME);
appConfig.ApplicationStartTime = startTime;
appConfig.BrowserCachePath = Path.Combine(appDataLocalFolder, "Cache");
appConfig.BrowserLogFilePath = Path.Combine(logFolder, $"{logFilePrefix}_Browser.log");
appConfig.ClientId = Guid.NewGuid();
- appConfig.ClientAddress = $"{BASE_ADDRESS}/client/{Guid.NewGuid()}";
+ appConfig.ClientAddress = $"{AppConfig.BASE_ADDRESS}/client/{Guid.NewGuid()}";
appConfig.ClientExecutablePath = Path.Combine(Path.GetDirectoryName(executablePath), $"{nameof(SafeExamBrowser)}.Client.exe");
appConfig.ClientLogFilePath = Path.Combine(logFolder, $"{logFilePrefix}_Client.log");
appConfig.ConfigurationFileExtension = ".seb";
appConfig.DownloadDirectory = Path.Combine(appDataLocalFolder, "Downloads");
appConfig.ProgramCopyright = programCopyright;
- appConfig.ProgramDataFilePath = Path.Combine(programDataFolder, DEFAULT_FILE_NAME);
+ appConfig.ProgramDataFilePath = Path.Combine(programDataFolder, DEFAULT_CONFIGURATION_NAME);
appConfig.ProgramTitle = programTitle;
appConfig.ProgramVersion = programVersion;
appConfig.RuntimeId = Guid.NewGuid();
- appConfig.RuntimeAddress = $"{BASE_ADDRESS}/runtime/{Guid.NewGuid()}";
+ appConfig.RuntimeAddress = $"{AppConfig.BASE_ADDRESS}/runtime/{Guid.NewGuid()}";
appConfig.RuntimeLogFilePath = Path.Combine(logFolder, $"{logFilePrefix}_Runtime.log");
appConfig.SebUriScheme = "seb";
appConfig.SebUriSchemeSecure = "sebs";
- appConfig.ServiceAddress = $"{BASE_ADDRESS}/service";
+ appConfig.ServiceAddress = $"{AppConfig.BASE_ADDRESS}/service";
appConfig.ServiceEventName = $@"Global\{nameof(SafeExamBrowser)}-{Guid.NewGuid()}";
appConfig.ServiceLogFilePath = Path.Combine(logFolder, $"{logFilePrefix}_Service.log");
@@ -79,7 +78,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
var configuration = new SessionConfiguration();
appConfig.ClientId = Guid.NewGuid();
- appConfig.ClientAddress = $"{BASE_ADDRESS}/client/{Guid.NewGuid()}";
+ appConfig.ClientAddress = $"{AppConfig.BASE_ADDRESS}/client/{Guid.NewGuid()}";
appConfig.ServiceEventName = $@"Global\{nameof(SafeExamBrowser)}-{Guid.NewGuid()}";
configuration.AppConfig = appConfig.Clone();
diff --git a/SafeExamBrowser.Contracts/Configuration/AppConfig.cs b/SafeExamBrowser.Contracts/Configuration/AppConfig.cs
index 8e8bfb06..9e6ff7e7 100644
--- a/SafeExamBrowser.Contracts/Configuration/AppConfig.cs
+++ b/SafeExamBrowser.Contracts/Configuration/AppConfig.cs
@@ -16,6 +16,21 @@ namespace SafeExamBrowser.Contracts.Configuration
[Serializable]
public class AppConfig
{
+ ///
+ /// The name of the backup data file used by the service component.
+ ///
+ public const string BACKUP_FILE_NAME = "Backup.bin";
+
+ ///
+ /// The base address for all communication hosts of the application.
+ ///
+ public const string BASE_ADDRESS = "net.pipe://localhost/safeexambrowser";
+
+ ///
+ /// The communication address of the service component.
+ ///
+ public const string SERVICE_ADDRESS = BASE_ADDRESS + "/service";
+
///
/// The file path of the local client configuration for the active user.
///
diff --git a/SafeExamBrowser.Contracts/Lockdown/IAutoRestoreMechanism.cs b/SafeExamBrowser.Contracts/Lockdown/IAutoRestoreMechanism.cs
new file mode 100644
index 00000000..48d8d423
--- /dev/null
+++ b/SafeExamBrowser.Contracts/Lockdown/IAutoRestoreMechanism.cs
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
+ *
+ * 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/.
+ */
+
+namespace SafeExamBrowser.Contracts.Lockdown
+{
+ ///
+ /// Defines a mechanism which tries to restore all changes saved in a .
+ ///
+ public interface IAutoRestoreMechanism
+ {
+ ///
+ /// Starts the procedure.
+ ///
+ void Start();
+
+ ///
+ /// Stops the procedure.
+ ///
+ void Stop();
+ }
+}
diff --git a/SafeExamBrowser.Contracts/Lockdown/IFeatureConfiguration.cs b/SafeExamBrowser.Contracts/Lockdown/IFeatureConfiguration.cs
index eff72b83..45d769f1 100644
--- a/SafeExamBrowser.Contracts/Lockdown/IFeatureConfiguration.cs
+++ b/SafeExamBrowser.Contracts/Lockdown/IFeatureConfiguration.cs
@@ -6,6 +6,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+using System;
+
namespace SafeExamBrowser.Contracts.Lockdown
{
///
@@ -13,6 +15,16 @@ namespace SafeExamBrowser.Contracts.Lockdown
///
public interface IFeatureConfiguration
{
+ ///
+ /// The unique identifier of this feature configuration.
+ ///
+ Guid Id { get; }
+
+ ///
+ /// The identifier of the group of changes to which this feature configuration belongs.
+ ///
+ Guid GroupId { get; }
+
///
/// Disables the feature.
///
@@ -29,7 +41,7 @@ namespace SafeExamBrowser.Contracts.Lockdown
void Monitor();
///
- /// Restores the feature to its initial configuration.
+ /// Restores the feature to its previous configuration (i.e. before it was enabled or disabled).
///
void Restore();
}
diff --git a/SafeExamBrowser.Contracts/Lockdown/IFeatureConfigurationBackup.cs b/SafeExamBrowser.Contracts/Lockdown/IFeatureConfigurationBackup.cs
index b430486c..6815e23c 100644
--- a/SafeExamBrowser.Contracts/Lockdown/IFeatureConfigurationBackup.cs
+++ b/SafeExamBrowser.Contracts/Lockdown/IFeatureConfigurationBackup.cs
@@ -6,6 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+using System;
using System.Collections.Generic;
namespace SafeExamBrowser.Contracts.Lockdown
@@ -15,19 +16,24 @@ namespace SafeExamBrowser.Contracts.Lockdown
///
public interface IFeatureConfigurationBackup
{
+ ///
+ /// Deletes the given from the backup repository.
+ ///
+ void Delete(IFeatureConfiguration configuration);
+
///
/// Gets all currently saved in the backup repository.
///
- IList GetConfigurations();
+ IList GetAllConfigurations();
+
+ ///
+ /// Gets all which are part of the given group.
+ ///
+ IList GetBy(Guid groupId);
///
/// Saves the given in the backup repository.
///
void Save(IFeatureConfiguration configuration);
-
- ///
- /// Deletes the given from the backup repository.
- ///
- void Delete(IFeatureConfiguration configuration);
}
}
diff --git a/SafeExamBrowser.Contracts/Lockdown/IFeatureConfigurationFactory.cs b/SafeExamBrowser.Contracts/Lockdown/IFeatureConfigurationFactory.cs
index 6d355c7f..96042d63 100644
--- a/SafeExamBrowser.Contracts/Lockdown/IFeatureConfigurationFactory.cs
+++ b/SafeExamBrowser.Contracts/Lockdown/IFeatureConfigurationFactory.cs
@@ -6,6 +6,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+using System;
+
namespace SafeExamBrowser.Contracts.Lockdown
{
///
@@ -16,61 +18,61 @@ namespace SafeExamBrowser.Contracts.Lockdown
///
/// Creates an to control notifications of the Google Chrome browser.
///
- IFeatureConfiguration CreateChromeNotificationConfiguration();
+ IFeatureConfiguration CreateChromeNotificationConfiguration(Guid groupId);
///
/// Creates an to control the ease of access options on the security screen.
///
- IFeatureConfiguration CreateEaseOfAccessConfiguration();
+ IFeatureConfiguration CreateEaseOfAccessConfiguration(Guid groupId);
///
/// Creates an to control the network options on the security screen.
///
- IFeatureConfiguration CreateNetworkOptionsConfiguration();
+ IFeatureConfiguration CreateNetworkOptionsConfiguration(Guid groupId);
///
/// Creates an to control the option to change the password of a user account via the security screen.
///
- IFeatureConfiguration CreatePasswordChangeConfiguration();
+ IFeatureConfiguration CreatePasswordChangeConfiguration(Guid groupId);
///
/// Creates an to control the power options on the security screen.
///
- IFeatureConfiguration CreatePowerOptionsConfiguration();
+ IFeatureConfiguration CreatePowerOptionsConfiguration(Guid groupId);
///
/// Creates an to control remote desktop connections.
///
- IFeatureConfiguration CreateRemoteConnectionConfiguration();
+ IFeatureConfiguration CreateRemoteConnectionConfiguration(Guid groupId);
///
/// Creates an to control the option to sign out out via security screen.
///
- IFeatureConfiguration CreateSignoutConfiguration();
+ IFeatureConfiguration CreateSignoutConfiguration(Guid groupId);
///
/// Creates an to control the task manager of Windows.
///
- IFeatureConfiguration CreateTaskManagerConfiguration();
+ IFeatureConfiguration CreateTaskManagerConfiguration(Guid groupId);
///
/// Creates an to control the option to lock the computer via the security screen.
///
- IFeatureConfiguration CreateUserLockConfiguration();
+ IFeatureConfiguration CreateUserLockConfiguration(Guid groupId);
///
/// Creates an to control the option to switch to another user account via the security screen.
///
- IFeatureConfiguration CreateUserSwitchConfiguration();
+ IFeatureConfiguration CreateUserSwitchConfiguration(Guid groupId);
///
/// Creates an to control the user interface overlay for VMware clients.
///
- IFeatureConfiguration CreateVmwareOverlayConfiguration();
+ IFeatureConfiguration CreateVmwareOverlayConfiguration(Guid groupId);
///
/// Creates an to control Windows Update.
///
- IFeatureConfiguration CreateWindowsUpdateConfiguration();
+ IFeatureConfiguration CreateWindowsUpdateConfiguration(Guid groupId);
}
}
diff --git a/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj b/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj
index fd10f1e7..880ad5ce 100644
--- a/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj
+++ b/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj
@@ -92,6 +92,7 @@
+
diff --git a/SafeExamBrowser.Lockdown/AutoRestoreMechanism.cs b/SafeExamBrowser.Lockdown/AutoRestoreMechanism.cs
new file mode 100644
index 00000000..9d042abd
--- /dev/null
+++ b/SafeExamBrowser.Lockdown/AutoRestoreMechanism.cs
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
+ *
+ * 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 SafeExamBrowser.Contracts.Lockdown;
+
+namespace SafeExamBrowser.Lockdown
+{
+ public class AutoRestoreMechanism : IAutoRestoreMechanism
+ {
+ private IFeatureConfigurationBackup backup;
+
+ public AutoRestoreMechanism(IFeatureConfigurationBackup backup)
+ {
+ this.backup = backup;
+ }
+
+ public void Start()
+ {
+
+ }
+
+ public void Stop()
+ {
+
+ }
+ }
+}
diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurationBackup.cs b/SafeExamBrowser.Lockdown/FeatureConfigurationBackup.cs
index ab4eedf6..cb87b87a 100644
--- a/SafeExamBrowser.Lockdown/FeatureConfigurationBackup.cs
+++ b/SafeExamBrowser.Lockdown/FeatureConfigurationBackup.cs
@@ -6,7 +6,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+using System;
using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
using SafeExamBrowser.Contracts.Lockdown;
using SafeExamBrowser.Contracts.Logging;
@@ -14,26 +19,114 @@ namespace SafeExamBrowser.Lockdown
{
public class FeatureConfigurationBackup : IFeatureConfigurationBackup
{
- private ILogger logger;
+ private readonly object @lock = new object();
- public FeatureConfigurationBackup(ILogger logger)
+ private string filePath;
+ private IModuleLogger logger;
+
+ public FeatureConfigurationBackup(string filePath, IModuleLogger logger)
{
+ this.filePath = filePath;
this.logger = logger;
}
public void Delete(IFeatureConfiguration configuration)
{
-
+ lock (@lock)
+ {
+ var configurations = LoadFromFile();
+ var obsolete = configurations.Find(c => c.Id == configuration.Id);
+
+ if (obsolete != default(IFeatureConfiguration))
+ {
+ configurations.Remove(obsolete);
+ SaveToFile(configurations);
+ logger.Info($"Successfully removed {configuration} from backup.");
+ }
+ else
+ {
+ logger.Warn($"Could not delete {configuration} as it does not exists in backup!");
+ }
+ }
}
- public IList GetConfigurations()
+ public IList GetAllConfigurations()
{
- return new List();
+ lock (@lock)
+ {
+ return LoadFromFile();
+ }
+ }
+
+ public IList GetBy(Guid groupId)
+ {
+ lock (@lock)
+ {
+ return LoadFromFile().Where(c => c.GroupId == groupId).ToList();
+ }
}
public void Save(IFeatureConfiguration configuration)
{
-
+ lock (@lock)
+ {
+ var configurations = LoadFromFile();
+
+ configurations.Add(configuration);
+ SaveToFile(configurations);
+ logger.Info($"Successfully added {configuration} to backup.");
+ }
+ }
+
+ private void SaveToFile(List configurations)
+ {
+ try
+ {
+ logger.Debug($"Attempting to save backup data to '{filePath}'...");
+
+ using (var stream = File.Open(filePath, FileMode.Create))
+ {
+ new BinaryFormatter().Serialize(stream, configurations);
+ }
+
+ logger.Debug($"Successfully saved {configurations.Count} items.");
+ }
+ catch (Exception e)
+ {
+ logger.Error($"Failed to save backup data to '{filePath}'!", e);
+ }
+ }
+
+ private List LoadFromFile()
+ {
+ var configurations = new List();
+
+ try
+ {
+ if (File.Exists(filePath))
+ {
+ var context = new StreamingContext(StreamingContextStates.All, logger);
+
+ logger.Debug($"Attempting to load backup data from '{filePath}'...");
+
+ using (var stream = File.Open(filePath, FileMode.Open))
+ {
+ configurations = (List) new BinaryFormatter(null, context).Deserialize(stream);
+ }
+
+ logger.Debug($"Backup data successfully loaded, found {configurations.Count} items.");
+ }
+ else
+ {
+ logger.Debug($"No backup data found under '{filePath}'.");
+ }
+ }
+ catch (Exception e)
+ {
+ logger.Error($"Failed to load backup data from '{filePath}'!", e);
+ }
+
+ return configurations;
}
}
}
diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurationFactory.cs b/SafeExamBrowser.Lockdown/FeatureConfigurationFactory.cs
index 304120e5..c3e9d0d2 100644
--- a/SafeExamBrowser.Lockdown/FeatureConfigurationFactory.cs
+++ b/SafeExamBrowser.Lockdown/FeatureConfigurationFactory.cs
@@ -6,6 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+using System;
using SafeExamBrowser.Contracts.Lockdown;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Lockdown.FeatureConfigurations;
@@ -21,64 +22,64 @@ namespace SafeExamBrowser.Lockdown
this.logger = logger;
}
- public IFeatureConfiguration CreateChromeNotificationConfiguration()
+ public IFeatureConfiguration CreateChromeNotificationConfiguration(Guid groupId)
{
- return new ChromeNotificationConfiguration();
+ return new ChromeNotificationConfiguration(groupId, logger.CloneFor(nameof(ChromeNotificationConfiguration)));
}
- public IFeatureConfiguration CreateEaseOfAccessConfiguration()
+ public IFeatureConfiguration CreateEaseOfAccessConfiguration(Guid groupId)
{
- return new EaseOfAccessConfiguration();
+ return new EaseOfAccessConfiguration(groupId, logger.CloneFor(nameof(EaseOfAccessConfiguration)));
}
- public IFeatureConfiguration CreateNetworkOptionsConfiguration()
+ public IFeatureConfiguration CreateNetworkOptionsConfiguration(Guid groupId)
{
- return new NetworkOptionsConfiguration();
+ return new NetworkOptionsConfiguration(groupId, logger.CloneFor(nameof(NetworkOptionsConfiguration)));
}
- public IFeatureConfiguration CreatePasswordChangeConfiguration()
+ public IFeatureConfiguration CreatePasswordChangeConfiguration(Guid groupId)
{
- return new PasswordChangeConfiguration();
+ return new PasswordChangeConfiguration(groupId, logger.CloneFor(nameof(PasswordChangeConfiguration)));
}
- public IFeatureConfiguration CreatePowerOptionsConfiguration()
+ public IFeatureConfiguration CreatePowerOptionsConfiguration(Guid groupId)
{
- return new PowerOptionsConfiguration();
+ return new PowerOptionsConfiguration(groupId, logger.CloneFor(nameof(PowerOptionsConfiguration)));
}
- public IFeatureConfiguration CreateRemoteConnectionConfiguration()
+ public IFeatureConfiguration CreateRemoteConnectionConfiguration(Guid groupId)
{
- return new RemoteConnectionConfiguration();
+ return new RemoteConnectionConfiguration(groupId, logger.CloneFor(nameof(RemoteConnectionConfiguration)));
}
- public IFeatureConfiguration CreateSignoutConfiguration()
+ public IFeatureConfiguration CreateSignoutConfiguration(Guid groupId)
{
- return new SignoutConfiguration();
+ return new SignoutConfiguration(groupId, logger.CloneFor(nameof(SignoutConfiguration)));
}
- public IFeatureConfiguration CreateTaskManagerConfiguration()
+ public IFeatureConfiguration CreateTaskManagerConfiguration(Guid groupId)
{
- return new TaskManagerConfiguration();
+ return new TaskManagerConfiguration(groupId, logger.CloneFor(nameof(TaskManagerConfiguration)));
}
- public IFeatureConfiguration CreateUserLockConfiguration()
+ public IFeatureConfiguration CreateUserLockConfiguration(Guid groupId)
{
- return new UserLockConfiguration();
+ return new UserLockConfiguration(groupId, logger.CloneFor(nameof(UserLockConfiguration)));
}
- public IFeatureConfiguration CreateUserSwitchConfiguration()
+ public IFeatureConfiguration CreateUserSwitchConfiguration(Guid groupId)
{
- return new UserSwitchConfiguration();
+ return new UserSwitchConfiguration(groupId, logger.CloneFor(nameof(UserSwitchConfiguration)));
}
- public IFeatureConfiguration CreateVmwareOverlayConfiguration()
+ public IFeatureConfiguration CreateVmwareOverlayConfiguration(Guid groupId)
{
- return new VmwareOverlayConfiguration();
+ return new VmwareOverlayConfiguration(groupId, logger.CloneFor(nameof(VmwareOverlayConfiguration)));
}
- public IFeatureConfiguration CreateWindowsUpdateConfiguration()
+ public IFeatureConfiguration CreateWindowsUpdateConfiguration(Guid groupId)
{
- return new WindowsUpdateConfiguration();
+ return new WindowsUpdateConfiguration(groupId, logger.CloneFor(nameof(WindowsUpdateConfiguration)));
}
}
}
diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/ChromeNotificationConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/ChromeNotificationConfiguration.cs
index cae32eea..490af30c 100644
--- a/SafeExamBrowser.Lockdown/FeatureConfigurations/ChromeNotificationConfiguration.cs
+++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/ChromeNotificationConfiguration.cs
@@ -6,30 +6,36 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-using SafeExamBrowser.Contracts.Lockdown;
+using System;
+using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations
{
- internal class ChromeNotificationConfiguration : IFeatureConfiguration
+ [Serializable]
+ internal class ChromeNotificationConfiguration : FeatureConfiguration
{
- public void DisableFeature()
+ public ChromeNotificationConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
{
-
}
- public void EnableFeature()
+ public override void DisableFeature()
{
-
+ logger.Info("Disabling...");
}
- public void Monitor()
+ public override void EnableFeature()
{
-
+ logger.Info("Enabling...");
}
- public void Restore()
+ public override void Monitor()
{
-
+ logger.Info("Monitoring...");
+ }
+
+ public override void Restore()
+ {
+ logger.Info("Restoring...");
}
}
}
diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/EaseOfAccessConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/EaseOfAccessConfiguration.cs
index 97ca0d01..3b876d95 100644
--- a/SafeExamBrowser.Lockdown/FeatureConfigurations/EaseOfAccessConfiguration.cs
+++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/EaseOfAccessConfiguration.cs
@@ -6,28 +6,34 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-using SafeExamBrowser.Contracts.Lockdown;
+using System;
+using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations
{
- internal class EaseOfAccessConfiguration : IFeatureConfiguration
+ [Serializable]
+ internal class EaseOfAccessConfiguration : FeatureConfiguration
{
- public void DisableFeature()
+ public EaseOfAccessConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
+ {
+ }
+
+ public override void DisableFeature()
{
}
- public void EnableFeature()
+ public override void EnableFeature()
{
}
- public void Monitor()
+ public override void Monitor()
{
}
- public void Restore()
+ public override void Restore()
{
}
diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/FeatureConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/FeatureConfiguration.cs
new file mode 100644
index 00000000..63e00ddd
--- /dev/null
+++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/FeatureConfiguration.cs
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
+ *
+ * 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.Runtime.Serialization;
+using SafeExamBrowser.Contracts.Lockdown;
+using SafeExamBrowser.Contracts.Logging;
+
+namespace SafeExamBrowser.Lockdown.FeatureConfigurations
+{
+ [Serializable]
+ internal abstract class FeatureConfiguration : IFeatureConfiguration
+ {
+ [NonSerialized]
+ protected ILogger logger;
+
+ public Guid Id { get; }
+ public Guid GroupId { get; }
+
+ public FeatureConfiguration(Guid groupId, ILogger logger)
+ {
+ this.GroupId = groupId;
+ this.Id = Guid.NewGuid();
+ this.logger = logger;
+ }
+
+ public abstract void DisableFeature();
+ public abstract void EnableFeature();
+ public abstract void Monitor();
+ public abstract void Restore();
+
+ public override string ToString()
+ {
+ return $"{GetType().Name} ({Id})";
+ }
+
+ [OnDeserialized]
+ private void OnDeserializedMethod(StreamingContext context)
+ {
+ logger = (context.Context as IModuleLogger).CloneFor(GetType().Name);
+ }
+ }
+}
diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/NetworkOptionsConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/NetworkOptionsConfiguration.cs
index 69732113..eedb2258 100644
--- a/SafeExamBrowser.Lockdown/FeatureConfigurations/NetworkOptionsConfiguration.cs
+++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/NetworkOptionsConfiguration.cs
@@ -6,28 +6,34 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-using SafeExamBrowser.Contracts.Lockdown;
+using System;
+using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations
{
- internal class NetworkOptionsConfiguration : IFeatureConfiguration
+ [Serializable]
+ internal class NetworkOptionsConfiguration : FeatureConfiguration
{
- public void DisableFeature()
+ public NetworkOptionsConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
+ {
+ }
+
+ public override void DisableFeature()
{
}
- public void EnableFeature()
+ public override void EnableFeature()
{
}
- public void Monitor()
+ public override void Monitor()
{
}
- public void Restore()
+ public override void Restore()
{
}
diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/PasswordChangeConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/PasswordChangeConfiguration.cs
index 32f8081c..f8051df9 100644
--- a/SafeExamBrowser.Lockdown/FeatureConfigurations/PasswordChangeConfiguration.cs
+++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/PasswordChangeConfiguration.cs
@@ -6,28 +6,34 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-using SafeExamBrowser.Contracts.Lockdown;
+using System;
+using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations
{
- internal class PasswordChangeConfiguration : IFeatureConfiguration
+ [Serializable]
+ internal class PasswordChangeConfiguration : FeatureConfiguration
{
- public void DisableFeature()
+ public PasswordChangeConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
+ {
+ }
+
+ public override void DisableFeature()
{
}
- public void EnableFeature()
+ public override void EnableFeature()
{
}
- public void Monitor()
+ public override void Monitor()
{
}
- public void Restore()
+ public override void Restore()
{
}
diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/PowerOptionsConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/PowerOptionsConfiguration.cs
index da9391f8..f7be1c5d 100644
--- a/SafeExamBrowser.Lockdown/FeatureConfigurations/PowerOptionsConfiguration.cs
+++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/PowerOptionsConfiguration.cs
@@ -6,28 +6,34 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-using SafeExamBrowser.Contracts.Lockdown;
+using System;
+using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations
{
- internal class PowerOptionsConfiguration : IFeatureConfiguration
+ [Serializable]
+ internal class PowerOptionsConfiguration : FeatureConfiguration
{
- public void DisableFeature()
+ public PowerOptionsConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
+ {
+ }
+
+ public override void DisableFeature()
{
}
- public void EnableFeature()
+ public override void EnableFeature()
{
}
- public void Monitor()
+ public override void Monitor()
{
}
- public void Restore()
+ public override void Restore()
{
}
diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/RemoteConnectionConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/RemoteConnectionConfiguration.cs
index f5ba59cc..e1b15e0c 100644
--- a/SafeExamBrowser.Lockdown/FeatureConfigurations/RemoteConnectionConfiguration.cs
+++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/RemoteConnectionConfiguration.cs
@@ -6,28 +6,34 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-using SafeExamBrowser.Contracts.Lockdown;
+using System;
+using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations
{
- internal class RemoteConnectionConfiguration : IFeatureConfiguration
+ [Serializable]
+ internal class RemoteConnectionConfiguration : FeatureConfiguration
{
- public void DisableFeature()
+ public RemoteConnectionConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
+ {
+ }
+
+ public override void DisableFeature()
{
}
- public void EnableFeature()
+ public override void EnableFeature()
{
}
- public void Monitor()
+ public override void Monitor()
{
}
- public void Restore()
+ public override void Restore()
{
}
diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/SignoutConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/SignoutConfiguration.cs
index d225acca..43d78ea0 100644
--- a/SafeExamBrowser.Lockdown/FeatureConfigurations/SignoutConfiguration.cs
+++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/SignoutConfiguration.cs
@@ -6,28 +6,34 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-using SafeExamBrowser.Contracts.Lockdown;
+using System;
+using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations
{
- internal class SignoutConfiguration : IFeatureConfiguration
+ [Serializable]
+ internal class SignoutConfiguration : FeatureConfiguration
{
- public void DisableFeature()
+ public SignoutConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
+ {
+ }
+
+ public override void DisableFeature()
{
}
- public void EnableFeature()
+ public override void EnableFeature()
{
}
- public void Monitor()
+ public override void Monitor()
{
}
- public void Restore()
+ public override void Restore()
{
}
diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/TaskManagerConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/TaskManagerConfiguration.cs
index 1bda3ab0..960ef92f 100644
--- a/SafeExamBrowser.Lockdown/FeatureConfigurations/TaskManagerConfiguration.cs
+++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/TaskManagerConfiguration.cs
@@ -6,28 +6,34 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-using SafeExamBrowser.Contracts.Lockdown;
+using System;
+using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations
{
- internal class TaskManagerConfiguration : IFeatureConfiguration
+ [Serializable]
+ internal class TaskManagerConfiguration : FeatureConfiguration
{
- public void DisableFeature()
+ public TaskManagerConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
+ {
+ }
+
+ public override void DisableFeature()
{
}
- public void EnableFeature()
+ public override void EnableFeature()
{
}
- public void Monitor()
+ public override void Monitor()
{
}
- public void Restore()
+ public override void Restore()
{
}
diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/UserLockConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/UserLockConfiguration.cs
index bb65bc96..03dd2578 100644
--- a/SafeExamBrowser.Lockdown/FeatureConfigurations/UserLockConfiguration.cs
+++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/UserLockConfiguration.cs
@@ -6,28 +6,34 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-using SafeExamBrowser.Contracts.Lockdown;
+using System;
+using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations
{
- internal class UserLockConfiguration : IFeatureConfiguration
+ [Serializable]
+ internal class UserLockConfiguration : FeatureConfiguration
{
- public void DisableFeature()
+ public UserLockConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
+ {
+ }
+
+ public override void DisableFeature()
{
}
- public void EnableFeature()
+ public override void EnableFeature()
{
}
- public void Monitor()
+ public override void Monitor()
{
}
- public void Restore()
+ public override void Restore()
{
}
diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/UserSwitchConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/UserSwitchConfiguration.cs
index 041028d4..602dbfbf 100644
--- a/SafeExamBrowser.Lockdown/FeatureConfigurations/UserSwitchConfiguration.cs
+++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/UserSwitchConfiguration.cs
@@ -6,28 +6,34 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-using SafeExamBrowser.Contracts.Lockdown;
+using System;
+using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations
{
- internal class UserSwitchConfiguration : IFeatureConfiguration
+ [Serializable]
+ internal class UserSwitchConfiguration : FeatureConfiguration
{
- public void DisableFeature()
+ public UserSwitchConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
+ {
+ }
+
+ public override void DisableFeature()
{
}
- public void EnableFeature()
+ public override void EnableFeature()
{
}
- public void Monitor()
+ public override void Monitor()
{
}
- public void Restore()
+ public override void Restore()
{
}
diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/VmwareOverlayConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/VmwareOverlayConfiguration.cs
index a1ff38d7..55454767 100644
--- a/SafeExamBrowser.Lockdown/FeatureConfigurations/VmwareOverlayConfiguration.cs
+++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/VmwareOverlayConfiguration.cs
@@ -6,28 +6,34 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-using SafeExamBrowser.Contracts.Lockdown;
+using System;
+using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations
{
- internal class VmwareOverlayConfiguration : IFeatureConfiguration
+ [Serializable]
+ internal class VmwareOverlayConfiguration : FeatureConfiguration
{
- public void DisableFeature()
+ public VmwareOverlayConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
+ {
+ }
+
+ public override void DisableFeature()
{
}
- public void EnableFeature()
+ public override void EnableFeature()
{
}
- public void Monitor()
+ public override void Monitor()
{
}
- public void Restore()
+ public override void Restore()
{
}
diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/WindowsUpdateConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/WindowsUpdateConfiguration.cs
index 82b5afc4..b89b4fbb 100644
--- a/SafeExamBrowser.Lockdown/FeatureConfigurations/WindowsUpdateConfiguration.cs
+++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/WindowsUpdateConfiguration.cs
@@ -6,28 +6,34 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-using SafeExamBrowser.Contracts.Lockdown;
+using System;
+using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations
{
- internal class WindowsUpdateConfiguration : IFeatureConfiguration
+ [Serializable]
+ internal class WindowsUpdateConfiguration : FeatureConfiguration
{
- public void DisableFeature()
+ public WindowsUpdateConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
+ {
+ }
+
+ public override void DisableFeature()
{
}
- public void EnableFeature()
+ public override void EnableFeature()
{
}
- public void Monitor()
+ public override void Monitor()
{
}
- public void Restore()
+ public override void Restore()
{
}
diff --git a/SafeExamBrowser.Lockdown/SafeExamBrowser.Lockdown.csproj b/SafeExamBrowser.Lockdown/SafeExamBrowser.Lockdown.csproj
index 63e5862c..80bac0d4 100644
--- a/SafeExamBrowser.Lockdown/SafeExamBrowser.Lockdown.csproj
+++ b/SafeExamBrowser.Lockdown/SafeExamBrowser.Lockdown.csproj
@@ -53,9 +53,11 @@
+
+
diff --git a/SafeExamBrowser.Service.UnitTests/Operations/SessionInitializationOperationTests.cs b/SafeExamBrowser.Service.UnitTests/Operations/SessionInitializationOperationTests.cs
index 07ca7972..56f881d7 100644
--- a/SafeExamBrowser.Service.UnitTests/Operations/SessionInitializationOperationTests.cs
+++ b/SafeExamBrowser.Service.UnitTests/Operations/SessionInitializationOperationTests.cs
@@ -14,6 +14,7 @@ using Moq;
using SafeExamBrowser.Contracts.Communication.Hosts;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Core.OperationModel;
+using SafeExamBrowser.Contracts.Lockdown;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Service.Operations;
@@ -22,6 +23,7 @@ namespace SafeExamBrowser.Service.UnitTests.Operations
[TestClass]
public class SessionInitializationOperationTests
{
+ private Mock autoRestoreMechanism;
private Mock logger;
private Mock> logWriterFactory;
private Mock serviceHost;
@@ -32,6 +34,7 @@ namespace SafeExamBrowser.Service.UnitTests.Operations
[TestInitialize]
public void Initialize()
{
+ autoRestoreMechanism = new Mock();
logger = new Mock();
logWriterFactory = new Mock>();
serviceHost = new Mock();
@@ -40,6 +43,7 @@ namespace SafeExamBrowser.Service.UnitTests.Operations
logWriterFactory.Setup(f => f.Invoke(It.IsAny())).Returns(new Mock().Object);
serviceEventFactory.Setup(f => f.Invoke(It.IsAny())).Returns(new EventStub());
+ sessionContext.AutoRestoreMechanism = autoRestoreMechanism.Object;
sessionContext.Configuration = new ServiceConfiguration
{
AppConfig = new AppConfig { ServiceEventName = $"{nameof(SafeExamBrowser)}-{nameof(SessionInitializationOperationTests)}" }
@@ -74,18 +78,12 @@ namespace SafeExamBrowser.Service.UnitTests.Operations
}
[TestMethod]
- public void Revert_MustSetServiceEvent()
+ public void Perform_MustStopAutoRestoreMechanism()
{
- sessionContext.ServiceEvent = new EventWaitHandle(false, EventResetMode.AutoReset);
-
- var wasSet = false;
- var task = Task.Run(() => wasSet = sessionContext.ServiceEvent.WaitOne(1000));
- var result = sut.Revert();
-
- task.Wait();
+ var result = sut.Perform();
+ autoRestoreMechanism.Verify(m => m.Stop(), Times.Once);
Assert.AreEqual(OperationResult.Success, result);
- Assert.IsTrue(wasSet);
}
[TestMethod]
@@ -110,5 +108,29 @@ namespace SafeExamBrowser.Service.UnitTests.Operations
serviceHost.VerifySet(h => h.AllowConnection = true, Times.Once);
Assert.AreEqual(OperationResult.Success, result);
}
+
+ [TestMethod]
+ public void Revert_MustSetServiceEvent()
+ {
+ sessionContext.ServiceEvent = new EventWaitHandle(false, EventResetMode.AutoReset);
+
+ var wasSet = false;
+ var task = Task.Run(() => wasSet = sessionContext.ServiceEvent.WaitOne(1000));
+ var result = sut.Revert();
+
+ task.Wait();
+
+ Assert.AreEqual(OperationResult.Success, result);
+ Assert.IsTrue(wasSet);
+ }
+
+ [TestMethod]
+ public void Revert_MustStartAutoRestoreMechanism()
+ {
+ var result = sut.Revert();
+
+ autoRestoreMechanism.Verify(m => m.Start(), Times.Once);
+ Assert.AreEqual(OperationResult.Success, result);
+ }
}
}
diff --git a/SafeExamBrowser.Service/CompositionRoot.cs b/SafeExamBrowser.Service/CompositionRoot.cs
index 189361ab..d391edca 100644
--- a/SafeExamBrowser.Service/CompositionRoot.cs
+++ b/SafeExamBrowser.Service/CompositionRoot.cs
@@ -14,6 +14,7 @@ using System.Security.Principal;
using System.Threading;
using SafeExamBrowser.Communication.Hosts;
using SafeExamBrowser.Communication.Proxies;
+using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Core.OperationModel;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Contracts.Service;
@@ -34,21 +35,23 @@ namespace SafeExamBrowser.Service
internal void BuildObjectGraph()
{
- const string SERVICE_ADDRESS = "net.pipe://localhost/safeexambrowser/service";
const int FIVE_SECONDS = 5000;
+ var backupFile = BuildBackupFilePath();
InitializeLogging();
- var featureBackup = new FeatureConfigurationBackup(new ModuleLogger(logger, nameof(FeatureConfigurationBackup)));
+ var featureBackup = new FeatureConfigurationBackup(backupFile, new ModuleLogger(logger, nameof(FeatureConfigurationBackup)));
var featureFactory = new FeatureConfigurationFactory(new ModuleLogger(logger, nameof(FeatureConfigurationFactory)));
var proxyFactory = new ProxyFactory(new ProxyObjectFactory(), new ModuleLogger(logger, nameof(ProxyFactory)));
- var serviceHost = new ServiceHost(SERVICE_ADDRESS, new HostObjectFactory(), new ModuleLogger(logger, nameof(ServiceHost)), FIVE_SECONDS);
+ var serviceHost = new ServiceHost(AppConfig.SERVICE_ADDRESS, new HostObjectFactory(), new ModuleLogger(logger, nameof(ServiceHost)), FIVE_SECONDS);
var sessionContext = new SessionContext();
var bootstrapOperations = new Queue();
var sessionOperations = new Queue();
- bootstrapOperations.Enqueue(new RestoreOperation(logger));
+ sessionContext.AutoRestoreMechanism = new AutoRestoreMechanism(featureBackup);
+
+ bootstrapOperations.Enqueue(new RestoreOperation(featureBackup, logger, sessionContext));
bootstrapOperations.Enqueue(new CommunicationHostOperation(serviceHost, logger));
bootstrapOperations.Enqueue(new ServiceEventCleanupOperation(logger, sessionContext));
@@ -62,6 +65,14 @@ namespace SafeExamBrowser.Service
ServiceController = new ServiceController(logger, bootstrapSequence, sessionSequence, serviceHost, sessionContext);
}
+ private string BuildBackupFilePath()
+ {
+ var appDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), nameof(SafeExamBrowser));
+ var filePath = Path.Combine(appDataFolder, AppConfig.BACKUP_FILE_NAME);
+
+ return filePath;
+ }
+
internal void LogStartupInformation()
{
logger.Log($"# Service started at {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
diff --git a/SafeExamBrowser.Service/Operations/LockdownOperation.cs b/SafeExamBrowser.Service/Operations/LockdownOperation.cs
index a84e001a..e7bc5808 100644
--- a/SafeExamBrowser.Service/Operations/LockdownOperation.cs
+++ b/SafeExamBrowser.Service/Operations/LockdownOperation.cs
@@ -6,6 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+using System;
using SafeExamBrowser.Contracts.Core.OperationModel;
using SafeExamBrowser.Contracts.Lockdown;
using SafeExamBrowser.Contracts.Logging;
@@ -17,6 +18,7 @@ namespace SafeExamBrowser.Service.Operations
private IFeatureConfigurationBackup backup;
private IFeatureConfigurationFactory factory;
private ILogger logger;
+ private Guid groupId;
public LockdownOperation(
IFeatureConfigurationBackup backup,
@@ -31,18 +33,21 @@ namespace SafeExamBrowser.Service.Operations
public override OperationResult Perform()
{
- var chromeNotification = factory.CreateChromeNotificationConfiguration();
- var easeOfAccess = factory.CreateEaseOfAccessConfiguration();
- var networkOptions = factory.CreateNetworkOptionsConfiguration();
- var passwordChange = factory.CreatePasswordChangeConfiguration();
- var powerOptions = factory.CreatePowerOptionsConfiguration();
- var remoteConnection = factory.CreateRemoteConnectionConfiguration();
- var signout = factory.CreateSignoutConfiguration();
- var taskManager = factory.CreateTaskManagerConfiguration();
- var userLock = factory.CreateUserLockConfiguration();
- var userSwitch = factory.CreateUserSwitchConfiguration();
- var vmwareOverlay = factory.CreateVmwareOverlayConfiguration();
- var windowsUpdate = factory.CreateWindowsUpdateConfiguration();
+ groupId = Guid.NewGuid();
+ logger.Info($"Attempting to perform lockdown (feature configuration group: {groupId})...");
+
+ var chromeNotification = factory.CreateChromeNotificationConfiguration(groupId);
+ var easeOfAccess = factory.CreateEaseOfAccessConfiguration(groupId);
+ var networkOptions = factory.CreateNetworkOptionsConfiguration(groupId);
+ var passwordChange = factory.CreatePasswordChangeConfiguration(groupId);
+ var powerOptions = factory.CreatePowerOptionsConfiguration(groupId);
+ var remoteConnection = factory.CreateRemoteConnectionConfiguration(groupId);
+ var signout = factory.CreateSignoutConfiguration(groupId);
+ var taskManager = factory.CreateTaskManagerConfiguration(groupId);
+ var userLock = factory.CreateUserLockConfiguration(groupId);
+ var userSwitch = factory.CreateUserSwitchConfiguration(groupId);
+ var vmwareOverlay = factory.CreateVmwareOverlayConfiguration(groupId);
+ var windowsUpdate = factory.CreateWindowsUpdateConfiguration(groupId);
SetConfiguration(chromeNotification, Context.Configuration.Settings.Service.DisableChromeNotifications);
SetConfiguration(easeOfAccess, Context.Configuration.Settings.Service.DisableEaseOfAccessOptions);
@@ -57,12 +62,16 @@ namespace SafeExamBrowser.Service.Operations
SetConfiguration(vmwareOverlay, Context.Configuration.Settings.Service.DisableVmwareOverlay);
SetConfiguration(windowsUpdate, Context.Configuration.Settings.Service.DisableWindowsUpdate);
+ logger.Info("Lockdown successful.");
+
return OperationResult.Success;
}
public override OperationResult Revert()
{
- var configurations = backup.GetConfigurations();
+ logger.Info($"Attempting to revert lockdown (feature configuration group: {groupId})...");
+
+ var configurations = backup.GetBy(groupId);
foreach (var configuration in configurations)
{
@@ -70,6 +79,8 @@ namespace SafeExamBrowser.Service.Operations
backup.Delete(configuration);
}
+ logger.Info("Lockdown reversion successful.");
+
return OperationResult.Success;
}
diff --git a/SafeExamBrowser.Service/Operations/RestoreOperation.cs b/SafeExamBrowser.Service/Operations/RestoreOperation.cs
index 1ec3f861..b1cd1518 100644
--- a/SafeExamBrowser.Service/Operations/RestoreOperation.cs
+++ b/SafeExamBrowser.Service/Operations/RestoreOperation.cs
@@ -8,32 +8,40 @@
using SafeExamBrowser.Contracts.Core.OperationModel;
using SafeExamBrowser.Contracts.Core.OperationModel.Events;
+using SafeExamBrowser.Contracts.Lockdown;
using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Service.Operations
{
internal class RestoreOperation : IOperation
{
+ private readonly IFeatureConfigurationBackup backup;
private ILogger logger;
+ private readonly SessionContext sessionContext;
public event ActionRequiredEventHandler ActionRequired { add { } remove { } }
public event StatusChangedEventHandler StatusChanged { add { } remove { } }
- public RestoreOperation(ILogger logger)
+ public RestoreOperation(IFeatureConfigurationBackup backup, ILogger logger, SessionContext sessionContext)
{
+ this.backup = backup;
this.logger = logger;
+ this.sessionContext = sessionContext;
}
public OperationResult Perform()
{
- // TODO: Must not delay startup! If restore does not succeed on first attempt, try again in separate thread!
- // -> Ensure session cannot be started until values are restored or alike!
+ logger.Info("Starting auto-restore mechanism...");
+ sessionContext.AutoRestoreMechanism.Start();
return OperationResult.Success;
}
public OperationResult Revert()
{
+ logger.Info("Stopping auto-restore mechanism...");
+ sessionContext.AutoRestoreMechanism.Stop();
+
return OperationResult.Success;
}
}
diff --git a/SafeExamBrowser.Service/Operations/SessionInitializationOperation.cs b/SafeExamBrowser.Service/Operations/SessionInitializationOperation.cs
index 6404c81c..3fe4747e 100644
--- a/SafeExamBrowser.Service/Operations/SessionInitializationOperation.cs
+++ b/SafeExamBrowser.Service/Operations/SessionInitializationOperation.cs
@@ -40,12 +40,16 @@ namespace SafeExamBrowser.Service.Operations
InitializeSessionWriter();
logger.Info("Initializing new session...");
-
- serviceHost.AllowConnection = false;
logger.Info($" -> Client-ID: {Context.Configuration.AppConfig.ClientId}");
logger.Info($" -> Runtime-ID: {Context.Configuration.AppConfig.RuntimeId}");
logger.Info($" -> Session-ID: {Context.Configuration.SessionId}");
+ logger.Info("Stopping auto-restore mechanism...");
+ Context.AutoRestoreMechanism.Stop();
+
+ logger.Info("Disabling service host...");
+ serviceHost.AllowConnection = false;
+
InitializeServiceEvent();
return OperationResult.Success;
@@ -71,11 +75,17 @@ namespace SafeExamBrowser.Service.Operations
}
}
- Context.Configuration = null;
- logger.Unsubscribe(sessionWriter);
- sessionWriter = null;
+ logger.Info("Starting auto-restore mechanism...");
+ Context.AutoRestoreMechanism.Start();
+
+ logger.Info("Enabling service host...");
serviceHost.AllowConnection = true;
+ logger.Info("Clearing session data...");
+ Context.Configuration = null;
+
+ FinalizeSessionWriter();
+
return success ? OperationResult.Success : OperationResult.Failed;
}
@@ -97,6 +107,14 @@ namespace SafeExamBrowser.Service.Operations
{
sessionWriter = logWriterFactory.Invoke(Context.Configuration.AppConfig.ServiceLogFilePath);
logger.Subscribe(sessionWriter);
+ logger.Debug($"Created session log file {Context.Configuration.AppConfig.ServiceLogFilePath}.");
+ }
+
+ private void FinalizeSessionWriter()
+ {
+ logger.Debug("Closed session log file.");
+ logger.Unsubscribe(sessionWriter);
+ sessionWriter = null;
}
}
}
diff --git a/SafeExamBrowser.Service/SessionContext.cs b/SafeExamBrowser.Service/SessionContext.cs
index f6716a8e..33ecb318 100644
--- a/SafeExamBrowser.Service/SessionContext.cs
+++ b/SafeExamBrowser.Service/SessionContext.cs
@@ -8,6 +8,7 @@
using System.Threading;
using SafeExamBrowser.Contracts.Configuration;
+using SafeExamBrowser.Contracts.Lockdown;
namespace SafeExamBrowser.Service
{
@@ -16,6 +17,11 @@ namespace SafeExamBrowser.Service
///
internal class SessionContext
{
+ ///
+ /// The mechanism trying to restore all changes after an application or system failure.
+ ///
+ internal IAutoRestoreMechanism AutoRestoreMechanism { get; set; }
+
///
/// The configuration of the currently active session.
///