2018-01-16 08:14:57 +01:00
|
|
|
|
/*
|
2018-01-16 08:24:00 +01:00
|
|
|
|
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
2018-01-16 08:14:57 +01:00
|
|
|
|
*
|
|
|
|
|
* 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/.
|
|
|
|
|
*/
|
|
|
|
|
|
2018-02-12 12:21:55 +01:00
|
|
|
|
using System;
|
2018-01-16 08:14:57 +01:00
|
|
|
|
using System.Collections.Generic;
|
2018-02-16 13:15:16 +01:00
|
|
|
|
using System.Diagnostics;
|
2018-08-31 10:06:27 +02:00
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Reflection;
|
2018-01-17 08:26:44 +01:00
|
|
|
|
using SafeExamBrowser.Browser;
|
2018-02-12 12:21:55 +01:00
|
|
|
|
using SafeExamBrowser.Client.Communication;
|
2018-02-28 09:45:29 +01:00
|
|
|
|
using SafeExamBrowser.Client.Notifications;
|
2018-08-31 10:06:27 +02:00
|
|
|
|
using SafeExamBrowser.Client.Operations;
|
|
|
|
|
using SafeExamBrowser.Communication.Hosts;
|
|
|
|
|
using SafeExamBrowser.Communication.Proxies;
|
2018-01-17 08:26:44 +01:00
|
|
|
|
using SafeExamBrowser.Configuration;
|
2018-06-21 07:56:25 +02:00
|
|
|
|
using SafeExamBrowser.Contracts.Browser;
|
2018-03-15 14:32:07 +01:00
|
|
|
|
using SafeExamBrowser.Contracts.Communication.Hosts;
|
|
|
|
|
using SafeExamBrowser.Contracts.Communication.Proxies;
|
2018-01-17 08:26:44 +01:00
|
|
|
|
using SafeExamBrowser.Contracts.Configuration;
|
2018-08-31 10:06:27 +02:00
|
|
|
|
using SafeExamBrowser.Contracts.Core;
|
|
|
|
|
using SafeExamBrowser.Contracts.Core.OperationModel;
|
2018-01-17 08:26:44 +01:00
|
|
|
|
using SafeExamBrowser.Contracts.I18n;
|
|
|
|
|
using SafeExamBrowser.Contracts.Logging;
|
2018-08-17 14:48:50 +02:00
|
|
|
|
using SafeExamBrowser.Contracts.Monitoring;
|
2018-01-17 08:26:44 +01:00
|
|
|
|
using SafeExamBrowser.Contracts.UserInterface;
|
2018-03-14 12:07:20 +01:00
|
|
|
|
using SafeExamBrowser.Contracts.UserInterface.MessageBox;
|
2018-01-17 08:26:44 +01:00
|
|
|
|
using SafeExamBrowser.Contracts.WindowsApi;
|
2018-08-31 10:06:27 +02:00
|
|
|
|
using SafeExamBrowser.Core.OperationModel;
|
|
|
|
|
using SafeExamBrowser.Core.Operations;
|
|
|
|
|
using SafeExamBrowser.I18n;
|
|
|
|
|
using SafeExamBrowser.Logging;
|
2018-02-12 12:21:55 +01:00
|
|
|
|
using SafeExamBrowser.Monitoring.Display;
|
|
|
|
|
using SafeExamBrowser.Monitoring.Keyboard;
|
|
|
|
|
using SafeExamBrowser.Monitoring.Mouse;
|
|
|
|
|
using SafeExamBrowser.Monitoring.Processes;
|
|
|
|
|
using SafeExamBrowser.Monitoring.Windows;
|
|
|
|
|
using SafeExamBrowser.SystemComponents;
|
2018-01-16 08:14:57 +01:00
|
|
|
|
using SafeExamBrowser.UserInterface.Classic;
|
2018-01-17 08:26:44 +01:00
|
|
|
|
using SafeExamBrowser.WindowsApi;
|
2018-01-16 08:14:57 +01:00
|
|
|
|
|
|
|
|
|
namespace SafeExamBrowser.Client
|
|
|
|
|
{
|
|
|
|
|
internal class CompositionRoot
|
|
|
|
|
{
|
2018-02-16 13:15:16 +01:00
|
|
|
|
private string logFilePath;
|
|
|
|
|
private string runtimeHostUri;
|
|
|
|
|
private Guid startupToken;
|
|
|
|
|
|
2018-06-21 07:56:25 +02:00
|
|
|
|
private IBrowserApplicationController browserController;
|
2018-02-15 15:42:54 +01:00
|
|
|
|
private ClientConfiguration configuration;
|
2018-02-21 14:01:21 +01:00
|
|
|
|
private IClientHost clientHost;
|
2018-01-17 08:26:44 +01:00
|
|
|
|
private ILogger logger;
|
2018-03-14 12:07:20 +01:00
|
|
|
|
private IMessageBox messageBox;
|
2018-08-17 14:48:50 +02:00
|
|
|
|
private IProcessMonitor processMonitor;
|
2018-01-17 08:26:44 +01:00
|
|
|
|
private INativeMethods nativeMethods;
|
2018-03-08 15:27:12 +01:00
|
|
|
|
private IRuntimeProxy runtimeProxy;
|
2018-01-17 08:26:44 +01:00
|
|
|
|
private ISystemInfo systemInfo;
|
|
|
|
|
private IText text;
|
2018-08-31 10:06:27 +02:00
|
|
|
|
private ITextResource textResource;
|
2018-01-17 08:26:44 +01:00
|
|
|
|
private IUserInterfaceFactory uiFactory;
|
2018-01-16 08:14:57 +01:00
|
|
|
|
|
2018-02-12 12:21:55 +01:00
|
|
|
|
internal IClientController ClientController { get; private set; }
|
2018-01-17 08:26:44 +01:00
|
|
|
|
internal Taskbar Taskbar { get; private set; }
|
|
|
|
|
|
2018-02-21 14:01:21 +01:00
|
|
|
|
internal void BuildObjectGraph(Action shutdown)
|
2018-01-16 08:14:57 +01:00
|
|
|
|
{
|
2018-02-16 13:15:16 +01:00
|
|
|
|
ValidateCommandLineArguments();
|
2018-02-12 12:21:55 +01:00
|
|
|
|
|
|
|
|
|
configuration = new ClientConfiguration();
|
2018-01-17 14:08:39 +01:00
|
|
|
|
logger = new Logger();
|
2018-01-17 08:26:44 +01:00
|
|
|
|
nativeMethods = new NativeMethods();
|
|
|
|
|
systemInfo = new SystemInfo();
|
|
|
|
|
|
2018-02-16 13:15:16 +01:00
|
|
|
|
InitializeLogging();
|
2018-08-31 10:06:27 +02:00
|
|
|
|
InitializeText();
|
2018-01-17 08:26:44 +01:00
|
|
|
|
|
2018-03-14 12:07:20 +01:00
|
|
|
|
messageBox = new MessageBox(text);
|
2018-08-31 15:29:36 +02:00
|
|
|
|
processMonitor = new ProcessMonitor(new ModuleLogger(logger, nameof(ProcessMonitor)), nativeMethods);
|
2018-02-07 13:25:49 +01:00
|
|
|
|
uiFactory = new UserInterfaceFactory(text);
|
2018-08-31 15:29:36 +02:00
|
|
|
|
runtimeProxy = new RuntimeProxy(runtimeHostUri, new ProxyObjectFactory(), new ModuleLogger(logger, nameof(RuntimeProxy)));
|
2018-02-12 12:21:55 +01:00
|
|
|
|
|
2018-08-31 15:29:36 +02:00
|
|
|
|
var displayMonitor = new DisplayMonitor(new ModuleLogger(logger, nameof(DisplayMonitor)), nativeMethods);
|
|
|
|
|
var explorerShell = new ExplorerShell(new ModuleLogger(logger, nameof(ExplorerShell)), nativeMethods);
|
|
|
|
|
var windowMonitor = new WindowMonitor(new ModuleLogger(logger, nameof(WindowMonitor)), nativeMethods);
|
2018-02-12 12:21:55 +01:00
|
|
|
|
|
2018-08-31 15:29:36 +02:00
|
|
|
|
Taskbar = new Taskbar(new ModuleLogger(logger, nameof(Taskbar)));
|
2018-02-12 12:21:55 +01:00
|
|
|
|
|
|
|
|
|
var operations = new Queue<IOperation>();
|
|
|
|
|
|
2018-08-31 10:06:27 +02:00
|
|
|
|
operations.Enqueue(new I18nOperation(logger, text, textResource));
|
2018-02-16 13:15:16 +01:00
|
|
|
|
operations.Enqueue(new RuntimeConnectionOperation(logger, runtimeProxy, startupToken));
|
2018-02-12 12:21:55 +01:00
|
|
|
|
operations.Enqueue(new ConfigurationOperation(configuration, logger, runtimeProxy));
|
2018-08-10 13:23:24 +02:00
|
|
|
|
operations.Enqueue(new DelegateOperation(UpdateAppConfig));
|
2018-02-12 12:21:55 +01:00
|
|
|
|
operations.Enqueue(new DelayedInitializationOperation(BuildCommunicationHostOperation));
|
2018-02-16 13:15:16 +01:00
|
|
|
|
// TODO
|
|
|
|
|
//operations.Enqueue(new DelayedInitializationOperation(BuildKeyboardInterceptorOperation));
|
|
|
|
|
//operations.Enqueue(new WindowMonitorOperation(logger, windowMonitor));
|
2018-08-17 14:48:50 +02:00
|
|
|
|
operations.Enqueue(new DelayedInitializationOperation(BuildProcessMonitorOperation));
|
2018-02-12 12:21:55 +01:00
|
|
|
|
operations.Enqueue(new DisplayMonitorOperation(displayMonitor, logger, Taskbar));
|
|
|
|
|
operations.Enqueue(new DelayedInitializationOperation(BuildTaskbarOperation));
|
|
|
|
|
operations.Enqueue(new DelayedInitializationOperation(BuildBrowserOperation));
|
|
|
|
|
operations.Enqueue(new ClipboardOperation(logger, nativeMethods));
|
2018-02-16 13:15:16 +01:00
|
|
|
|
//operations.Enqueue(new DelayedInitializationOperation(BuildMouseInterceptorOperation));
|
2018-06-21 07:56:25 +02:00
|
|
|
|
operations.Enqueue(new DelegateOperation(UpdateClientControllerDependencies));
|
2018-02-12 12:21:55 +01:00
|
|
|
|
|
|
|
|
|
var sequence = new OperationSequence(logger, operations);
|
|
|
|
|
|
2018-08-17 14:48:50 +02:00
|
|
|
|
ClientController = new ClientController(displayMonitor, explorerShell, logger, messageBox, sequence, processMonitor, runtimeProxy, shutdown, Taskbar, text, uiFactory, windowMonitor);
|
2018-02-12 12:21:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-02-16 13:15:16 +01:00
|
|
|
|
internal void LogStartupInformation()
|
|
|
|
|
{
|
|
|
|
|
logger.Log($"# New client instance started at {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
|
|
|
|
|
logger.Log(string.Empty);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal void LogShutdownInformation()
|
2018-02-12 12:21:55 +01:00
|
|
|
|
{
|
2018-02-16 13:15:16 +01:00
|
|
|
|
logger?.Log($"# Client instance terminated at {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ValidateCommandLineArguments()
|
|
|
|
|
{
|
|
|
|
|
var args = Environment.GetCommandLineArgs();
|
2018-02-15 15:42:54 +01:00
|
|
|
|
var hasFour = args?.Length == 4;
|
2018-02-12 12:21:55 +01:00
|
|
|
|
|
2018-02-15 15:42:54 +01:00
|
|
|
|
if (hasFour)
|
2018-02-12 12:21:55 +01:00
|
|
|
|
{
|
|
|
|
|
var hasLogfilePath = Uri.TryCreate(args?[1], UriKind.Absolute, out Uri filePath) && filePath.IsFile;
|
|
|
|
|
var hasHostUri = Uri.TryCreate(args?[2], UriKind.Absolute, out Uri hostUri) && hostUri.IsWellFormedOriginalString();
|
|
|
|
|
var hasToken = Guid.TryParse(args?[3], out Guid token);
|
|
|
|
|
|
|
|
|
|
if (hasLogfilePath && hasHostUri && hasToken)
|
|
|
|
|
{
|
2018-02-16 13:15:16 +01:00
|
|
|
|
logFilePath = args[1];
|
|
|
|
|
runtimeHostUri = args[2];
|
|
|
|
|
startupToken = Guid.Parse(args[3]);
|
|
|
|
|
|
2018-02-12 12:21:55 +01:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-16 13:15:16 +01:00
|
|
|
|
throw new ArgumentException("Invalid arguments! Required: SafeExamBrowser.Client.exe <logfile path> <host URI> <token>");
|
2018-02-12 12:21:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-02-16 13:15:16 +01:00
|
|
|
|
private void InitializeLogging()
|
2018-02-12 12:21:55 +01:00
|
|
|
|
{
|
2018-02-16 13:15:16 +01:00
|
|
|
|
var logFileWriter = new LogFileWriter(new DefaultLogFormatter(), logFilePath);
|
2018-02-12 12:21:55 +01:00
|
|
|
|
|
|
|
|
|
logFileWriter.Initialize();
|
|
|
|
|
logger.Subscribe(logFileWriter);
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-31 10:06:27 +02:00
|
|
|
|
private void InitializeText()
|
|
|
|
|
{
|
|
|
|
|
var location = Assembly.GetAssembly(typeof(XmlTextResource)).Location;
|
|
|
|
|
var path = $@"{Path.GetDirectoryName(location)}\Text.xml";
|
|
|
|
|
|
|
|
|
|
text = new Text(logger);
|
|
|
|
|
textResource = new XmlTextResource(path);
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-12 12:21:55 +01:00
|
|
|
|
private IOperation BuildBrowserOperation()
|
|
|
|
|
{
|
2018-08-31 07:49:41 +02:00
|
|
|
|
var moduleLogger = new ModuleLogger(logger, "BrowserController");
|
2018-06-29 09:50:20 +02:00
|
|
|
|
var browserController = new BrowserApplicationController(configuration.AppConfig, configuration.Settings.Browser, moduleLogger, messageBox, text, uiFactory);
|
2018-02-12 12:21:55 +01:00
|
|
|
|
var browserInfo = new BrowserApplicationInfo();
|
|
|
|
|
var operation = new BrowserOperation(browserController, browserInfo, logger, Taskbar, uiFactory);
|
|
|
|
|
|
2018-06-21 07:56:25 +02:00
|
|
|
|
this.browserController = browserController;
|
|
|
|
|
|
2018-02-12 12:21:55 +01:00
|
|
|
|
return operation;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private IOperation BuildCommunicationHostOperation()
|
|
|
|
|
{
|
2018-02-16 13:15:16 +01:00
|
|
|
|
var processId = Process.GetCurrentProcess().Id;
|
2018-03-16 15:46:53 +01:00
|
|
|
|
var factory = new HostObjectFactory();
|
2018-08-31 15:29:36 +02:00
|
|
|
|
var host = new ClientHost(configuration.AppConfig.ClientAddress, factory, new ModuleLogger(logger, nameof(ClientHost)), processId);
|
2018-02-12 12:21:55 +01:00
|
|
|
|
var operation = new CommunicationOperation(host, logger);
|
|
|
|
|
|
2018-02-21 14:01:21 +01:00
|
|
|
|
clientHost = host;
|
|
|
|
|
clientHost.StartupToken = startupToken;
|
2018-02-16 13:15:16 +01:00
|
|
|
|
|
2018-02-12 12:21:55 +01:00
|
|
|
|
return operation;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private IOperation BuildKeyboardInterceptorOperation()
|
|
|
|
|
{
|
2018-08-31 15:29:36 +02:00
|
|
|
|
var keyboardInterceptor = new KeyboardInterceptor(configuration.Settings.Keyboard, new ModuleLogger(logger, nameof(KeyboardInterceptor)));
|
2018-02-12 12:21:55 +01:00
|
|
|
|
var operation = new KeyboardInterceptorOperation(keyboardInterceptor, logger, nativeMethods);
|
|
|
|
|
|
|
|
|
|
return operation;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private IOperation BuildMouseInterceptorOperation()
|
|
|
|
|
{
|
2018-08-31 15:29:36 +02:00
|
|
|
|
var mouseInterceptor = new MouseInterceptor(new ModuleLogger(logger, nameof(MouseInterceptor)), configuration.Settings.Mouse);
|
2018-02-12 12:21:55 +01:00
|
|
|
|
var operation = new MouseInterceptorOperation(logger, mouseInterceptor, nativeMethods);
|
|
|
|
|
|
|
|
|
|
return operation;
|
2018-01-17 08:26:44 +01:00
|
|
|
|
}
|
|
|
|
|
|
2018-08-17 14:48:50 +02:00
|
|
|
|
private IOperation BuildProcessMonitorOperation()
|
|
|
|
|
{
|
|
|
|
|
return new ProcessMonitorOperation(logger, processMonitor, configuration.Settings);
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-12 12:21:55 +01:00
|
|
|
|
private IOperation BuildTaskbarOperation()
|
2018-01-17 08:26:44 +01:00
|
|
|
|
{
|
2018-08-31 15:29:36 +02:00
|
|
|
|
var keyboardLayout = new KeyboardLayout(new ModuleLogger(logger, nameof(KeyboardLayout)), text);
|
2018-02-28 09:45:29 +01:00
|
|
|
|
var logController = new LogNotificationController(logger, uiFactory);
|
|
|
|
|
var logInfo = new LogNotificationInfo(text);
|
2018-08-31 15:29:36 +02:00
|
|
|
|
var powerSupply = new PowerSupply(new ModuleLogger(logger, nameof(PowerSupply)), text);
|
|
|
|
|
var wirelessNetwork = new WirelessNetwork(new ModuleLogger(logger, nameof(WirelessNetwork)), text);
|
2018-02-28 09:45:29 +01:00
|
|
|
|
var operation = new TaskbarOperation(logger, logInfo, logController, keyboardLayout, powerSupply, wirelessNetwork, systemInfo, Taskbar, configuration.Settings.Taskbar, text, uiFactory);
|
2018-01-17 14:08:39 +01:00
|
|
|
|
|
2018-02-12 12:21:55 +01:00
|
|
|
|
return operation;
|
2018-01-16 08:14:57 +01:00
|
|
|
|
}
|
2018-02-21 14:01:21 +01:00
|
|
|
|
|
2018-08-10 13:23:24 +02:00
|
|
|
|
private void UpdateAppConfig()
|
2018-02-21 14:01:21 +01:00
|
|
|
|
{
|
2018-06-29 09:50:20 +02:00
|
|
|
|
ClientController.AppConfig = configuration.AppConfig;
|
2018-08-10 13:23:24 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateClientControllerDependencies()
|
|
|
|
|
{
|
2018-06-21 07:56:25 +02:00
|
|
|
|
ClientController.Browser = browserController;
|
2018-02-21 14:01:21 +01:00
|
|
|
|
ClientController.ClientHost = clientHost;
|
|
|
|
|
ClientController.SessionId = configuration.SessionId;
|
|
|
|
|
ClientController.Settings = configuration.Settings;
|
|
|
|
|
}
|
2018-01-16 08:14:57 +01:00
|
|
|
|
}
|
|
|
|
|
}
|