diff --git a/SafeExamBrowser.Contracts/Lockdown/IFeatureConfiguration.cs b/SafeExamBrowser.Contracts/Lockdown/IFeatureConfiguration.cs index 59d02052..f525d062 100644 --- a/SafeExamBrowser.Contracts/Lockdown/IFeatureConfiguration.cs +++ b/SafeExamBrowser.Contracts/Lockdown/IFeatureConfiguration.cs @@ -35,6 +35,11 @@ namespace SafeExamBrowser.Contracts.Lockdown /// bool EnableFeature(); + /// + /// Initializes the currently active configuration of the feature. + /// + void Initialize(); + /// /// Starts monitoring the feature to ensure that it remains as currently configured. /// diff --git a/SafeExamBrowser.Contracts/Lockdown/IFeatureConfigurationFactory.cs b/SafeExamBrowser.Contracts/Lockdown/IFeatureConfigurationFactory.cs index 96042d63..2bb11693 100644 --- a/SafeExamBrowser.Contracts/Lockdown/IFeatureConfigurationFactory.cs +++ b/SafeExamBrowser.Contracts/Lockdown/IFeatureConfigurationFactory.cs @@ -18,7 +18,7 @@ namespace SafeExamBrowser.Contracts.Lockdown /// /// Creates an to control notifications of the Google Chrome browser. /// - IFeatureConfiguration CreateChromeNotificationConfiguration(Guid groupId); + IFeatureConfiguration CreateChromeNotificationConfiguration(Guid groupId, string sid, string userName); /// /// Creates an to control the ease of access options on the security screen. diff --git a/SafeExamBrowser.Lockdown.UnitTests/FeatureConfigurationStub.cs b/SafeExamBrowser.Lockdown.UnitTests/FeatureConfigurationStub.cs index a6f41d7a..b63ebdc3 100644 --- a/SafeExamBrowser.Lockdown.UnitTests/FeatureConfigurationStub.cs +++ b/SafeExamBrowser.Lockdown.UnitTests/FeatureConfigurationStub.cs @@ -32,6 +32,11 @@ namespace SafeExamBrowser.Lockdown.UnitTests throw new NotImplementedException(); } + public void Initialize() + { + throw new NotImplementedException(); + } + public void Monitor() { throw new NotImplementedException(); diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurationFactory.cs b/SafeExamBrowser.Lockdown/FeatureConfigurationFactory.cs index c3e9d0d2..b6fa7811 100644 --- a/SafeExamBrowser.Lockdown/FeatureConfigurationFactory.cs +++ b/SafeExamBrowser.Lockdown/FeatureConfigurationFactory.cs @@ -10,6 +10,7 @@ using System; using SafeExamBrowser.Contracts.Lockdown; using SafeExamBrowser.Contracts.Logging; using SafeExamBrowser.Lockdown.FeatureConfigurations; +using SafeExamBrowser.Lockdown.FeatureConfigurations.RegistryConfigurations.UserHive; namespace SafeExamBrowser.Lockdown { @@ -22,9 +23,9 @@ namespace SafeExamBrowser.Lockdown this.logger = logger; } - public IFeatureConfiguration CreateChromeNotificationConfiguration(Guid groupId) + public IFeatureConfiguration CreateChromeNotificationConfiguration(Guid groupId, string sid, string userName) { - return new ChromeNotificationConfiguration(groupId, logger.CloneFor(nameof(ChromeNotificationConfiguration))); + return new ChromeNotificationConfiguration(groupId, logger.CloneFor(nameof(ChromeNotificationConfiguration)), sid, userName); } public IFeatureConfiguration CreateEaseOfAccessConfiguration(Guid groupId) diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/ChromeNotificationConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/ChromeNotificationConfiguration.cs deleted file mode 100644 index af50791e..00000000 --- a/SafeExamBrowser.Lockdown/FeatureConfigurations/ChromeNotificationConfiguration.cs +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 SafeExamBrowser.Contracts.Logging; - -namespace SafeExamBrowser.Lockdown.FeatureConfigurations -{ - [Serializable] - internal class ChromeNotificationConfiguration : FeatureConfiguration - { - public ChromeNotificationConfiguration(Guid groupId, ILogger logger) : base(groupId, logger) - { - } - - public override bool DisableFeature() - { - logger.Info("Disabling..."); - - return true; - } - - public override bool EnableFeature() - { - logger.Info("Enabling..."); - - return true; - } - - public override void Monitor() - { - logger.Info("Monitoring..."); - } - - public override bool Restore() - { - logger.Info("Restoring..."); - - return true; - } - } -} diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/EaseOfAccessConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/EaseOfAccessConfiguration.cs index bf3544b8..ccac2bca 100644 --- a/SafeExamBrowser.Lockdown/FeatureConfigurations/EaseOfAccessConfiguration.cs +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/EaseOfAccessConfiguration.cs @@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations return true; } + public override void Initialize() + { + + } + public override void Monitor() { diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/FeatureConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/FeatureConfiguration.cs index 825ed412..5272c155 100644 --- a/SafeExamBrowser.Lockdown/FeatureConfigurations/FeatureConfiguration.cs +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/FeatureConfiguration.cs @@ -31,6 +31,7 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations public abstract bool DisableFeature(); public abstract bool EnableFeature(); + public abstract void Initialize(); public abstract void Monitor(); public abstract bool Restore(); diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/NetworkOptionsConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/NetworkOptionsConfiguration.cs index da522f62..2278bfcb 100644 --- a/SafeExamBrowser.Lockdown/FeatureConfigurations/NetworkOptionsConfiguration.cs +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/NetworkOptionsConfiguration.cs @@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations return true; } + public override void Initialize() + { + + } + public override void Monitor() { diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/PasswordChangeConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/PasswordChangeConfiguration.cs index 6f37e7a8..dc938be2 100644 --- a/SafeExamBrowser.Lockdown/FeatureConfigurations/PasswordChangeConfiguration.cs +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/PasswordChangeConfiguration.cs @@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations return true; } + public override void Initialize() + { + + } + public override void Monitor() { diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/PowerOptionsConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/PowerOptionsConfiguration.cs index f100a31b..84e8acf1 100644 --- a/SafeExamBrowser.Lockdown/FeatureConfigurations/PowerOptionsConfiguration.cs +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/PowerOptionsConfiguration.cs @@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations return true; } + public override void Initialize() + { + + } + public override void Monitor() { diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/MachineHiveConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/MachineHiveConfiguration.cs new file mode 100644 index 00000000..0b41fa70 --- /dev/null +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/MachineHiveConfiguration.cs @@ -0,0 +1,29 @@ +/* + * 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 Microsoft.Win32; +using SafeExamBrowser.Contracts.Logging; + +namespace SafeExamBrowser.Lockdown.FeatureConfigurations.RegistryConfigurations +{ + [Serializable] + internal abstract class MachineHiveConfiguration : RegistryConfiguration + { + protected override RegistryKey RootKey => Registry.LocalMachine; + + public MachineHiveConfiguration(Guid groupId, ILogger logger) : base(groupId, logger) + { + } + + protected override bool IsHiveAvailable(RegistryDataItem item) + { + return true; + } + } +} diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/RegistryConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/RegistryConfiguration.cs new file mode 100644 index 00000000..6c23dfcb --- /dev/null +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/RegistryConfiguration.cs @@ -0,0 +1,201 @@ +/* + * 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.Collections.Generic; +using System.Linq; +using Microsoft.Win32; +using SafeExamBrowser.Contracts.Logging; + +namespace SafeExamBrowser.Lockdown.FeatureConfigurations.RegistryConfigurations +{ + [Serializable] + internal abstract class RegistryConfiguration : FeatureConfiguration + { + private IList itemsToDelete; + private IList itemsToRestore; + + protected abstract IEnumerable Items { get; } + protected abstract RegistryKey RootKey { get; } + + public RegistryConfiguration(Guid groupId, ILogger logger) : base(groupId, logger) + { + itemsToDelete = new List(); + itemsToRestore = new List(); + } + + public override bool DisableFeature() + { + var success = true; + + foreach (var item in Items) + { + success &= TrySet(new RegistryDataItem { Key = item.Key, Value = item.Value, Data = item.Disabled }); + } + + if (success) + { + logger.Info("Successfully disabled feature."); + } + else + { + logger.Warn("Failed to disable feature!"); + } + + return success; + } + + public override bool EnableFeature() + { + var success = true; + + foreach (var item in Items) + { + success &= TrySet(new RegistryDataItem { Key = item.Key, Value = item.Value, Data = item.Enabled }); + } + + if (success) + { + logger.Info("Successfully enabled feature."); + } + else + { + logger.Warn("Failed to enabled feature!"); + } + + return success; + } + + public override void Initialize() + { + foreach (var item in Items) + { + var original = ReadItem(item.Key, item.Value); + + if (original.Data == null) + { + itemsToDelete.Add(original); + } + else + { + itemsToRestore.Add(original); + } + } + } + + public override void Monitor() + { + // TODO! + } + + public override bool Restore() + { + foreach (var item in new List(itemsToDelete)) + { + if (TryDelete(item)) + { + itemsToDelete.Remove(item); + } + } + + foreach (var item in new List(itemsToRestore)) + { + if (TrySet(item)) + { + itemsToRestore.Remove(item); + } + } + + var success = !itemsToDelete.Any() && !itemsToRestore.Any(); + + if (success) + { + logger.Info("Successfully restored feature."); + } + else + { + logger.Warn("Failed to restore feature!"); + } + + return success; + } + + protected abstract bool IsHiveAvailable(RegistryDataItem item); + + private RegistryDataItem ReadItem(string key, string value) + { + var data = Registry.GetValue(key, value, null); + var original = new RegistryDataItem { Key = key, Value = value, Data = data }; + + return original; + } + + private bool TryDelete(RegistryDataItem item) + { + var success = false; + + try + { + if (IsHiveAvailable(item)) + { + var keyWithoutRoot = item.Key.Substring(item.Key.IndexOf('\\') + 1); + + using (var key = RootKey.OpenSubKey(keyWithoutRoot, true)) + { + if (key.GetValue(item.Value) != null) + { + key.DeleteValue(item.Value); + logger.Debug($"Successfully deleted registry item {item}."); + } + else + { + logger.Debug($"No need to delete registry item {item} as it does not exist."); + } + + success = true; + } + } + else + { + logger.Warn($"Cannot delete item {item} as its registry hive is not available!"); + } + } + catch (Exception e) + { + logger.Error($"Failed to delete registry item {item}!", e); + } + + return success; + } + + private bool TrySet(RegistryDataItem item) + { + var success = false; + + try + { + if (IsHiveAvailable(item)) + { + Registry.SetValue(item.Key, item.Value, item.Data); + logger.Debug($"Successfully set registry item {item}."); + success = true; + } + else + { + logger.Warn($"Cannot set item {item} as its registry hive is not available!"); + } + } + catch (Exception e) + { + logger.Error($"Failed to set registry item {item}!", e); + } + + return success; + } + } +} diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/RegistryConfigurationItem.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/RegistryConfigurationItem.cs new file mode 100644 index 00000000..9ca70745 --- /dev/null +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/RegistryConfigurationItem.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.Lockdown.FeatureConfigurations.RegistryConfigurations +{ + internal class RegistryConfigurationItem + { + internal object Disabled { get; } + internal object Enabled { get; } + internal string Key { get; } + internal string Value { get; } + + internal RegistryConfigurationItem(string key, string value, object disabled, object enabled) + { + Key = key; + Value = value; + Disabled = disabled; + Enabled = enabled; + } + } +} diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/RegistryDataItem.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/RegistryDataItem.cs new file mode 100644 index 00000000..8fe3bf45 --- /dev/null +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/RegistryDataItem.cs @@ -0,0 +1,25 @@ +/* + * 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; + +namespace SafeExamBrowser.Lockdown.FeatureConfigurations.RegistryConfigurations +{ + [Serializable] + internal class RegistryDataItem + { + internal object Data { get; set; } + internal string Key { get; set; } + internal string Value { get; set; } + + public override string ToString() + { + return $@"'{Key}\{Value}'{(Data != null ? $" => '{Data}'" : "")}"; + } + } +} diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/UserHive/ChromeNotificationConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/UserHive/ChromeNotificationConfiguration.cs new file mode 100644 index 00000000..35cee403 --- /dev/null +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/UserHive/ChromeNotificationConfiguration.cs @@ -0,0 +1,35 @@ +/* + * 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.Collections.Generic; +using SafeExamBrowser.Contracts.Logging; + +namespace SafeExamBrowser.Lockdown.FeatureConfigurations.RegistryConfigurations.UserHive +{ + /// + /// IMPORTANT: This registry configuration only has an effect after Chrome is restarted! + /// + /// See https://www.chromium.org/administrators/policy-list-3#DefaultNotificationsSetting: + /// • 1 = Allow sites to show desktop notifications + /// • 2 = Do not allow any site to show desktop notifications + /// • 3 = Ask every time a site wants to show desktop notifications + /// + [Serializable] + internal class ChromeNotificationConfiguration : UserHiveConfiguration + { + protected override IEnumerable Items => new [] + { + new RegistryConfigurationItem($@"HKEY_USERS\{SID}\Software\Policies\Google\Chrome", "DefaultNotificationsSetting", 2, 1) + }; + + public ChromeNotificationConfiguration(Guid groupId, ILogger logger, string sid, string userName) : base(groupId, logger, sid, userName) + { + } + } +} diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/UserHiveConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/UserHiveConfiguration.cs new file mode 100644 index 00000000..a8343ae5 --- /dev/null +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/RegistryConfigurations/UserHiveConfiguration.cs @@ -0,0 +1,50 @@ +/* + * 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 Microsoft.Win32; +using SafeExamBrowser.Contracts.Logging; + +namespace SafeExamBrowser.Lockdown.FeatureConfigurations.RegistryConfigurations +{ + [Serializable] + internal abstract class UserHiveConfiguration : RegistryConfiguration + { + protected string SID { get; } + protected string UserName { get; } + + protected override RegistryKey RootKey => Registry.Users; + + public UserHiveConfiguration(Guid groupId, ILogger logger, string sid, string userName) : base(groupId, logger) + { + SID = sid ?? throw new ArgumentNullException(nameof(sid)); + UserName = userName ?? throw new ArgumentNullException(nameof(userName)); + } + + public override string ToString() + { + return $"{GetType().Name} ({Id}) for user '{UserName}'"; + } + + protected override bool IsHiveAvailable(RegistryDataItem item) + { + var isAvailable = false; + + try + { + isAvailable = Registry.Users.OpenSubKey(SID) != null; + } + catch (Exception e) + { + logger.Error($"Failed to check availability of registry hive for item {item}!", e); + } + + return isAvailable; + } + } +} diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/RemoteConnectionConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/RemoteConnectionConfiguration.cs index 4a60ef07..c39649da 100644 --- a/SafeExamBrowser.Lockdown/FeatureConfigurations/RemoteConnectionConfiguration.cs +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/RemoteConnectionConfiguration.cs @@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations return true; } + public override void Initialize() + { + + } + public override void Monitor() { diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/SignoutConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/SignoutConfiguration.cs index d6db15ab..4fb49060 100644 --- a/SafeExamBrowser.Lockdown/FeatureConfigurations/SignoutConfiguration.cs +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/SignoutConfiguration.cs @@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations return true; } + public override void Initialize() + { + + } + public override void Monitor() { diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/TaskManagerConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/TaskManagerConfiguration.cs index 8df5546a..25a27eb9 100644 --- a/SafeExamBrowser.Lockdown/FeatureConfigurations/TaskManagerConfiguration.cs +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/TaskManagerConfiguration.cs @@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations return true; } + public override void Initialize() + { + + } + public override void Monitor() { diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/UserLockConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/UserLockConfiguration.cs index 39437c7c..6d148e45 100644 --- a/SafeExamBrowser.Lockdown/FeatureConfigurations/UserLockConfiguration.cs +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/UserLockConfiguration.cs @@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations return true; } + public override void Initialize() + { + + } + public override void Monitor() { diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/UserSwitchConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/UserSwitchConfiguration.cs index 67330467..3ea5a17c 100644 --- a/SafeExamBrowser.Lockdown/FeatureConfigurations/UserSwitchConfiguration.cs +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/UserSwitchConfiguration.cs @@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations return true; } + public override void Initialize() + { + + } + public override void Monitor() { diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/VmwareOverlayConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/VmwareOverlayConfiguration.cs index c8b17e82..86673861 100644 --- a/SafeExamBrowser.Lockdown/FeatureConfigurations/VmwareOverlayConfiguration.cs +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/VmwareOverlayConfiguration.cs @@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations return true; } + public override void Initialize() + { + + } + public override void Monitor() { diff --git a/SafeExamBrowser.Lockdown/FeatureConfigurations/WindowsUpdateConfiguration.cs b/SafeExamBrowser.Lockdown/FeatureConfigurations/WindowsUpdateConfiguration.cs index 706e8a89..d4d0d6ca 100644 --- a/SafeExamBrowser.Lockdown/FeatureConfigurations/WindowsUpdateConfiguration.cs +++ b/SafeExamBrowser.Lockdown/FeatureConfigurations/WindowsUpdateConfiguration.cs @@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations return true; } + public override void Initialize() + { + + } + public override void Monitor() { diff --git a/SafeExamBrowser.Lockdown/SafeExamBrowser.Lockdown.csproj b/SafeExamBrowser.Lockdown/SafeExamBrowser.Lockdown.csproj index 80bac0d4..625c3272 100644 --- a/SafeExamBrowser.Lockdown/SafeExamBrowser.Lockdown.csproj +++ b/SafeExamBrowser.Lockdown/SafeExamBrowser.Lockdown.csproj @@ -56,8 +56,13 @@ - + + + + + + @@ -77,6 +82,8 @@ SafeExamBrowser.Contracts - + + + \ No newline at end of file diff --git a/SafeExamBrowser.Service.UnitTests/Operations/LockdownOperationTests.cs b/SafeExamBrowser.Service.UnitTests/Operations/LockdownOperationTests.cs index 5fffda28..ae83405f 100644 --- a/SafeExamBrowser.Service.UnitTests/Operations/LockdownOperationTests.cs +++ b/SafeExamBrowser.Service.UnitTests/Operations/LockdownOperationTests.cs @@ -37,7 +37,10 @@ namespace SafeExamBrowser.Service.UnitTests.Operations factory = new Mock(); logger = new Mock(); settings = new Settings(); - sessionContext = new SessionContext { Configuration = new ServiceConfiguration { Settings = settings } }; + sessionContext = new SessionContext + { + Configuration = new ServiceConfiguration { Settings = settings, UserName = "TestName", UserSid = "S-1-234-TEST" } + }; sut = new LockdownOperation(backup.Object, factory.Object, logger.Object, sessionContext); } @@ -57,6 +60,7 @@ namespace SafeExamBrowser.Service.UnitTests.Operations var result = sut.Perform(); backup.Verify(b => b.Save(It.Is(c => c == configuration.Object)), Times.Exactly(count)); + configuration.Verify(c => c.Initialize(), Times.Exactly(count)); configuration.Verify(c => c.DisableFeature(), Times.Exactly(3)); configuration.Verify(c => c.EnableFeature(), Times.Exactly(count - 3)); configuration.Verify(c => c.Monitor(), Times.Exactly(count)); @@ -71,12 +75,15 @@ namespace SafeExamBrowser.Service.UnitTests.Operations var groupId = default(Guid); configuration.SetReturnsDefault(true); - factory.Setup(f => f.CreateChromeNotificationConfiguration(It.IsAny())).Returns(configuration.Object).Callback(id => groupId = id); + factory + .Setup(f => f.CreateChromeNotificationConfiguration(It.IsAny(), It.IsAny(), It.IsAny())) + .Returns(configuration.Object) + .Callback((id, name, sid) => groupId = id); factory.SetReturnsDefault(configuration.Object); sut.Perform(); - factory.Verify(f => f.CreateChromeNotificationConfiguration(It.Is(id => id == groupId)), Times.Once); + factory.Verify(f => f.CreateChromeNotificationConfiguration(It.Is(id => id == groupId), It.IsAny(), It.IsAny()), Times.Once); factory.Verify(f => f.CreateEaseOfAccessConfiguration(It.Is(id => id == groupId)), Times.Once); factory.Verify(f => f.CreateNetworkOptionsConfiguration(It.Is(id => id == groupId)), Times.Once); factory.Verify(f => f.CreatePasswordChangeConfiguration(It.Is(id => id == groupId)), Times.Once); @@ -104,6 +111,7 @@ namespace SafeExamBrowser.Service.UnitTests.Operations var result = sut.Perform(); backup.Verify(b => b.Save(It.Is(c => c == configuration.Object)), Times.Exactly(count - offset)); + configuration.Verify(c => c.Initialize(), Times.Exactly(count - offset)); configuration.Verify(c => c.DisableFeature(), Times.Never); configuration.Verify(c => c.EnableFeature(), Times.Exactly(count - offset)); configuration.Verify(c => c.Monitor(), Times.Exactly(count - offset - 1)); @@ -141,18 +149,22 @@ namespace SafeExamBrowser.Service.UnitTests.Operations configuration1.Verify(c => c.DisableFeature(), Times.Never); configuration1.Verify(c => c.EnableFeature(), Times.Never); + configuration1.Verify(c => c.Initialize(), Times.Never); configuration1.Verify(c => c.Restore(), Times.Once); configuration2.Verify(c => c.DisableFeature(), Times.Never); configuration2.Verify(c => c.EnableFeature(), Times.Never); + configuration2.Verify(c => c.Initialize(), Times.Never); configuration2.Verify(c => c.Restore(), Times.Once); configuration3.Verify(c => c.DisableFeature(), Times.Never); configuration3.Verify(c => c.EnableFeature(), Times.Never); + configuration3.Verify(c => c.Initialize(), Times.Never); configuration3.Verify(c => c.Restore(), Times.Once); configuration4.Verify(c => c.DisableFeature(), Times.Never); configuration4.Verify(c => c.EnableFeature(), Times.Never); + configuration4.Verify(c => c.Initialize(), Times.Never); configuration4.Verify(c => c.Restore(), Times.Once); Assert.AreEqual(OperationResult.Success, result); @@ -188,18 +200,22 @@ namespace SafeExamBrowser.Service.UnitTests.Operations configuration1.Verify(c => c.DisableFeature(), Times.Never); configuration1.Verify(c => c.EnableFeature(), Times.Never); + configuration1.Verify(c => c.Initialize(), Times.Never); configuration1.Verify(c => c.Restore(), Times.Once); configuration2.Verify(c => c.DisableFeature(), Times.Never); configuration2.Verify(c => c.EnableFeature(), Times.Never); + configuration2.Verify(c => c.Initialize(), Times.Never); configuration2.Verify(c => c.Restore(), Times.Once); configuration3.Verify(c => c.DisableFeature(), Times.Never); configuration3.Verify(c => c.EnableFeature(), Times.Never); + configuration3.Verify(c => c.Initialize(), Times.Never); configuration3.Verify(c => c.Restore(), Times.Once); configuration4.Verify(c => c.DisableFeature(), Times.Never); configuration4.Verify(c => c.EnableFeature(), Times.Never); + configuration4.Verify(c => c.Initialize(), Times.Never); configuration4.Verify(c => c.Restore(), Times.Once); Assert.AreEqual(OperationResult.Failed, result); diff --git a/SafeExamBrowser.Service/Operations/LockdownOperation.cs b/SafeExamBrowser.Service/Operations/LockdownOperation.cs index bbbace0c..db17b757 100644 --- a/SafeExamBrowser.Service/Operations/LockdownOperation.cs +++ b/SafeExamBrowser.Service/Operations/LockdownOperation.cs @@ -36,9 +36,11 @@ namespace SafeExamBrowser.Service.Operations groupId = Guid.NewGuid(); var success = true; + var sid = Context.Configuration.UserSid; + var userName = Context.Configuration.UserName; var configurations = new [] { - (factory.CreateChromeNotificationConfiguration(groupId), Context.Configuration.Settings.Service.DisableChromeNotifications), + (factory.CreateChromeNotificationConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisableChromeNotifications), (factory.CreateEaseOfAccessConfiguration(groupId), Context.Configuration.Settings.Service.DisableEaseOfAccessOptions), (factory.CreateNetworkOptionsConfiguration(groupId), Context.Configuration.Settings.Service.DisableNetworkOptions), (factory.CreatePasswordChangeConfiguration(groupId), Context.Configuration.Settings.Service.DisablePasswordChange), @@ -114,6 +116,7 @@ namespace SafeExamBrowser.Service.Operations { var success = false; + configuration.Initialize(); backup.Save(configuration); if (disable) diff --git a/SafeExamBrowser.Service/SafeExamBrowser.Service.csproj b/SafeExamBrowser.Service/SafeExamBrowser.Service.csproj index 3b0293a3..521af350 100644 --- a/SafeExamBrowser.Service/SafeExamBrowser.Service.csproj +++ b/SafeExamBrowser.Service/SafeExamBrowser.Service.csproj @@ -52,6 +52,9 @@ MinimumRecommendedRules.ruleset true + + SafeExamBrowser.ico + @@ -102,6 +105,8 @@ SafeExamBrowser.Logging - + + + \ No newline at end of file diff --git a/SafeExamBrowser.Service/SafeExamBrowser.ico b/SafeExamBrowser.Service/SafeExamBrowser.ico new file mode 100644 index 00000000..abdc4635 Binary files /dev/null and b/SafeExamBrowser.Service/SafeExamBrowser.ico differ