From 5bd1d9dea4efaccaa9e2231ba7fc70e2ed34f295 Mon Sep 17 00:00:00 2001 From: dbuechel Date: Thu, 8 Mar 2018 07:35:58 +0100 Subject: [PATCH] SEBWIN-219: Found acceptable solution for interception of configuration requests. --- .../BrowserApplicationController.cs | 33 ++++++------ .../BrowserApplicationInstance.cs | 6 ++- SafeExamBrowser.Browser/BrowserControl.cs | 10 +++- ...xtMenuHandler.cs => ContextMenuHandler.cs} | 6 +-- ...rKeyboardHandler.cs => KeyboardHandler.cs} | 6 +-- .../Handlers/RequestHandler.cs | 50 +++++++++++++++++++ ...dlerFactory.cs => SchemeHandlerFactory.cs} | 11 ++-- .../Handlers/SebSchemeHandler.cs | 47 ----------------- .../SafeExamBrowser.Browser.csproj | 42 ++++++++-------- SafeExamBrowser.Browser/packages.config | 8 +-- SafeExamBrowser.Client.UnitTests/app.config | 4 ++ .../ConfigurationRepository.cs | 2 +- SafeExamBrowser.Contracts/I18n/TextKey.cs | 2 + .../Communication/BaseProxy.cs | 6 +-- SafeExamBrowser.Core/I18n/Text.xml | 6 +++ 15 files changed, 131 insertions(+), 108 deletions(-) rename SafeExamBrowser.Browser/Handlers/{BrowserContextMenuHandler.cs => ContextMenuHandler.cs} (89%) rename SafeExamBrowser.Browser/Handlers/{BrowserKeyboardHandler.cs => KeyboardHandler.cs} (86%) create mode 100644 SafeExamBrowser.Browser/Handlers/RequestHandler.cs rename SafeExamBrowser.Browser/Handlers/{SebSchemeHandlerFactory.cs => SchemeHandlerFactory.cs} (62%) delete mode 100644 SafeExamBrowser.Browser/Handlers/SebSchemeHandler.cs diff --git a/SafeExamBrowser.Browser/BrowserApplicationController.cs b/SafeExamBrowser.Browser/BrowserApplicationController.cs index 8d82f504..20901d10 100644 --- a/SafeExamBrowser.Browser/BrowserApplicationController.cs +++ b/SafeExamBrowser.Browser/BrowserApplicationController.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using CefSharp; using SafeExamBrowser.Browser.Handlers; @@ -76,13 +77,13 @@ namespace SafeExamBrowser.Browser button.RegisterInstance(instance); instances.Add(instance); + instance.ConfigurationDetected += Instance_ConfigurationDetected; instance.Terminated += Instance_Terminated; instance.Window.Show(); } private CefSettings InitializeCefSettings() { - var schemeFactory = new SebSchemeHandlerFactory(); var cefSettings = new CefSettings { CachePath = runtimeInfo.BrowserCachePath, @@ -91,25 +92,12 @@ namespace SafeExamBrowser.Browser LogSeverity = LogSeverity.Verbose }; - schemeFactory.ConfigurationDetected += OnConfigurationDetected; - - cefSettings.RegisterScheme(new CefCustomScheme { SchemeName = "seb", SchemeHandlerFactory = schemeFactory }); - cefSettings.RegisterScheme(new CefCustomScheme { SchemeName = "sebs", SchemeHandlerFactory = schemeFactory }); + cefSettings.RegisterScheme(new CefCustomScheme { SchemeName = "seb", SchemeHandlerFactory = new SchemeHandlerFactory() }); + cefSettings.RegisterScheme(new CefCustomScheme { SchemeName = "sebs", SchemeHandlerFactory = new SchemeHandlerFactory() }); return cefSettings; } - private void OnConfigurationDetected(string url) - { - // TODO: - // 1. Ask whether reconfiguration should be attempted - // 2. Contact runtime and ask whether configuration valid and reconfiguration allowed - // - If yes, do nothing and wait for shutdown command - // - If no, show message box and NAVIGATE TO PREVIOUS PAGE -> but how? - - uiFactory.Show("Detected re-configuration request for " + url, "Info"); - } - private void Button_OnClick(Guid? instanceId = null) { if (instanceId.HasValue) @@ -122,6 +110,19 @@ namespace SafeExamBrowser.Browser } } + private void Instance_ConfigurationDetected(string url, CancelEventArgs args) + { + // TODO: + // 1. Ask whether reconfiguration should be attempted + // 2. Contact runtime and ask whether configuration valid and reconfiguration allowed + // - If yes, do nothing and wait for shutdown command + // - If no, show message box and NAVIGATE TO PREVIOUS PAGE -> but how? + + var result = uiFactory.Show(TextKey.MessageBox_ReconfigureQuestion, TextKey.MessageBox_ReconfigureQuestionTitle, MessageBoxAction.YesNo, MessageBoxIcon.Question); + + args.Cancel = result == MessageBoxResult.No; + } + private void Instance_Terminated(Guid id) { instances.Remove(instances.FirstOrDefault(i => i.Id == id)); diff --git a/SafeExamBrowser.Browser/BrowserApplicationInstance.cs b/SafeExamBrowser.Browser/BrowserApplicationInstance.cs index 54ba653f..a7f1a275 100644 --- a/SafeExamBrowser.Browser/BrowserApplicationInstance.cs +++ b/SafeExamBrowser.Browser/BrowserApplicationInstance.cs @@ -7,6 +7,7 @@ */ using System; +using SafeExamBrowser.Browser.Handlers; using SafeExamBrowser.Contracts.Configuration; using SafeExamBrowser.Contracts.Configuration.Settings; using SafeExamBrowser.Contracts.I18n; @@ -14,7 +15,7 @@ using SafeExamBrowser.Contracts.UserInterface; namespace SafeExamBrowser.Browser { - public class BrowserApplicationInstance : IApplicationInstance + internal class BrowserApplicationInstance : IApplicationInstance { private IBrowserControl control; private IBrowserWindow window; @@ -23,6 +24,7 @@ namespace SafeExamBrowser.Browser public string Name { get; private set; } public IWindow Window { get { return window; } } + internal event ConfigurationDetectedEventHandler ConfigurationDetected; public event TerminatedEventHandler Terminated; public event NameChangedEventHandler NameChanged; @@ -30,8 +32,10 @@ namespace SafeExamBrowser.Browser { Id = Guid.NewGuid(); + // TODO: Move to initialize method! control = new BrowserControl(settings, text); control.AddressChanged += Control_AddressChanged; + (control as BrowserControl).ConfigurationDetected += (url, args) => ConfigurationDetected?.Invoke(url, args); control.LoadingStateChanged += Control_LoadingStateChanged; control.TitleChanged += Control_TitleChanged; diff --git a/SafeExamBrowser.Browser/BrowserControl.cs b/SafeExamBrowser.Browser/BrowserControl.cs index 7a98b313..bc8233c6 100644 --- a/SafeExamBrowser.Browser/BrowserControl.cs +++ b/SafeExamBrowser.Browser/BrowserControl.cs @@ -24,6 +24,8 @@ namespace SafeExamBrowser.Browser private LoadingStateChangedEventHandler loadingStateChanged; private TitleChangedEventHandler titleChanged; + internal event ConfigurationDetectedEventHandler ConfigurationDetected; + event AddressChangedEventHandler IBrowserControl.AddressChanged { add { addressChanged += value; } @@ -75,12 +77,16 @@ namespace SafeExamBrowser.Browser private void Initialize() { + var requestHandler = new RequestHandler(); + AddressChanged += (o, args) => addressChanged?.Invoke(args.Address); LoadingStateChanged += (o, args) => loadingStateChanged?.Invoke(args.IsLoading); TitleChanged += (o, args) => titleChanged?.Invoke(args.Title); + requestHandler.ConfigurationDetected += (url, args) => ConfigurationDetected?.Invoke(url, args); - MenuHandler = new BrowserContextMenuHandler(settings, text); - KeyboardHandler = new BrowserKeyboardHandler(settings); + KeyboardHandler = new KeyboardHandler(settings); + MenuHandler = new ContextMenuHandler(settings, text); + RequestHandler = requestHandler; } } } diff --git a/SafeExamBrowser.Browser/Handlers/BrowserContextMenuHandler.cs b/SafeExamBrowser.Browser/Handlers/ContextMenuHandler.cs similarity index 89% rename from SafeExamBrowser.Browser/Handlers/BrowserContextMenuHandler.cs rename to SafeExamBrowser.Browser/Handlers/ContextMenuHandler.cs index 5cd19943..300e6071 100644 --- a/SafeExamBrowser.Browser/Handlers/BrowserContextMenuHandler.cs +++ b/SafeExamBrowser.Browser/Handlers/ContextMenuHandler.cs @@ -13,16 +13,16 @@ using BrowserSettings = SafeExamBrowser.Contracts.Configuration.Settings.Browser namespace SafeExamBrowser.Browser.Handlers { /// - /// See https://cefsharp.github.io/api/57.0.0/html/T_CefSharp_IContextMenuHandler.htm. + /// See https://cefsharp.github.io/api/63.0.0/html/T_CefSharp_IContextMenuHandler.htm. /// - internal class BrowserContextMenuHandler : IContextMenuHandler + internal class ContextMenuHandler : IContextMenuHandler { private const int DEV_CONSOLE_COMMAND = (int) CefMenuCommand.UserFirst + 1; private BrowserSettings settings; private IText text; - public BrowserContextMenuHandler(BrowserSettings settings, IText text) + public ContextMenuHandler(BrowserSettings settings, IText text) { this.settings = settings; this.text = text; diff --git a/SafeExamBrowser.Browser/Handlers/BrowserKeyboardHandler.cs b/SafeExamBrowser.Browser/Handlers/KeyboardHandler.cs similarity index 86% rename from SafeExamBrowser.Browser/Handlers/BrowserKeyboardHandler.cs rename to SafeExamBrowser.Browser/Handlers/KeyboardHandler.cs index 54a0ae84..43041228 100644 --- a/SafeExamBrowser.Browser/Handlers/BrowserKeyboardHandler.cs +++ b/SafeExamBrowser.Browser/Handlers/KeyboardHandler.cs @@ -13,13 +13,13 @@ using BrowserSettings = SafeExamBrowser.Contracts.Configuration.Settings.Browser namespace SafeExamBrowser.Browser.Handlers { /// - /// See https://cefsharp.github.io/api/57.0.0/html/T_CefSharp_IKeyboardHandler.htm. + /// See https://cefsharp.github.io/api/63.0.0/html/T_CefSharp_IKeyboardHandler.htm. /// - internal class BrowserKeyboardHandler : IKeyboardHandler + internal class KeyboardHandler : IKeyboardHandler { private BrowserSettings settings; - public BrowserKeyboardHandler(BrowserSettings settings) + public KeyboardHandler(BrowserSettings settings) { this.settings = settings; } diff --git a/SafeExamBrowser.Browser/Handlers/RequestHandler.cs b/SafeExamBrowser.Browser/Handlers/RequestHandler.cs new file mode 100644 index 00000000..f8abbde7 --- /dev/null +++ b/SafeExamBrowser.Browser/Handlers/RequestHandler.cs @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2018 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.ComponentModel; +using System.Threading.Tasks; +using CefSharp; +using CefSharp.Handler; + +namespace SafeExamBrowser.Browser.Handlers +{ + internal delegate void ConfigurationDetectedEventHandler(string url, CancelEventArgs args); + + /// + /// See https://cefsharp.github.io/api/63.0.0/html/T_CefSharp_Handler_DefaultRequestHandler.htm. + /// + internal class RequestHandler : DefaultRequestHandler + { + internal event ConfigurationDetectedEventHandler ConfigurationDetected; + + public override CefReturnValue OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback) + { + Task.Run(() => + { + var allow = true; + + // TODO: Check if the requested resource is a configuration file, even if the URL does not indicate so! + if (request.Url.StartsWith("seb") || request.Url.StartsWith("sebs") || request.Url.EndsWith(".seb")) + { + var args = new CancelEventArgs(); + + ConfigurationDetected?.Invoke(request.Url, args); + + allow = !args.Cancel; + } + + using (callback) + { + callback.Continue(allow); + } + }); + + return CefReturnValue.ContinueAsync; + } + } +} diff --git a/SafeExamBrowser.Browser/Handlers/SebSchemeHandlerFactory.cs b/SafeExamBrowser.Browser/Handlers/SchemeHandlerFactory.cs similarity index 62% rename from SafeExamBrowser.Browser/Handlers/SebSchemeHandlerFactory.cs rename to SafeExamBrowser.Browser/Handlers/SchemeHandlerFactory.cs index 69d952ce..9d13bbb6 100644 --- a/SafeExamBrowser.Browser/Handlers/SebSchemeHandlerFactory.cs +++ b/SafeExamBrowser.Browser/Handlers/SchemeHandlerFactory.cs @@ -11,17 +11,14 @@ using CefSharp; namespace SafeExamBrowser.Browser.Handlers { /// - /// See https://cefsharp.github.io/api/57.0.0/html/T_CefSharp_ISchemeHandlerFactory.htm. + /// See https://cefsharp.github.io/api/63.0.0/html/T_CefSharp_ISchemeHandlerFactory.htm. /// - internal class SebSchemeHandlerFactory : ISchemeHandlerFactory + internal class SchemeHandlerFactory : ISchemeHandlerFactory { - internal event ConfigurationDetectedEventHandler ConfigurationDetected; - public IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request) { - var handler = new SebSchemeHandler(); - - handler.ConfigurationDetected += (url) => ConfigurationDetected?.Invoke(url); + var page = ""; + var handler = ResourceHandler.FromString(page); return handler; } diff --git a/SafeExamBrowser.Browser/Handlers/SebSchemeHandler.cs b/SafeExamBrowser.Browser/Handlers/SebSchemeHandler.cs deleted file mode 100644 index 40627d0d..00000000 --- a/SafeExamBrowser.Browser/Handlers/SebSchemeHandler.cs +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2018 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.Net; -using System.Text; -using System.Threading.Tasks; -using CefSharp; - -namespace SafeExamBrowser.Browser.Handlers -{ - internal delegate void ConfigurationDetectedEventHandler(string url); - - /// - /// See https://cefsharp.github.io/api/57.0.0/html/T_CefSharp_ResourceHandler.htm. - /// - internal class SebSchemeHandler : ResourceHandler - { - internal event ConfigurationDetectedEventHandler ConfigurationDetected; - - public override bool ProcessRequestAsync(IRequest request, ICallback callback) - { - Task.Run(() => - { - using (callback) - { - var page = ""; - var stream = GetMemoryStream(page, Encoding.UTF8); - - ResponseLength = stream.Length; - MimeType = "text/html"; - StatusCode = (int) HttpStatusCode.OK; - Stream = stream; - - callback.Continue(); - ConfigurationDetected?.Invoke(request.Url); - } - }); - - return true; - } - } -} diff --git a/SafeExamBrowser.Browser/SafeExamBrowser.Browser.csproj b/SafeExamBrowser.Browser/SafeExamBrowser.Browser.csproj index 0d9f70cf..6296a2b8 100644 --- a/SafeExamBrowser.Browser/SafeExamBrowser.Browser.csproj +++ b/SafeExamBrowser.Browser/SafeExamBrowser.Browser.csproj @@ -1,7 +1,9 @@  - - + + + + Debug @@ -60,14 +62,14 @@ - + Component - - - + + + @@ -82,23 +84,21 @@ - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + \ No newline at end of file diff --git a/SafeExamBrowser.Browser/packages.config b/SafeExamBrowser.Browser/packages.config index 92d8bc85..d972e00c 100644 --- a/SafeExamBrowser.Browser/packages.config +++ b/SafeExamBrowser.Browser/packages.config @@ -1,7 +1,7 @@  - - - - + + + + \ No newline at end of file diff --git a/SafeExamBrowser.Client.UnitTests/app.config b/SafeExamBrowser.Client.UnitTests/app.config index 7d8c9227..7b7e0134 100644 --- a/SafeExamBrowser.Client.UnitTests/app.config +++ b/SafeExamBrowser.Client.UnitTests/app.config @@ -6,6 +6,10 @@ + + + + \ No newline at end of file diff --git a/SafeExamBrowser.Configuration/ConfigurationRepository.cs b/SafeExamBrowser.Configuration/ConfigurationRepository.cs index d3cdca07..f309a6d7 100644 --- a/SafeExamBrowser.Configuration/ConfigurationRepository.cs +++ b/SafeExamBrowser.Configuration/ConfigurationRepository.cs @@ -72,7 +72,7 @@ namespace SafeExamBrowser.Configuration ServicePolicy = ServicePolicy.Optional }; - settings.Browser.StartUrl = "https://www.duckduckgo.com"; + settings.Browser.StartUrl = "https://www.safeexambrowser.org/testing"; settings.Browser.AllowAddressBar = true; settings.Browser.AllowBackwardNavigation = true; settings.Browser.AllowDeveloperConsole = true; diff --git a/SafeExamBrowser.Contracts/I18n/TextKey.cs b/SafeExamBrowser.Contracts/I18n/TextKey.cs index 3dc22fa9..94b225bf 100644 --- a/SafeExamBrowser.Contracts/I18n/TextKey.cs +++ b/SafeExamBrowser.Contracts/I18n/TextKey.cs @@ -24,6 +24,8 @@ namespace SafeExamBrowser.Contracts.I18n MessageBox_QuitTitle, MessageBox_QuitError, MessageBox_QuitErrorTitle, + MessageBox_ReconfigureQuestion, + MessageBox_ReconfigureQuestionTitle, MessageBox_SessionStartError, MessageBox_SessionStartErrorTitle, MessageBox_SessionStopError, diff --git a/SafeExamBrowser.Core/Communication/BaseProxy.cs b/SafeExamBrowser.Core/Communication/BaseProxy.cs index 8484b6d3..0c85b28e 100644 --- a/SafeExamBrowser.Core/Communication/BaseProxy.cs +++ b/SafeExamBrowser.Core/Communication/BaseProxy.cs @@ -186,18 +186,18 @@ namespace SafeExamBrowser.Core.Communication if (IsAcknowledged(response)) { - Logger.Info("Pinged proxy, connection is alive."); + Logger.Info("Pinged host, connection is alive."); } else { - Logger.Error($"Proxy did not acknowledge ping message! Received: {ToString(response)}."); + Logger.Error($"Host did not acknowledge ping message! Received: {ToString(response)}."); timer.Stop(); ConnectionLost?.Invoke(); } } catch (Exception e) { - Logger.Error("Failed to ping proxy!", e); + Logger.Error("Failed to ping host!", e); timer.Stop(); ConnectionLost?.Invoke(); } diff --git a/SafeExamBrowser.Core/I18n/Text.xml b/SafeExamBrowser.Core/I18n/Text.xml index 3c42d27b..492d40a0 100644 --- a/SafeExamBrowser.Core/I18n/Text.xml +++ b/SafeExamBrowser.Core/I18n/Text.xml @@ -30,6 +30,12 @@ Quit Error + + Would you like to reconfigure the application? + + + Configuration Detected + The application failed to start a new session. Please consult the application log for more information...