SEBWIN-319: Implemented registry configuration functionality.

This commit is contained in:
dbuechel 2019-07-03 08:59:27 +02:00
parent ee683af63c
commit 2f510096d0
28 changed files with 340 additions and 480 deletions

View file

@ -15,6 +15,11 @@ namespace SafeExamBrowser.Contracts.Lockdown
/// </summary> /// </summary>
public interface IFeatureConfigurationFactory public interface IFeatureConfigurationFactory
{ {
/// <summary>
/// Creates an <see cref="IFeatureConfiguration"/> to control the option to change the password of a user account via the security screen.
/// </summary>
IFeatureConfiguration CreateChangePasswordConfiguration(Guid groupId, string sid, string userName);
/// <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>
@ -25,16 +30,16 @@ namespace SafeExamBrowser.Contracts.Lockdown
/// </summary> /// </summary>
IFeatureConfiguration CreateEaseOfAccessConfiguration(Guid groupId); IFeatureConfiguration CreateEaseOfAccessConfiguration(Guid groupId);
/// <summary>
/// Creates an <see cref="IFeatureConfiguration"/> to control the option to lock the computer via the security screen.
/// </summary>
IFeatureConfiguration CreateLockWorkstationConfiguration(Guid groupId, string sid, string userName);
/// <summary> /// <summary>
/// Creates an <see cref="IFeatureConfiguration"/> to control the network options on the security screen. /// Creates an <see cref="IFeatureConfiguration"/> to control the network options on the security screen.
/// </summary> /// </summary>
IFeatureConfiguration CreateNetworkOptionsConfiguration(Guid groupId); IFeatureConfiguration CreateNetworkOptionsConfiguration(Guid groupId);
/// <summary>
/// Creates an <see cref="IFeatureConfiguration"/> to control the option to change the password of a user account via the security screen.
/// </summary>
IFeatureConfiguration CreatePasswordChangeConfiguration(Guid groupId);
/// <summary> /// <summary>
/// Creates an <see cref="IFeatureConfiguration"/> to control the power options on the security screen. /// Creates an <see cref="IFeatureConfiguration"/> to control the power options on the security screen.
/// </summary> /// </summary>
@ -48,27 +53,22 @@ namespace SafeExamBrowser.Contracts.Lockdown
/// <summary> /// <summary>
/// Creates an <see cref="IFeatureConfiguration"/> to control the option to sign out out via security screen. /// Creates an <see cref="IFeatureConfiguration"/> to control the option to sign out out via security screen.
/// </summary> /// </summary>
IFeatureConfiguration CreateSignoutConfiguration(Guid groupId); IFeatureConfiguration CreateSignoutConfiguration(Guid groupId, string sid, string userName);
/// <summary>
/// Creates an <see cref="IFeatureConfiguration"/> to control the task manager of Windows.
/// </summary>
IFeatureConfiguration CreateTaskManagerConfiguration(Guid groupId);
/// <summary>
/// Creates an <see cref="IFeatureConfiguration"/> to control the option to lock the computer via the security screen.
/// </summary>
IFeatureConfiguration CreateUserLockConfiguration(Guid groupId);
/// <summary> /// <summary>
/// Creates an <see cref="IFeatureConfiguration"/> to control the option to switch to another user account via the security screen. /// Creates an <see cref="IFeatureConfiguration"/> to control the option to switch to another user account via the security screen.
/// </summary> /// </summary>
IFeatureConfiguration CreateUserSwitchConfiguration(Guid groupId); IFeatureConfiguration CreateSwitchUserConfiguration(Guid groupId);
/// <summary>
/// Creates an <see cref="IFeatureConfiguration"/> to control the task manager of Windows.
/// </summary>
IFeatureConfiguration CreateTaskManagerConfiguration(Guid groupId, string sid, string userName);
/// <summary> /// <summary>
/// Creates an <see cref="IFeatureConfiguration"/> to control the user interface overlay for VMware clients. /// Creates an <see cref="IFeatureConfiguration"/> to control the user interface overlay for VMware clients.
/// </summary> /// </summary>
IFeatureConfiguration CreateVmwareOverlayConfiguration(Guid groupId); IFeatureConfiguration CreateVmwareOverlayConfiguration(Guid groupId, string sid, string userName);
/// <summary> /// <summary>
/// Creates an <see cref="IFeatureConfiguration"/> to control Windows Update. /// Creates an <see cref="IFeatureConfiguration"/> to control Windows Update.

View file

@ -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.MachineHive;
using SafeExamBrowser.Lockdown.FeatureConfigurations.RegistryConfigurations.UserHive; using SafeExamBrowser.Lockdown.FeatureConfigurations.RegistryConfigurations.UserHive;
namespace SafeExamBrowser.Lockdown namespace SafeExamBrowser.Lockdown
@ -23,6 +24,11 @@ namespace SafeExamBrowser.Lockdown
this.logger = logger; this.logger = logger;
} }
public IFeatureConfiguration CreateChangePasswordConfiguration(Guid groupId, string sid, string userName)
{
return new ChangePasswordConfiguration(groupId, logger.CloneFor(nameof(ChangePasswordConfiguration)), sid, userName);
}
public IFeatureConfiguration CreateChromeNotificationConfiguration(Guid groupId, string sid, string userName) public IFeatureConfiguration CreateChromeNotificationConfiguration(Guid groupId, string sid, string userName)
{ {
return new ChromeNotificationConfiguration(groupId, logger.CloneFor(nameof(ChromeNotificationConfiguration)), sid, userName); return new ChromeNotificationConfiguration(groupId, logger.CloneFor(nameof(ChromeNotificationConfiguration)), sid, userName);
@ -33,16 +39,16 @@ namespace SafeExamBrowser.Lockdown
return new EaseOfAccessConfiguration(groupId, logger.CloneFor(nameof(EaseOfAccessConfiguration))); return new EaseOfAccessConfiguration(groupId, logger.CloneFor(nameof(EaseOfAccessConfiguration)));
} }
public IFeatureConfiguration CreateLockWorkstationConfiguration(Guid groupId, string sid, string userName)
{
return new LockWorkstationConfiguration(groupId, logger.CloneFor(nameof(LockWorkstationConfiguration)), sid, userName);
}
public IFeatureConfiguration CreateNetworkOptionsConfiguration(Guid groupId) public IFeatureConfiguration CreateNetworkOptionsConfiguration(Guid groupId)
{ {
return new NetworkOptionsConfiguration(groupId, logger.CloneFor(nameof(NetworkOptionsConfiguration))); return new NetworkOptionsConfiguration(groupId, logger.CloneFor(nameof(NetworkOptionsConfiguration)));
} }
public IFeatureConfiguration CreatePasswordChangeConfiguration(Guid groupId)
{
return new PasswordChangeConfiguration(groupId, logger.CloneFor(nameof(PasswordChangeConfiguration)));
}
public IFeatureConfiguration CreatePowerOptionsConfiguration(Guid groupId) public IFeatureConfiguration CreatePowerOptionsConfiguration(Guid groupId)
{ {
return new PowerOptionsConfiguration(groupId, logger.CloneFor(nameof(PowerOptionsConfiguration))); return new PowerOptionsConfiguration(groupId, logger.CloneFor(nameof(PowerOptionsConfiguration)));
@ -53,29 +59,24 @@ namespace SafeExamBrowser.Lockdown
return new RemoteConnectionConfiguration(groupId, logger.CloneFor(nameof(RemoteConnectionConfiguration))); return new RemoteConnectionConfiguration(groupId, logger.CloneFor(nameof(RemoteConnectionConfiguration)));
} }
public IFeatureConfiguration CreateSignoutConfiguration(Guid groupId) public IFeatureConfiguration CreateSignoutConfiguration(Guid groupId, string sid, string userName)
{ {
return new SignoutConfiguration(groupId, logger.CloneFor(nameof(SignoutConfiguration))); return new SignoutConfiguration(groupId, logger.CloneFor(nameof(SignoutConfiguration)), sid, userName);
} }
public IFeatureConfiguration CreateTaskManagerConfiguration(Guid groupId) public IFeatureConfiguration CreateSwitchUserConfiguration(Guid groupId)
{ {
return new TaskManagerConfiguration(groupId, logger.CloneFor(nameof(TaskManagerConfiguration))); return new SwitchUserConfiguration(groupId, logger.CloneFor(nameof(SwitchUserConfiguration)));
} }
public IFeatureConfiguration CreateUserLockConfiguration(Guid groupId) public IFeatureConfiguration CreateTaskManagerConfiguration(Guid groupId, string sid, string userName)
{ {
return new UserLockConfiguration(groupId, logger.CloneFor(nameof(UserLockConfiguration))); return new TaskManagerConfiguration(groupId, logger.CloneFor(nameof(TaskManagerConfiguration)), sid, userName);
} }
public IFeatureConfiguration CreateUserSwitchConfiguration(Guid groupId) public IFeatureConfiguration CreateVmwareOverlayConfiguration(Guid groupId, string sid, string userName)
{ {
return new UserSwitchConfiguration(groupId, logger.CloneFor(nameof(UserSwitchConfiguration))); return new VmwareOverlayConfiguration(groupId, logger.CloneFor(nameof(VmwareOverlayConfiguration)), sid, userName);
}
public IFeatureConfiguration CreateVmwareOverlayConfiguration(Guid groupId)
{
return new VmwareOverlayConfiguration(groupId, logger.CloneFor(nameof(VmwareOverlayConfiguration)));
} }
public IFeatureConfiguration CreateWindowsUpdateConfiguration(Guid groupId) public IFeatureConfiguration CreateWindowsUpdateConfiguration(Guid groupId)

