SEBWIN-319: Implemented infrastructure for registry configurations and corrected mistake in backup mechanism.
This commit is contained in:
parent
ac5791ee13
commit
ee683af63c
28 changed files with 474 additions and 57 deletions
|
@ -35,6 +35,11 @@ namespace SafeExamBrowser.Contracts.Lockdown
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool EnableFeature();
|
bool EnableFeature();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the currently active configuration of the feature.
|
||||||
|
/// </summary>
|
||||||
|
void Initialize();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Starts monitoring the feature to ensure that it remains as currently configured.
|
/// Starts monitoring the feature to ensure that it remains as currently configured.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace SafeExamBrowser.Contracts.Lockdown
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an <see cref="IFeatureConfiguration"/> to control notifications of the Google Chrome browser.
|
/// Creates an <see cref="IFeatureConfiguration"/> to control notifications of the Google Chrome browser.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IFeatureConfiguration CreateChromeNotificationConfiguration(Guid groupId);
|
IFeatureConfiguration CreateChromeNotificationConfiguration(Guid groupId, string sid, string userName);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an <see cref="IFeatureConfiguration"/> to control the ease of access options on the security screen.
|
/// Creates an <see cref="IFeatureConfiguration"/> to control the ease of access options on the security screen.
|
||||||
|
|
|
@ -32,6 +32,11 @@ namespace SafeExamBrowser.Lockdown.UnitTests
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public void Monitor()
|
public void Monitor()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
|
@ -10,6 +10,7 @@ using System;
|
||||||
using SafeExamBrowser.Contracts.Lockdown;
|
using SafeExamBrowser.Contracts.Lockdown;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Lockdown.FeatureConfigurations;
|
using SafeExamBrowser.Lockdown.FeatureConfigurations;
|
||||||
|
using SafeExamBrowser.Lockdown.FeatureConfigurations.RegistryConfigurations.UserHive;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Lockdown
|
namespace SafeExamBrowser.Lockdown
|
||||||
{
|
{
|
||||||
|
@ -22,9 +23,9 @@ namespace SafeExamBrowser.Lockdown
|
||||||
this.logger = logger;
|
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)
|
public IFeatureConfiguration CreateEaseOfAccessConfiguration(Guid groupId)
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public override void Monitor()
|
public override void Monitor()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations
|
||||||
|
|
||||||
public abstract bool DisableFeature();
|
public abstract bool DisableFeature();
|
||||||
public abstract bool EnableFeature();
|
public abstract bool EnableFeature();
|
||||||
|
public abstract void Initialize();
|
||||||
public abstract void Monitor();
|
public abstract void Monitor();
|
||||||
public abstract bool Restore();
|
public abstract bool Restore();
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public override void Monitor()
|
public override void Monitor()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public override void Monitor()
|
public override void Monitor()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public override void Monitor()
|
public override void Monitor()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<RegistryDataItem> itemsToDelete;
|
||||||
|
private IList<RegistryDataItem> itemsToRestore;
|
||||||
|
|
||||||
|
protected abstract IEnumerable<RegistryConfigurationItem> Items { get; }
|
||||||
|
protected abstract RegistryKey RootKey { get; }
|
||||||
|
|
||||||
|
public RegistryConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
|
||||||
|
{
|
||||||
|
itemsToDelete = new List<RegistryDataItem>();
|
||||||
|
itemsToRestore = new List<RegistryDataItem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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<RegistryDataItem>(itemsToDelete))
|
||||||
|
{
|
||||||
|
if (TryDelete(item))
|
||||||
|
{
|
||||||
|
itemsToDelete.Remove(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var item in new List<RegistryDataItem>(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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}'" : "")}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 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
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
internal class ChromeNotificationConfiguration : UserHiveConfiguration
|
||||||
|
{
|
||||||
|
protected override IEnumerable<RegistryConfigurationItem> 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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public override void Monitor()
|
public override void Monitor()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public override void Monitor()
|
public override void Monitor()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public override void Monitor()
|
public override void Monitor()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public override void Monitor()
|
public override void Monitor()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public override void Monitor()
|
public override void Monitor()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public override void Monitor()
|
public override void Monitor()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,11 @@ namespace SafeExamBrowser.Lockdown.FeatureConfigurations
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public override void Monitor()
|
public override void Monitor()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,13 @@
|
||||||
<Compile Include="AutoRestoreMechanism.cs" />
|
<Compile Include="AutoRestoreMechanism.cs" />
|
||||||
<Compile Include="FeatureConfigurationFactory.cs" />
|
<Compile Include="FeatureConfigurationFactory.cs" />
|
||||||
<Compile Include="FeatureConfigurationBackup.cs" />
|
<Compile Include="FeatureConfigurationBackup.cs" />
|
||||||
<Compile Include="FeatureConfigurations\ChromeNotificationConfiguration.cs" />
|
<Compile Include="FeatureConfigurations\RegistryConfigurations\RegistryDataItem.cs" />
|
||||||
|
<Compile Include="FeatureConfigurations\RegistryConfigurations\RegistryConfigurationItem.cs" />
|
||||||
|
<Compile Include="FeatureConfigurations\RegistryConfigurations\UserHive\ChromeNotificationConfiguration.cs" />
|
||||||
<Compile Include="FeatureConfigurations\FeatureConfiguration.cs" />
|
<Compile Include="FeatureConfigurations\FeatureConfiguration.cs" />
|
||||||
|
<Compile Include="FeatureConfigurations\RegistryConfigurations\MachineHiveConfiguration.cs" />
|
||||||
|
<Compile Include="FeatureConfigurations\RegistryConfigurations\RegistryConfiguration.cs" />
|
||||||
|
<Compile Include="FeatureConfigurations\RegistryConfigurations\UserHiveConfiguration.cs" />
|
||||||
<Compile Include="FeatureConfigurations\TaskManagerConfiguration.cs" />
|
<Compile Include="FeatureConfigurations\TaskManagerConfiguration.cs" />
|
||||||
<Compile Include="FeatureConfigurations\EaseOfAccessConfiguration.cs" />
|
<Compile Include="FeatureConfigurations\EaseOfAccessConfiguration.cs" />
|
||||||
<Compile Include="FeatureConfigurations\NetworkOptionsConfiguration.cs" />
|
<Compile Include="FeatureConfigurations\NetworkOptionsConfiguration.cs" />
|
||||||
|
@ -77,6 +82,8 @@
|
||||||
<Name>SafeExamBrowser.Contracts</Name>
|
<Name>SafeExamBrowser.Contracts</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup>
|
||||||
|
<Folder Include="FeatureConfigurations\RegistryConfigurations\MachineHive\" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
|
@ -37,7 +37,10 @@ namespace SafeExamBrowser.Service.UnitTests.Operations
|
||||||
factory = new Mock<IFeatureConfigurationFactory>();
|
factory = new Mock<IFeatureConfigurationFactory>();
|
||||||
logger = new Mock<ILogger>();
|
logger = new Mock<ILogger>();
|
||||||
settings = new Settings();
|
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);
|
sut = new LockdownOperation(backup.Object, factory.Object, logger.Object, sessionContext);
|
||||||
}
|
}
|
||||||
|
@ -57,6 +60,7 @@ namespace SafeExamBrowser.Service.UnitTests.Operations
|
||||||
var result = sut.Perform();
|
var result = sut.Perform();
|
||||||
|
|
||||||
backup.Verify(b => b.Save(It.Is<IFeatureConfiguration>(c => c == configuration.Object)), Times.Exactly(count));
|
backup.Verify(b => b.Save(It.Is<IFeatureConfiguration>(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.DisableFeature(), Times.Exactly(3));
|
||||||
configuration.Verify(c => c.EnableFeature(), Times.Exactly(count - 3));
|
configuration.Verify(c => c.EnableFeature(), Times.Exactly(count - 3));
|
||||||
configuration.Verify(c => c.Monitor(), Times.Exactly(count));
|
configuration.Verify(c => c.Monitor(), Times.Exactly(count));
|
||||||
|
@ -71,12 +75,15 @@ namespace SafeExamBrowser.Service.UnitTests.Operations
|
||||||
var groupId = default(Guid);
|
var groupId = default(Guid);
|
||||||
|
|
||||||
configuration.SetReturnsDefault(true);
|
configuration.SetReturnsDefault(true);
|
||||||
factory.Setup(f => f.CreateChromeNotificationConfiguration(It.IsAny<Guid>())).Returns(configuration.Object).Callback<Guid>(id => groupId = id);
|
factory
|
||||||
|
.Setup(f => f.CreateChromeNotificationConfiguration(It.IsAny<Guid>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||||
|
.Returns(configuration.Object)
|
||||||
|
.Callback<Guid, string, string>((id, name, sid) => groupId = id);
|
||||||
factory.SetReturnsDefault(configuration.Object);
|
factory.SetReturnsDefault(configuration.Object);
|
||||||
|
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
factory.Verify(f => f.CreateChromeNotificationConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
|
factory.Verify(f => f.CreateChromeNotificationConfiguration(It.Is<Guid>(id => id == groupId), It.IsAny<string>(), It.IsAny<string>()), Times.Once);
|
||||||
factory.Verify(f => f.CreateEaseOfAccessConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
|
factory.Verify(f => f.CreateEaseOfAccessConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
|
||||||
factory.Verify(f => f.CreateNetworkOptionsConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
|
factory.Verify(f => f.CreateNetworkOptionsConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
|
||||||
factory.Verify(f => f.CreatePasswordChangeConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
|
factory.Verify(f => f.CreatePasswordChangeConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
|
||||||
|
@ -104,6 +111,7 @@ namespace SafeExamBrowser.Service.UnitTests.Operations
|
||||||
var result = sut.Perform();
|
var result = sut.Perform();
|
||||||
|
|
||||||
backup.Verify(b => b.Save(It.Is<IFeatureConfiguration>(c => c == configuration.Object)), Times.Exactly(count - offset));
|
backup.Verify(b => b.Save(It.Is<IFeatureConfiguration>(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.DisableFeature(), Times.Never);
|
||||||
configuration.Verify(c => c.EnableFeature(), Times.Exactly(count - offset));
|
configuration.Verify(c => c.EnableFeature(), Times.Exactly(count - offset));
|
||||||
configuration.Verify(c => c.Monitor(), Times.Exactly(count - offset - 1));
|
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.DisableFeature(), Times.Never);
|
||||||
configuration1.Verify(c => c.EnableFeature(), Times.Never);
|
configuration1.Verify(c => c.EnableFeature(), Times.Never);
|
||||||
|
configuration1.Verify(c => c.Initialize(), Times.Never);
|
||||||
configuration1.Verify(c => c.Restore(), Times.Once);
|
configuration1.Verify(c => c.Restore(), Times.Once);
|
||||||
|
|
||||||
configuration2.Verify(c => c.DisableFeature(), Times.Never);
|
configuration2.Verify(c => c.DisableFeature(), Times.Never);
|
||||||
configuration2.Verify(c => c.EnableFeature(), Times.Never);
|
configuration2.Verify(c => c.EnableFeature(), Times.Never);
|
||||||
|
configuration2.Verify(c => c.Initialize(), Times.Never);
|
||||||
configuration2.Verify(c => c.Restore(), Times.Once);
|
configuration2.Verify(c => c.Restore(), Times.Once);
|
||||||
|
|
||||||
configuration3.Verify(c => c.DisableFeature(), Times.Never);
|
configuration3.Verify(c => c.DisableFeature(), Times.Never);
|
||||||
configuration3.Verify(c => c.EnableFeature(), Times.Never);
|
configuration3.Verify(c => c.EnableFeature(), Times.Never);
|
||||||
|
configuration3.Verify(c => c.Initialize(), Times.Never);
|
||||||
configuration3.Verify(c => c.Restore(), Times.Once);
|
configuration3.Verify(c => c.Restore(), Times.Once);
|
||||||
|
|
||||||
configuration4.Verify(c => c.DisableFeature(), Times.Never);
|
configuration4.Verify(c => c.DisableFeature(), Times.Never);
|
||||||
configuration4.Verify(c => c.EnableFeature(), Times.Never);
|
configuration4.Verify(c => c.EnableFeature(), Times.Never);
|
||||||
|
configuration4.Verify(c => c.Initialize(), Times.Never);
|
||||||
configuration4.Verify(c => c.Restore(), Times.Once);
|
configuration4.Verify(c => c.Restore(), Times.Once);
|
||||||
|
|
||||||
Assert.AreEqual(OperationResult.Success, result);
|
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.DisableFeature(), Times.Never);
|
||||||
configuration1.Verify(c => c.EnableFeature(), Times.Never);
|
configuration1.Verify(c => c.EnableFeature(), Times.Never);
|
||||||
|
configuration1.Verify(c => c.Initialize(), Times.Never);
|
||||||
configuration1.Verify(c => c.Restore(), Times.Once);
|
configuration1.Verify(c => c.Restore(), Times.Once);
|
||||||
|
|
||||||
configuration2.Verify(c => c.DisableFeature(), Times.Never);
|
configuration2.Verify(c => c.DisableFeature(), Times.Never);
|
||||||
configuration2.Verify(c => c.EnableFeature(), Times.Never);
|
configuration2.Verify(c => c.EnableFeature(), Times.Never);
|
||||||
|
configuration2.Verify(c => c.Initialize(), Times.Never);
|
||||||
configuration2.Verify(c => c.Restore(), Times.Once);
|
configuration2.Verify(c => c.Restore(), Times.Once);
|
||||||
|
|
||||||
configuration3.Verify(c => c.DisableFeature(), Times.Never);
|
configuration3.Verify(c => c.DisableFeature(), Times.Never);
|
||||||
configuration3.Verify(c => c.EnableFeature(), Times.Never);
|
configuration3.Verify(c => c.EnableFeature(), Times.Never);
|
||||||
|
configuration3.Verify(c => c.Initialize(), Times.Never);
|
||||||
configuration3.Verify(c => c.Restore(), Times.Once);
|
configuration3.Verify(c => c.Restore(), Times.Once);
|
||||||
|
|
||||||
configuration4.Verify(c => c.DisableFeature(), Times.Never);
|
configuration4.Verify(c => c.DisableFeature(), Times.Never);
|
||||||
configuration4.Verify(c => c.EnableFeature(), Times.Never);
|
configuration4.Verify(c => c.EnableFeature(), Times.Never);
|
||||||
|
configuration4.Verify(c => c.Initialize(), Times.Never);
|
||||||
configuration4.Verify(c => c.Restore(), Times.Once);
|
configuration4.Verify(c => c.Restore(), Times.Once);
|
||||||
|
|
||||||
Assert.AreEqual(OperationResult.Failed, result);
|
Assert.AreEqual(OperationResult.Failed, result);
|
||||||
|
|
|
@ -36,9 +36,11 @@ namespace SafeExamBrowser.Service.Operations
|
||||||
groupId = Guid.NewGuid();
|
groupId = Guid.NewGuid();
|
||||||
|
|
||||||
var success = true;
|
var success = true;
|
||||||
|
var sid = Context.Configuration.UserSid;
|
||||||
|
var userName = Context.Configuration.UserName;
|
||||||
var configurations = new []
|
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.CreateEaseOfAccessConfiguration(groupId), Context.Configuration.Settings.Service.DisableEaseOfAccessOptions),
|
||||||
(factory.CreateNetworkOptionsConfiguration(groupId), Context.Configuration.Settings.Service.DisableNetworkOptions),
|
(factory.CreateNetworkOptionsConfiguration(groupId), Context.Configuration.Settings.Service.DisableNetworkOptions),
|
||||||
(factory.CreatePasswordChangeConfiguration(groupId), Context.Configuration.Settings.Service.DisablePasswordChange),
|
(factory.CreatePasswordChangeConfiguration(groupId), Context.Configuration.Settings.Service.DisablePasswordChange),
|
||||||
|
@ -114,6 +116,7 @@ namespace SafeExamBrowser.Service.Operations
|
||||||
{
|
{
|
||||||
var success = false;
|
var success = false;
|
||||||
|
|
||||||
|
configuration.Initialize();
|
||||||
backup.Save(configuration);
|
backup.Save(configuration);
|
||||||
|
|
||||||
if (disable)
|
if (disable)
|
||||||
|
|
|
@ -52,6 +52,9 @@
|
||||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
<Prefer32Bit>true</Prefer32Bit>
|
<Prefer32Bit>true</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<ApplicationIcon>SafeExamBrowser.ico</ApplicationIcon>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
@ -102,6 +105,8 @@
|
||||||
<Name>SafeExamBrowser.Logging</Name>
|
<Name>SafeExamBrowser.Logging</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup>
|
||||||
|
<Content Include="SafeExamBrowser.ico" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
BIN
SafeExamBrowser.Service/SafeExamBrowser.ico
Normal file
BIN
SafeExamBrowser.Service/SafeExamBrowser.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 361 KiB |
Loading…
Add table
Reference in a new issue