seb-win-refactoring/SafeExamBrowser.Service/Operations/LockdownOperation.cs

166 lines
5.1 KiB
C#

/*
* Copyright (c) 2024 ETH Zürich, IT Services
*
* 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.Core.Contracts.OperationModel;
using SafeExamBrowser.Lockdown.Contracts;
using SafeExamBrowser.Logging.Contracts;
namespace SafeExamBrowser.Service.Operations
{
internal class LockdownOperation : SessionOperation
{
private readonly IFeatureConfigurationBackup backup;
private readonly IFeatureConfigurationFactory factory;
private readonly IFeatureConfigurationMonitor monitor;
private readonly ILogger logger;
private Guid groupId;
public LockdownOperation(
IFeatureConfigurationBackup backup,
IFeatureConfigurationFactory factory,
IFeatureConfigurationMonitor monitor,
ILogger logger,
SessionContext sessionContext) : base(sessionContext)
{
this.backup = backup;
this.factory = factory;
this.monitor = monitor;
this.logger = logger;
}
public override OperationResult Perform()
{
groupId = Guid.NewGuid();
var success = true;
var sid = Context.Configuration.UserSid;
var userName = Context.Configuration.UserName;
var configurations = new List<(IFeatureConfiguration, bool)>
{
(factory.CreateChangePasswordConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisablePasswordChange),
(factory.CreateChromeNotificationConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisableChromeNotifications),
(factory.CreateEaseOfAccessConfiguration(groupId), Context.Configuration.Settings.Service.DisableEaseOfAccessOptions),
(factory.CreateFindPrinterConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisableFindPrinter),
(factory.CreateLockWorkstationConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisableUserLock),
(factory.CreateMachinePowerOptionsConfiguration(groupId), Context.Configuration.Settings.Service.DisablePowerOptions),
(factory.CreateNetworkOptionsConfiguration(groupId), Context.Configuration.Settings.Service.DisableNetworkOptions),
(factory.CreateRemoteConnectionConfiguration(groupId), Context.Configuration.Settings.Service.DisableRemoteConnections),
(factory.CreateSignoutConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisableSignout),
(factory.CreateSwitchUserConfiguration(groupId), Context.Configuration.Settings.Service.DisableUserSwitch),
(factory.CreateTaskManagerConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisableTaskManager),
(factory.CreateUserPowerOptionsConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisablePowerOptions),
(factory.CreateWindowsUpdateConfiguration(groupId), Context.Configuration.Settings.Service.DisableWindowsUpdate)
};
if (Context.Configuration.Settings.Service.SetVmwareConfiguration)
{
configurations.Add((factory.CreateVmwareOverlayConfiguration(groupId, sid, userName), Context.Configuration.Settings.Service.DisableVmwareOverlay));
}
logger.Info($"Attempting to perform lockdown (feature configuration group: {groupId})...");
foreach (var (configuration, disable) in configurations)
{
success &= TrySet(configuration, disable);
if (!success)
{
break;
}
}
if (success)
{
monitor.Start();
logger.Info("Lockdown successful.");
}
else
{
logger.Error("Lockdown was not successful!");
}
return success ? OperationResult.Success : OperationResult.Failed;
}
public override OperationResult Revert()
{
logger.Info($"Attempting to revert lockdown (feature configuration group: {groupId})...");
var configurations = backup.GetBy(groupId);
var success = true;
monitor.Reset();
foreach (var configuration in configurations)
{
success &= TryRestore(configuration);
}
if (success)
{
logger.Info("Lockdown reversion successful.");
}
else
{
logger.Warn("Lockdown reversion was not successful!");
}
return success ? OperationResult.Success : OperationResult.Failed;
}
private bool TryRestore(IFeatureConfiguration configuration)
{
var success = configuration.Restore();
if (success)
{
backup.Delete(configuration);
}
else
{
logger.Error($"Failed to restore {configuration}!");
}
return success;
}
private bool TrySet(IFeatureConfiguration configuration, bool disable)
{
var success = false;
var status = FeatureConfigurationStatus.Undefined;
configuration.Initialize();
backup.Save(configuration);
if (disable)
{
success = configuration.DisableFeature();
status = FeatureConfigurationStatus.Disabled;
}
else
{
success = configuration.EnableFeature();
status = FeatureConfigurationStatus.Enabled;
}
if (success)
{
monitor.Observe(configuration, status);
}
else
{
logger.Error($"Failed to configure {configuration}!");
}
return success;
}
}
}