View file

@ -1,46 +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 PasswordChangeConfiguration : FeatureConfiguration
{
public PasswordChangeConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
{
}
public override bool DisableFeature()
{
return true;
}
public override bool EnableFeature()
{
return true;
}
public override void Initialize()
{
}
public override void Monitor()
{
}
public override bool Restore()
{
return true;
}
}
}

View file

@ -7,40 +7,21 @@
*/ */
using System; using System;
using System.Collections.Generic;
using SafeExamBrowser.Contracts.Logging; using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations namespace SafeExamBrowser.Lockdown.FeatureConfigurations.RegistryConfigurations.MachineHive
{ {
[Serializable] [Serializable]
internal class EaseOfAccessConfiguration : FeatureConfiguration internal class EaseOfAccessConfiguration : MachineHiveConfiguration
{ {
protected override IEnumerable<RegistryConfigurationItem> Items => new []
{
new RegistryConfigurationItem(@"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\Utilman.exe", "Debugger", "SebDummy.exe", "")
};
public EaseOfAccessConfiguration(Guid groupId, ILogger logger) : base(groupId, logger) public EaseOfAccessConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
{ {
} }
public override bool DisableFeature()
{
return true;
}
public override bool EnableFeature()
{
return true;
}
public override void Initialize()
{
}
public override void Monitor()
{
}
public override bool Restore()
{
return true;
}
} }
} }

