diff --git a/SafeExamBrowser.Client/Behaviour/ClientController.cs b/SafeExamBrowser.Client/Behaviour/ClientController.cs index f8cb2804..81f35621 100644 --- a/SafeExamBrowser.Client/Behaviour/ClientController.cs +++ b/SafeExamBrowser.Client/Behaviour/ClientController.cs @@ -86,6 +86,7 @@ namespace SafeExamBrowser.Client.Behaviour if (success) { RegisterEvents(); + // TODO: Handle communication exception! runtime.InformClientReady(); splashScreen.Hide(); @@ -174,14 +175,9 @@ namespace SafeExamBrowser.Client.Behaviour private void Taskbar_QuitButtonClicked() { - // TODO: MessageBox asking whether user really wants to quit -> args.Cancel - - var acknowledged = runtime.RequestShutdown(); - - if (!acknowledged) - { - logger.Warn("The runtime did not acknowledge the shutdown request!"); - } + // TODO: MessageBox asking whether user really wants to quit -> only then request shutdown! + // TODO: Handle communication exception! + runtime.RequestShutdown(); } private void WindowMonitor_WindowChanged(IntPtr window) diff --git a/SafeExamBrowser.Contracts/Communication/IClientProxy.cs b/SafeExamBrowser.Contracts/Communication/IClientProxy.cs index 13698163..7fdca40d 100644 --- a/SafeExamBrowser.Contracts/Communication/IClientProxy.cs +++ b/SafeExamBrowser.Contracts/Communication/IClientProxy.cs @@ -15,11 +15,13 @@ namespace SafeExamBrowser.Contracts.Communication /// /// Instructs the client to initiate its shutdown procedure. /// + /// If the communication failed. void InitiateShutdown(); /// /// Instructs the client to submit its authentication data. /// + /// If the communication failed. AuthenticationResponse RequestAuthentication(); } } diff --git a/SafeExamBrowser.Contracts/Communication/ICommunicationProxy.cs b/SafeExamBrowser.Contracts/Communication/ICommunicationProxy.cs index 5e7ea1bc..d69e99bb 100644 --- a/SafeExamBrowser.Contracts/Communication/ICommunicationProxy.cs +++ b/SafeExamBrowser.Contracts/Communication/ICommunicationProxy.cs @@ -13,13 +13,15 @@ namespace SafeExamBrowser.Contracts.Communication public interface ICommunicationProxy { /// - /// Tries to establish a connection. Returns true if successful, otherwise false. + /// Tries to establish a connection. Returns true if the connection has been accepted, otherwise false. /// + /// If the communication failed. bool Connect(Guid? token = null); /// - /// Terminates an open connection. Returns true if successful, otherwise false. + /// Terminates an open connection. Returns true if the disconnection has been acknowledged, otherwise false. /// + /// If the communication failed. bool Disconnect(); } } diff --git a/SafeExamBrowser.Contracts/Communication/IRuntimeProxy.cs b/SafeExamBrowser.Contracts/Communication/IRuntimeProxy.cs index 2f674385..0ab70170 100644 --- a/SafeExamBrowser.Contracts/Communication/IRuntimeProxy.cs +++ b/SafeExamBrowser.Contracts/Communication/IRuntimeProxy.cs @@ -15,18 +15,19 @@ namespace SafeExamBrowser.Contracts.Communication /// /// Retrieves the application configuration from the runtime. /// - /// If the configuration could not be retrieved. + /// If the communication failed. ClientConfiguration GetConfiguration(); /// /// Informs the runtime that the client is ready. /// - /// If the runtime did not acknowledge the status update. + /// If the communication failed. void InformClientReady(); /// - /// Requests the runtime to shut down the application. Returns true if the request was acknowledged, otherwise false. + /// Requests the runtime to shut down the application. /// - bool RequestShutdown(); + /// If the communication failed. + void RequestShutdown(); } } diff --git a/SafeExamBrowser.Contracts/Communication/IServiceProxy.cs b/SafeExamBrowser.Contracts/Communication/IServiceProxy.cs index f7dd5807..06ef26e7 100644 --- a/SafeExamBrowser.Contracts/Communication/IServiceProxy.cs +++ b/SafeExamBrowser.Contracts/Communication/IServiceProxy.cs @@ -22,11 +22,13 @@ namespace SafeExamBrowser.Contracts.Communication /// /// Instructs the service to start a new session according to the given parameters. /// + /// If the communication failed. void StartSession(Guid sessionId, Settings settings); /// /// Instructs the service to stop the specified session. /// + /// If the communication failed. void StopSession(Guid sessionId); } } diff --git a/SafeExamBrowser.Contracts/Communication/Responses/SimpleResponsePurport.cs b/SafeExamBrowser.Contracts/Communication/Responses/SimpleResponsePurport.cs index 801e044f..ef869fe8 100644 --- a/SafeExamBrowser.Contracts/Communication/Responses/SimpleResponsePurport.cs +++ b/SafeExamBrowser.Contracts/Communication/Responses/SimpleResponsePurport.cs @@ -18,6 +18,11 @@ namespace SafeExamBrowser.Contracts.Communication.Responses /// Acknowledged = 1, + /// + /// Signals an interlocutor that it is not authorized to communicate. + /// + Unauthorized, + /// /// Signals an interlocutor that a message has not been understood. /// diff --git a/SafeExamBrowser.Core/Communication/BaseHost.cs b/SafeExamBrowser.Core/Communication/BaseHost.cs index bdd64f51..3993bfa6 100644 --- a/SafeExamBrowser.Core/Communication/BaseHost.cs +++ b/SafeExamBrowser.Core/Communication/BaseHost.cs @@ -97,7 +97,7 @@ namespace SafeExamBrowser.Core.Communication { lock (@lock) { - var response = default(Response); + var response = new SimpleResponse(SimpleResponsePurport.Unauthorized) as Response; if (IsAuthorized(message?.CommunicationToken)) { diff --git a/SafeExamBrowser.Core/Communication/RuntimeProxy.cs b/SafeExamBrowser.Core/Communication/RuntimeProxy.cs index 16b445b7..39d4fb0f 100644 --- a/SafeExamBrowser.Core/Communication/RuntimeProxy.cs +++ b/SafeExamBrowser.Core/Communication/RuntimeProxy.cs @@ -37,21 +37,23 @@ namespace SafeExamBrowser.Core.Communication { var response = Send(SimpleMessagePurport.ClientIsReady); - if (!IsAcknowledgeResponse(response)) + if (!IsAcknowledged(response)) { throw new CommunicationException($"Runtime did not acknowledge that client is ready! Response: {ToString(response)}."); } } - public bool RequestShutdown() + public void RequestShutdown() { var response = Send(SimpleMessagePurport.RequestShutdown); - var acknowledged = IsAcknowledgeResponse(response); - return acknowledged; + if (!IsAcknowledged(response)) + { + throw new CommunicationException($"Runtime did not acknowledge shutdown request! Response: {ToString(response)}."); + } } - private bool IsAcknowledgeResponse(Response response) + private bool IsAcknowledged(Response response) { return response is SimpleResponse simpleResponse && simpleResponse.Purport == SimpleResponsePurport.Acknowledged; } diff --git a/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/SessionSequenceOperationTests.cs b/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/SessionSequenceOperationTests.cs new file mode 100644 index 00000000..d92ad056 --- /dev/null +++ b/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/SessionSequenceOperationTests.cs @@ -0,0 +1,22 @@ +/* + * 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 Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations +{ + [TestClass] + public class SessionSequenceOperationTests + { + [TestMethod] + public void TODO() + { + Assert.Fail(); + } + } +} diff --git a/SafeExamBrowser.Runtime.UnitTests/SafeExamBrowser.Runtime.UnitTests.csproj b/SafeExamBrowser.Runtime.UnitTests/SafeExamBrowser.Runtime.UnitTests.csproj index 0e881f6e..aa293215 100644 --- a/SafeExamBrowser.Runtime.UnitTests/SafeExamBrowser.Runtime.UnitTests.csproj +++ b/SafeExamBrowser.Runtime.UnitTests/SafeExamBrowser.Runtime.UnitTests.csproj @@ -83,6 +83,7 @@ + diff --git a/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs b/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs index 4c8fe79c..7d5d4923 100644 --- a/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs +++ b/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs @@ -58,9 +58,9 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations logger.Info($"Loading configuration from '{uri.AbsolutePath}'..."); settings = repository.LoadSettings(uri); - if (settings.ConfigurationMode == ConfigurationMode.ConfigureClient && UserWantsToAbortStartup()) + if (settings.ConfigurationMode == ConfigurationMode.ConfigureClient) { - Abort = true; + Abort = IsConfigurationSufficient(); logger.Info($"The user chose to {(Abort ? "abort" : "continue")} the application startup after successful client configuration."); } } @@ -75,6 +75,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations { // TODO: How will the new settings be retrieved? Uri passed to the repository? If yes, how does the Uri get here?! // -> IDEA: Use configuration repository as container? + // -> IDEA: Introduce IRepeatParams or alike? } public void Revert() @@ -115,7 +116,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations return isValidUri; } - private bool UserWantsToAbortStartup() + private bool IsConfigurationSufficient() { var message = text.Get(TextKey.MessageBox_ConfigureClientSuccess); var title = text.Get(TextKey.MessageBox_ConfigureClientSuccessTitle); diff --git a/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs b/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs index abd0768d..328d4200 100644 --- a/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs +++ b/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs @@ -7,7 +7,6 @@ */ using System; -using System.Threading.Tasks; using SafeExamBrowser.Contracts.Communication; using SafeExamBrowser.Contracts.Communication.Messages; using SafeExamBrowser.Contracts.Communication.Responses; @@ -39,7 +38,7 @@ namespace SafeExamBrowser.Runtime.Communication protected override void OnDisconnect() { - Task.Run(() => ClientDisconnected?.Invoke()); + ClientDisconnected?.Invoke(); } protected override Response OnReceive(Message message)