View file

@ -10,7 +10,7 @@ using System;
using Microsoft.Win32; using Microsoft.Win32;
using SafeExamBrowser.Contracts.Logging; using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations.RegistryConfigurations namespace SafeExamBrowser.Lockdown.FeatureConfigurations.RegistryConfigurations.MachineHive
{ {
[Serializable] [Serializable]
internal abstract class MachineHiveConfiguration : RegistryConfiguration internal abstract class MachineHiveConfiguration : RegistryConfiguration

View file

@ -7,40 +7,21 @@
*/ */
using System; using System;
using System.Collections.Generic;
using SafeExamBrowser.Contracts.Logging; using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations namespace SafeExamBrowser.Lockdown.FeatureConfigurations.RegistryConfigurations.MachineHive
{ {
[Serializable] [Serializable]
internal class NetworkOptionsConfiguration : FeatureConfiguration internal class NetworkOptionsConfiguration : MachineHiveConfiguration
{ {
protected override IEnumerable<RegistryConfigurationItem> Items => new []
{
new RegistryConfigurationItem(@"HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\System", "DontDisplayNetworkSelectionUI", 1, 0)
};
public NetworkOptionsConfiguration(Guid groupId, ILogger logger) : base(groupId, logger) public NetworkOptionsConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
{ {
} }
public override bool DisableFeature()
{
return true;
}
public override bool EnableFeature()
{
return true;
}
public override void Initialize()
{
}
public override void Monitor()
{
}
public override bool Restore()
{
return true;
}
} }
} }

View file

@ -7,40 +7,21 @@
*/ */
using System; using System;
using System.Collections.Generic;
using SafeExamBrowser.Contracts.Logging; using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations namespace SafeExamBrowser.Lockdown.FeatureConfigurations.RegistryConfigurations.MachineHive
{ {
[Serializable] [Serializable]
internal class PowerOptionsConfiguration : FeatureConfiguration internal class PowerOptionsConfiguration : MachineHiveConfiguration
{ {
protected override IEnumerable<RegistryConfigurationItem> Items => new []
{
new RegistryConfigurationItem(@"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer", "NoClose", 1, 0)
};
public PowerOptionsConfiguration(Guid groupId, ILogger logger) : base(groupId, logger) public PowerOptionsConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
{ {
} }
public override bool DisableFeature()
{
return true;
}
public override bool EnableFeature()
{
return true;
}
public override void Initialize()
{
}
public override void Monitor()
{
}
public override bool Restore()
{
return true;
}
} }
} }

View file

@ -7,40 +7,21 @@
*/ */
using System; using System;
using System.Collections.Generic;
using SafeExamBrowser.Contracts.Logging; using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations namespace SafeExamBrowser.Lockdown.FeatureConfigurations.RegistryConfigurations.MachineHive
{ {
[Serializable] [Serializable]
internal class RemoteConnectionConfiguration : FeatureConfiguration internal class RemoteConnectionConfiguration : MachineHiveConfiguration
{ {
protected override IEnumerable<RegistryConfigurationItem> Items => new []
{
new RegistryConfigurationItem(@"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server", "fDenyTSConnections", 1, 0)
};
public RemoteConnectionConfiguration(Guid groupId, ILogger logger) : base(groupId, logger) public RemoteConnectionConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
{ {
} }
public override bool DisableFeature()
{
return true;
}
public override bool EnableFeature()
{
return true;
}
public override void Initialize()
{
}
public override void Monitor()
{
}
public override bool Restore()
{
return true;
}
} }
} }

View file

@ -0,0 +1,27 @@
/*
* 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.MachineHive
{
[Serializable]
internal class SwitchUserConfiguration : MachineHiveConfiguration
{
protected override IEnumerable<RegistryConfigurationItem> Items => new []
{
new RegistryConfigurationItem(@"HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System", "HideFastUserSwitching", 1, 0)
};
public SwitchUserConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
{
}
}
}

View file

@ -0,0 +1,27 @@
/*
* 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
{
[Serializable]
internal class ChangePasswordConfiguration : UserHiveConfiguration
{
protected override IEnumerable<RegistryConfigurationItem> Items => new []
{
new RegistryConfigurationItem($@"HKEY_USERS\{SID}\Software\Microsoft\Windows\CurrentVersion\Policies\System", "DisableChangePassword", 1, 0)
};
public ChangePasswordConfiguration(Guid groupId, ILogger logger, string sid, string userName) : base(groupId, logger, sid, userName)
{
}
}
}

View file

@ -0,0 +1,27 @@
/*
* 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
{
[Serializable]
internal class LockWorkstationConfiguration : UserHiveConfiguration
{
protected override IEnumerable<RegistryConfigurationItem> Items => new []
{
new RegistryConfigurationItem($@"HKEY_USERS\{SID}\Software\Microsoft\Windows\CurrentVersion\Policies\System", "DisableLockWorkstation", 1, 0)
};
public LockWorkstationConfiguration(Guid groupId, ILogger logger, string sid, string userName) : base(groupId, logger, sid, userName)
{
}
}
}

View file

@ -0,0 +1,27 @@
/*
* 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
{
[Serializable]
internal class SignoutConfiguration : UserHiveConfiguration
{
protected override IEnumerable<RegistryConfigurationItem> Items => new []
{
new RegistryConfigurationItem($@"HKEY_USERS\{SID}\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer", "NoLogoff", 1, 0)
};
public SignoutConfiguration(Guid groupId, ILogger logger, string sid, string userName) : base(groupId, logger, sid, userName)
{
}
}
}

View file

@ -0,0 +1,27 @@
/*
* 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
{
[Serializable]
internal class TaskManagerConfiguration : UserHiveConfiguration
{
protected override IEnumerable<RegistryConfigurationItem> Items => new []
{
new RegistryConfigurationItem($@"HKEY_USERS\{SID}\Software\Microsoft\Windows\CurrentVersion\Policies\System", "DisableTaskMgr", 1, 0)
};
public TaskManagerConfiguration(Guid groupId, ILogger logger, string sid, string userName) : base(groupId, logger, sid, userName)
{
}
}
}

View file

@ -10,7 +10,7 @@ using System;
using Microsoft.Win32; using Microsoft.Win32;
using SafeExamBrowser.Contracts.Logging; using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Lockdown.FeatureConfigurations.RegistryConfigurations namespace SafeExamBrowser.Lockdown.FeatureConfigurations.RegistryConfigurations.UserHive
{ {
[Serializable] [Serializable]
internal abstract class UserHiveConfiguration : RegistryConfiguration internal abstract class UserHiveConfiguration : RegistryConfiguration

View file

@ -0,0 +1,28 @@
/*
* 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
{
[Serializable]
internal class VmwareOverlayConfiguration : UserHiveConfiguration
{
protected override IEnumerable<RegistryConfigurationItem> Items => new []
{
new RegistryConfigurationItem($@"HKEY_USERS\{SID}\Software\VMware, Inc.\VMware VDM\Client", "EnableShade", 0, 1),
new RegistryConfigurationItem($@"HKEY_USERS\{SID}\Software\Policies\VMware, Inc.\VMware VDM\Client", "EnableShade", "False", "True")
};
public VmwareOverlayConfiguration(Guid groupId, ILogger logger, string sid, string userName) : base(groupId, logger, sid, userName)
{
}
}
}

View file

@ -1,46 +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 SignoutConfiguration : FeatureConfiguration
{
public SignoutConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
{
}
public override bool DisableFeature()
{
return true;
}
public override bool EnableFeature()
{
return true;
}
public override void Initialize()
{
}
public override void Monitor()
{
}
public override bool Restore()
{
return true;
}
}
}

View file

@ -1,46 +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 TaskManagerConfiguration : FeatureConfiguration
{
public TaskManagerConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
{
}
public override bool DisableFeature()
{
return true;
}
public override bool EnableFeature()
{
return true;
}
public override void Initialize()
{
}
public override void Monitor()
{
}
public override bool Restore()
{
return true;
}
}
}

View file

@ -1,46 +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 UserLockConfiguration : FeatureConfiguration
{
public UserLockConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
{
}
public override bool DisableFeature()
{
return true;
}
public override bool EnableFeature()
{
return true;
}
public override void Initialize()
{
}
public override void Monitor()
{
}
public override bool Restore()
{
return true;
}
}
}

View file

@ -1,46 +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 UserSwitchConfiguration : FeatureConfiguration
{
public UserSwitchConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
{
}
public override bool DisableFeature()
{
return true;
}
public override bool EnableFeature()
{
return true;
}
public override void Initialize()
{
}
public override void Monitor()
{
}
public override bool Restore()
{
return true;
}
}
}

View file

@ -1,46 +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 VmwareOverlayConfiguration : FeatureConfiguration
{
public VmwareOverlayConfiguration(Guid groupId, ILogger logger) : base(groupId, logger)
{
}
public override bool DisableFeature()
{
return true;
}
public override bool EnableFeature()
{
return true;
}
public override void Initialize()
{
}
public override void Monitor()
{
}
public override bool Restore()
{
return true;
}
}
}

View file

@ -60,19 +60,19 @@
<Compile Include="FeatureConfigurations\RegistryConfigurations\RegistryConfigurationItem.cs" /> <Compile Include="FeatureConfigurations\RegistryConfigurations\RegistryConfigurationItem.cs" />
<Compile Include="FeatureConfigurations\RegistryConfigurations\UserHive\ChromeNotificationConfiguration.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\MachineHive\MachineHiveConfiguration.cs" />
<Compile Include="FeatureConfigurations\RegistryConfigurations\RegistryConfiguration.cs" /> <Compile Include="FeatureConfigurations\RegistryConfigurations\RegistryConfiguration.cs" />
<Compile Include="FeatureConfigurations\RegistryConfigurations\UserHiveConfiguration.cs" /> <Compile Include="FeatureConfigurations\RegistryConfigurations\UserHive\UserHiveConfiguration.cs" />
<Compile Include="FeatureConfigurations\TaskManagerConfiguration.cs" /> <Compile Include="FeatureConfigurations\RegistryConfigurations\UserHive\TaskManagerConfiguration.cs" />
<Compile Include="FeatureConfigurations\EaseOfAccessConfiguration.cs" /> <Compile Include="FeatureConfigurations\RegistryConfigurations\MachineHive\EaseOfAccessConfiguration.cs" />
<Compile Include="FeatureConfigurations\NetworkOptionsConfiguration.cs" /> <Compile Include="FeatureConfigurations\RegistryConfigurations\MachineHive\NetworkOptionsConfiguration.cs" />
<Compile Include="FeatureConfigurations\PasswordChangeConfiguration.cs" /> <Compile Include="FeatureConfigurations\RegistryConfigurations\UserHive\ChangePasswordConfiguration.cs" />
<Compile Include="FeatureConfigurations\PowerOptionsConfiguration.cs" /> <Compile Include="FeatureConfigurations\RegistryConfigurations\MachineHive\PowerOptionsConfiguration.cs" />
<Compile Include="FeatureConfigurations\RemoteConnectionConfiguration.cs" /> <Compile Include="FeatureConfigurations\RegistryConfigurations\MachineHive\RemoteConnectionConfiguration.cs" />
<Compile Include="FeatureConfigurations\SignoutConfiguration.cs" /> <Compile Include="FeatureConfigurations\RegistryConfigurations\UserHive\SignoutConfiguration.cs" />
<Compile Include="FeatureConfigurations\UserLockConfiguration.cs" /> <Compile Include="FeatureConfigurations\RegistryConfigurations\UserHive\LockWorkstationConfiguration.cs" />
<Compile Include="FeatureConfigurations\UserSwitchConfiguration.cs" /> <Compile Include="FeatureConfigurations\RegistryConfigurations\MachineHive\SwitchUserConfiguration.cs" />
<Compile Include="FeatureConfigurations\VmwareOverlayConfiguration.cs" /> <Compile Include="FeatureConfigurations\RegistryConfigurations\UserHive\VmwareOverlayConfiguration.cs" />
<Compile Include="FeatureConfigurations\WindowsUpdateConfiguration.cs" /> <Compile Include="FeatureConfigurations\WindowsUpdateConfiguration.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
@ -82,8 +82,6 @@
<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>

View file

@ -83,17 +83,17 @@ namespace SafeExamBrowser.Service.UnitTests.Operations
sut.Perform(); sut.Perform();
factory.Verify(f => f.CreateChangePasswordConfiguration(It.Is<Guid>(id => id == groupId), It.IsAny<string>(), It.IsAny<string>()), 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.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.CreateLockWorkstationConfiguration(It.Is<Guid>(id => id == groupId), It.IsAny<string>(), It.IsAny<string>()), 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.CreatePowerOptionsConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once); factory.Verify(f => f.CreatePowerOptionsConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
factory.Verify(f => f.CreateRemoteConnectionConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once); factory.Verify(f => f.CreateRemoteConnectionConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
factory.Verify(f => f.CreateSignoutConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once); factory.Verify(f => f.CreateSignoutConfiguration(It.Is<Guid>(id => id == groupId), It.IsAny<string>(), It.IsAny<string>()), Times.Once);
factory.Verify(f => f.CreateTaskManagerConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once); factory.Verify(f => f.CreateSwitchUserConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
factory.Verify(f => f.CreateUserLockConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once); factory.Verify(f => f.CreateTaskManagerConfiguration(It.Is<Guid>(id => id == groupId), It.IsAny<string>(), It.IsAny<string>()), Times.Once);
factory.Verify(f => f.CreateUserSwitchConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once); factory.Verify(f => f.CreateVmwareOverlayConfiguration(It.Is<Guid>(id => id == groupId), It.IsAny<string>(), It.IsAny<string>()), Times.Once);
factory.Verify(f => f.CreateVmwareOverlayConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
factory.Verify(f => f.CreateWindowsUpdateConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once); factory.Verify(f => f.CreateWindowsUpdateConfiguration(It.Is<Guid>(id => id == groupId)), Times.Once);
} }

View file

@ -13,6 +13,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq; using Moq;
using SafeExamBrowser.Contracts.Communication.Hosts; using SafeExamBrowser.Contracts.Communication.Hosts;
using SafeExamBrowser.Contracts.Configuration; using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.Core.OperationModel; using SafeExamBrowser.Contracts.Core.OperationModel;
using SafeExamBrowser.Contracts.Lockdown; using SafeExamBrowser.Contracts.Lockdown;
using SafeExamBrowser.Contracts.Logging; using SafeExamBrowser.Contracts.Logging;
@ -25,7 +26,6 @@ namespace SafeExamBrowser.Service.UnitTests.Operations
{ {
private Mock<IAutoRestoreMechanism> autoRestoreMechanism; private Mock<IAutoRestoreMechanism> autoRestoreMechanism;
private Mock<ILogger> logger; private Mock<ILogger> logger;
private Mock<Func<string, ILogObserver>> logWriterFactory;
private Mock<IServiceHost> serviceHost; private Mock<IServiceHost> serviceHost;
private Mock<Func<string, EventWaitHandle>> serviceEventFactory; private Mock<Func<string, EventWaitHandle>> serviceEventFactory;
private SessionContext sessionContext; private SessionContext sessionContext;
@ -36,20 +36,19 @@ namespace SafeExamBrowser.Service.UnitTests.Operations
{ {
autoRestoreMechanism = new Mock<IAutoRestoreMechanism>(); autoRestoreMechanism = new Mock<IAutoRestoreMechanism>();
logger = new Mock<ILogger>(); logger = new Mock<ILogger>();
logWriterFactory = new Mock<Func<string, ILogObserver>>();
serviceHost = new Mock<IServiceHost>(); serviceHost = new Mock<IServiceHost>();
serviceEventFactory = new Mock<Func<string, EventWaitHandle>>(); serviceEventFactory = new Mock<Func<string, EventWaitHandle>>();
sessionContext = new SessionContext(); sessionContext = new SessionContext();
logWriterFactory.Setup(f => f.Invoke(It.IsAny<string>())).Returns(new Mock<ILogObserver>().Object);
serviceEventFactory.Setup(f => f.Invoke(It.IsAny<string>())).Returns(new EventStub()); serviceEventFactory.Setup(f => f.Invoke(It.IsAny<string>())).Returns(new EventStub());
sessionContext.AutoRestoreMechanism = autoRestoreMechanism.Object; sessionContext.AutoRestoreMechanism = autoRestoreMechanism.Object;
sessionContext.Configuration = new ServiceConfiguration sessionContext.Configuration = new ServiceConfiguration
{ {
AppConfig = new AppConfig { ServiceEventName = $"{nameof(SafeExamBrowser)}-{nameof(SessionInitializationOperationTests)}" } AppConfig = new AppConfig { ServiceEventName = $"{nameof(SafeExamBrowser)}-{nameof(SessionInitializationOperationTests)}" },
Settings = new Settings()
}; };
sut = new SessionInitializationOperation(logger.Object, logWriterFactory.Object, serviceEventFactory.Object, serviceHost.Object, sessionContext); sut = new SessionInitializationOperation(logger.Object, serviceEventFactory.Object, serviceHost.Object, sessionContext);
} }
[TestMethod] [TestMethod]

View file

@ -12,6 +12,7 @@ using Moq;
using SafeExamBrowser.Contracts.Communication.Events; using SafeExamBrowser.Contracts.Communication.Events;
using SafeExamBrowser.Contracts.Communication.Hosts; using SafeExamBrowser.Contracts.Communication.Hosts;
using SafeExamBrowser.Contracts.Configuration; using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.Core.OperationModel; using SafeExamBrowser.Contracts.Core.OperationModel;
using SafeExamBrowser.Contracts.Logging; using SafeExamBrowser.Contracts.Logging;
@ -21,6 +22,7 @@ namespace SafeExamBrowser.Service.UnitTests
public class ServiceControllerTests public class ServiceControllerTests
{ {
private Mock<ILogger> logger; private Mock<ILogger> logger;
private Mock<Func<string, ILogObserver>> logWriterFactory;
private Mock<IOperationSequence> bootstrapSequence; private Mock<IOperationSequence> bootstrapSequence;
private SessionContext sessionContext; private SessionContext sessionContext;
private Mock<IOperationSequence> sessionSequence; private Mock<IOperationSequence> sessionSequence;
@ -31,12 +33,15 @@ namespace SafeExamBrowser.Service.UnitTests
public void Initialize() public void Initialize()
{ {
logger = new Mock<ILogger>(); logger = new Mock<ILogger>();
logWriterFactory = new Mock<Func<string, ILogObserver>>();
bootstrapSequence = new Mock<IOperationSequence>(); bootstrapSequence = new Mock<IOperationSequence>();
sessionContext = new SessionContext(); sessionContext = new SessionContext();
sessionSequence = new Mock<IOperationSequence>(); sessionSequence = new Mock<IOperationSequence>();
serviceHost = new Mock<IServiceHost>(); serviceHost = new Mock<IServiceHost>();
sut = new ServiceController(logger.Object, bootstrapSequence.Object, sessionSequence.Object, serviceHost.Object, sessionContext); logWriterFactory.Setup(f => f.Invoke(It.IsAny<string>())).Returns(new Mock<ILogObserver>().Object);
sut = new ServiceController(logger.Object, logWriterFactory.Object, bootstrapSequence.Object, sessionSequence.Object, serviceHost.Object, sessionContext);
} }
[TestMethod] [TestMethod]
@ -56,6 +61,28 @@ namespace SafeExamBrowser.Service.UnitTests
Assert.AreEqual(args.Configuration.SessionId, sessionContext.Configuration.SessionId); Assert.AreEqual(args.Configuration.SessionId, sessionContext.Configuration.SessionId);
} }
[TestMethod]
public void Communication_MustInitializeSessionLogging()
{
var args = new SessionStartEventArgs
{
Configuration = new ServiceConfiguration
{
AppConfig = new AppConfig { ServiceLogFilePath = "Test.log" },
SessionId = Guid.NewGuid(),
Settings = new Settings { LogLevel = LogLevel.Warning }
}
};
bootstrapSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success);
sessionSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success);
sut.TryStart();
serviceHost.Raise(h => h.SessionStartRequested += null, args);
logger.VerifySet(l => l.LogLevel = It.Is<LogLevel>(ll => ll == args.Configuration.Settings.LogLevel), Times.Once);
}
[TestMethod] [TestMethod]
public void Communication_MustNotAllowNewSessionDuringActiveSession() public void Communication_MustNotAllowNewSessionDuringActiveSession()
{ {
@ -73,6 +100,22 @@ namespace SafeExamBrowser.Service.UnitTests
Assert.AreNotEqual(args.Configuration.SessionId, sessionContext.Configuration.SessionId); Assert.AreNotEqual(args.Configuration.SessionId, sessionContext.Configuration.SessionId);
} }
[TestMethod]
public void Communication_MustNotFailIfNoValidSessionData()
{
var args = new SessionStartEventArgs { Configuration = null };
bootstrapSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success);
sessionSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success);
sut.TryStart();
serviceHost.Raise(h => h.SessionStartRequested += null, args);
sessionSequence.Verify(s => s.TryPerform(), Times.Once);
Assert.IsNull(sessionContext.Configuration);
}
[TestMethod] [TestMethod]
public void Communication_MustStopActiveSessionUponRequest() public void Communication_MustStopActiveSessionUponRequest()
{ {

View file

@ -56,14 +56,14 @@ namespace SafeExamBrowser.Service
bootstrapOperations.Enqueue(new CommunicationHostOperation(serviceHost, logger)); bootstrapOperations.Enqueue(new CommunicationHostOperation(serviceHost, logger));
bootstrapOperations.Enqueue(new ServiceEventCleanupOperation(logger, sessionContext)); bootstrapOperations.Enqueue(new ServiceEventCleanupOperation(logger, sessionContext));
sessionOperations.Enqueue(new SessionInitializationOperation(logger, LogWriterFactory, ServiceEventFactory, serviceHost, sessionContext)); sessionOperations.Enqueue(new SessionInitializationOperation(logger, ServiceEventFactory, serviceHost, sessionContext));
sessionOperations.Enqueue(new LockdownOperation(featureBackup, featureFactory, logger, sessionContext)); sessionOperations.Enqueue(new LockdownOperation(featureBackup, featureFactory, logger, sessionContext));
sessionOperations.Enqueue(new SessionActivationOperation(logger, sessionContext)); sessionOperations.Enqueue(new SessionActivationOperation(logger, sessionContext));
var bootstrapSequence = new OperationSequence(logger, bootstrapOperations); var bootstrapSequence = new OperationSequence(logger, bootstrapOperations);
var sessionSequence = new OperationSequence(logger, sessionOperations); var sessionSequence = new OperationSequence(logger, sessionOperations);
ServiceController = new ServiceController(logger, bootstrapSequence, sessionSequence, serviceHost, sessionContext); ServiceController = new ServiceController(logger, LogWriterFactory, bootstrapSequence, sessionSequence, serviceHost, sessionContext);
} }
private string BuildBackupFilePath() private string BuildBackupFilePath()

View file

@ -40,17 +40,17 @@ namespace SafeExamBrowser.Service.Operations
var userName = Context.Configuration.UserName; var userName = Context.Configuration.UserName;
var configurations = new [] var configurations = new []
{ {
(factory.CreateChangePasswordConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisablePasswordChange),
(factory.CreateChromeNotificationConfiguration(groupId, sid, userName), 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.CreateLockWorkstationConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisableUserLock),
(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.CreatePowerOptionsConfiguration(groupId), Context.Configuration.Settings.Service.DisablePowerOptions), (factory.CreatePowerOptionsConfiguration(groupId), Context.Configuration.Settings.Service.DisablePowerOptions),
(factory.CreateRemoteConnectionConfiguration(groupId), Context.Configuration.Settings.Service.DisableRemoteConnections), (factory.CreateRemoteConnectionConfiguration(groupId), Context.Configuration.Settings.Service.DisableRemoteConnections),
(factory.CreateSignoutConfiguration(groupId), Context.Configuration.Settings.Service.DisableSignout), (factory.CreateSignoutConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisableSignout),
(factory.CreateTaskManagerConfiguration(groupId), Context.Configuration.Settings.Service.DisableTaskManager), (factory.CreateSwitchUserConfiguration(groupId), Context.Configuration.Settings.Service.DisableUserSwitch),
(factory.CreateUserLockConfiguration(groupId), Context.Configuration.Settings.Service.DisableUserLock), (factory.CreateTaskManagerConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisableTaskManager),
(factory.CreateUserSwitchConfiguration(groupId), Context.Configuration.Settings.Service.DisableUserSwitch), (factory.CreateVmwareOverlayConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisableVmwareOverlay),
(factory.CreateVmwareOverlayConfiguration(groupId), Context.Configuration.Settings.Service.DisableVmwareOverlay),
(factory.CreateWindowsUpdateConfiguration(groupId), Context.Configuration.Settings.Service.DisableWindowsUpdate) (factory.CreateWindowsUpdateConfiguration(groupId), Context.Configuration.Settings.Service.DisableWindowsUpdate)
}; };

View file

@ -17,28 +17,22 @@ namespace SafeExamBrowser.Service.Operations
internal class SessionInitializationOperation : SessionOperation internal class SessionInitializationOperation : SessionOperation
{ {
private ILogger logger; private ILogger logger;
private Func<string, ILogObserver> logWriterFactory;
private Func<string, EventWaitHandle> serviceEventFactory; private Func<string, EventWaitHandle> serviceEventFactory;
private IServiceHost serviceHost; private IServiceHost serviceHost;
private ILogObserver sessionWriter;
public SessionInitializationOperation( public SessionInitializationOperation(
ILogger logger, ILogger logger,
Func<string, ILogObserver> logWriterFactory,
Func<string, EventWaitHandle> serviceEventFactory, Func<string, EventWaitHandle> serviceEventFactory,
IServiceHost serviceHost, IServiceHost serviceHost,
SessionContext sessionContext) : base(sessionContext) SessionContext sessionContext) : base(sessionContext)
{ {
this.logger = logger; this.logger = logger;
this.logWriterFactory = logWriterFactory;
this.serviceEventFactory = serviceEventFactory; this.serviceEventFactory = serviceEventFactory;
this.serviceHost = serviceHost; this.serviceHost = serviceHost;
} }
public override OperationResult Perform() public override OperationResult Perform()
{ {
InitializeSessionWriter();
logger.Info("Initializing new session..."); logger.Info("Initializing new session...");
logger.Info($" -> Client-ID: {Context.Configuration.AppConfig.ClientId}"); logger.Info($" -> Client-ID: {Context.Configuration.AppConfig.ClientId}");
logger.Info($" -> Runtime-ID: {Context.Configuration.AppConfig.RuntimeId}"); logger.Info($" -> Runtime-ID: {Context.Configuration.AppConfig.RuntimeId}");
@ -85,8 +79,6 @@ namespace SafeExamBrowser.Service.Operations
Context.Configuration = null; Context.Configuration = null;
Context.IsRunning = false; Context.IsRunning = false;
FinalizeSessionWriter();
return success ? OperationResult.Success : OperationResult.Failed; return success ? OperationResult.Success : OperationResult.Failed;
} }
@ -103,19 +95,5 @@ namespace SafeExamBrowser.Service.Operations
Context.ServiceEvent = serviceEventFactory.Invoke(Context.Configuration.AppConfig.ServiceEventName); Context.ServiceEvent = serviceEventFactory.Invoke(Context.Configuration.AppConfig.ServiceEventName);
logger.Info("Service event successfully created."); logger.Info("Service event successfully created.");
} }
private void InitializeSessionWriter()
{
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;
}
} }
} }

View file

@ -18,11 +18,13 @@ namespace SafeExamBrowser.Service
{ {
internal class ServiceController : IServiceController internal class ServiceController : IServiceController
{ {
private readonly ILogger logger; private ILogger logger;
private Func<string, ILogObserver> logWriterFactory;
private IOperationSequence bootstrapSequence; private IOperationSequence bootstrapSequence;
private IOperationSequence sessionSequence; private IOperationSequence sessionSequence;
private IServiceHost serviceHost; private IServiceHost serviceHost;
private SessionContext sessionContext; private SessionContext sessionContext;
private ILogObserver sessionWriter;
private ServiceConfiguration Session private ServiceConfiguration Session
{ {
@ -36,12 +38,14 @@ namespace SafeExamBrowser.Service
public ServiceController( public ServiceController(
ILogger logger, ILogger logger,
Func<string, ILogObserver> logWriterFactory,
IOperationSequence bootstrapSequence, IOperationSequence bootstrapSequence,
IOperationSequence sessionSequence, IOperationSequence sessionSequence,
IServiceHost serviceHost, IServiceHost serviceHost,
SessionContext sessionContext) SessionContext sessionContext)
{ {
this.logger = logger; this.logger = logger;
this.logWriterFactory = logWriterFactory;
this.bootstrapSequence = bootstrapSequence; this.bootstrapSequence = bootstrapSequence;
this.sessionSequence = sessionSequence; this.sessionSequence = sessionSequence;
this.serviceHost = serviceHost; this.serviceHost = serviceHost;
@ -100,6 +104,7 @@ namespace SafeExamBrowser.Service
private void StartSession() private void StartSession()
{ {
InitializeSessionLogging();
logger.Info(AppendDivider("Session Start Procedure")); logger.Info(AppendDivider("Session Start Procedure"));
var result = sessionSequence.TryPerform(); var result = sessionSequence.TryPerform();
@ -128,6 +133,8 @@ namespace SafeExamBrowser.Service
{ {
logger.Info(AppendDivider("Session Stop Failed")); logger.Info(AppendDivider("Session Stop Failed"));
} }
FinalizeSessionLogging();
} }
private void RegisterEvents() private void RegisterEvents()
@ -182,5 +189,28 @@ namespace SafeExamBrowser.Service
return $"### {dashesLeft} {message} {dashesRight} ###"; return $"### {dashesLeft} {message} {dashesRight} ###";
} }
private void InitializeSessionLogging()
{
if (Session?.AppConfig?.ServiceLogFilePath != null)
{
sessionWriter = logWriterFactory.Invoke(Session.AppConfig.ServiceLogFilePath);
logger.Subscribe(sessionWriter);
logger.LogLevel = Session.Settings.LogLevel;
}
else
{
logger.Warn("Could not initialize session writer due to missing configuration data!");
}
}
private void FinalizeSessionLogging()
{
if (sessionWriter != null)
{
logger.Unsubscribe(sessionWriter);
sessionWriter = null;
}
}
} }
} }