diff --git a/SafeExamBrowser.Client/Behaviour/ClientController.cs b/SafeExamBrowser.Client/Behaviour/ClientController.cs
index f5935e94..c17bcbe6 100644
--- a/SafeExamBrowser.Client/Behaviour/ClientController.cs
+++ b/SafeExamBrowser.Client/Behaviour/ClientController.cs
@@ -101,21 +101,20 @@ namespace SafeExamBrowser.Client.Behaviour
{
RegisterEvents();
- try
+ var communication = runtime.InformClientReady();
+
+ if (communication.Success)
{
- runtime.InformClientReady();
+ splashScreen.Hide();
+
+ logger.Info("--- Application successfully initialized ---");
+ logger.Log(string.Empty);
}
- catch (Exception e)
+ else
{
- logger.Error("Failed to inform runtime that client is ready!", e);
-
- return false;
+ success = false;
+ logger.Error("Failed to inform runtime that client is ready!");
}
-
- splashScreen.Hide();
-
- logger.Info("--- Application successfully initialized ---");
- logger.Log(string.Empty);
}
else
{
@@ -227,14 +226,15 @@ namespace SafeExamBrowser.Client.Behaviour
{
if (success)
{
- try
+ var communication = runtime.RequestReconfiguration(filePath);
+
+ if (communication.Success)
{
- runtime.RequestReconfiguration(filePath);
logger.Info($"Sent reconfiguration request for '{filePath}' to the runtime.");
}
- catch (Exception e)
+ else
{
- logger.Error($"Failed to communicate reconfiguration request for '{filePath}'!", e);
+ logger.Error($"Failed to communicate reconfiguration request for '{filePath}'!");
messageBox.Show(TextKey.MessageBox_ReconfigurationError, TextKey.MessageBox_ReconfigurationErrorTitle, icon: MessageBoxIcon.Error);
}
}
@@ -287,13 +287,11 @@ namespace SafeExamBrowser.Client.Behaviour
if (result == MessageBoxResult.Yes)
{
- try
+ var communication = runtime.RequestShutdown();
+
+ if (!communication.Success)
{
- runtime.RequestShutdown();
- }
- catch (Exception e)
- {
- logger.Error("Failed to communicate shutdown request to the runtime!", e);
+ logger.Error("Failed to communicate shutdown request to the runtime!");
messageBox.Show(TextKey.MessageBox_QuitError, TextKey.MessageBox_QuitErrorTitle, icon: MessageBoxIcon.Error);
}
}
diff --git a/SafeExamBrowser.Client/Behaviour/Operations/ConfigurationOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/ConfigurationOperation.cs
index 520cca18..f308deb7 100644
--- a/SafeExamBrowser.Client/Behaviour/Operations/ConfigurationOperation.cs
+++ b/SafeExamBrowser.Client/Behaviour/Operations/ConfigurationOperation.cs
@@ -38,7 +38,8 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
try
{
- var config = runtime.GetConfiguration();
+ var communication = runtime.GetConfiguration();
+ var config = communication.Value.Configuration;
configuration.AppConfig = config.AppConfig;
configuration.SessionId = config.SessionId;
diff --git a/SafeExamBrowser.Client/Behaviour/Operations/RuntimeConnectionOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/RuntimeConnectionOperation.cs
index d0a7a3c9..d4f4daee 100644
--- a/SafeExamBrowser.Client/Behaviour/Operations/RuntimeConnectionOperation.cs
+++ b/SafeExamBrowser.Client/Behaviour/Operations/RuntimeConnectionOperation.cs
@@ -36,25 +36,18 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
logger.Info("Initializing runtime connection...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeRuntimeConnection);
- try
- {
- connected = runtime.Connect(token);
- }
- catch (Exception e)
- {
- logger.Error("An unexpected error occurred while trying to connect to the runtime!", e);
- }
+ connected = runtime.Connect(token);
- if (!connected)
+ if (connected)
+ {
+ logger.Info("Successfully connected to the runtime.");
+ }
+ else
{
logger.Error("Failed to connect to the runtime. Aborting startup...");
-
- return OperationResult.Failed;
}
- logger.Info("Successfully connected to the runtime.");
-
- return OperationResult.Success;
+ return connected ? OperationResult.Success : OperationResult.Failed;
}
public OperationResult Repeat()
@@ -69,13 +62,15 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
if (connected)
{
- try
+ var success = runtime.Disconnect();
+
+ if (success)
{
- runtime.Disconnect();
+ logger.Info("Successfully disconnected from the runtime.");
}
- catch (Exception e)
+ else
{
- logger.Error("Failed to disconnect from runtime host!", e);
+ logger.Error("Failed to disconnect from the runtime!");
}
}
}
diff --git a/SafeExamBrowser.Client/CompositionRoot.cs b/SafeExamBrowser.Client/CompositionRoot.cs
index 7a6c495f..f6905150 100644
--- a/SafeExamBrowser.Client/CompositionRoot.cs
+++ b/SafeExamBrowser.Client/CompositionRoot.cs
@@ -89,6 +89,7 @@ namespace SafeExamBrowser.Client
operations.Enqueue(new I18nOperation(logger, text));
operations.Enqueue(new RuntimeConnectionOperation(logger, runtimeProxy, startupToken));
operations.Enqueue(new ConfigurationOperation(configuration, logger, runtimeProxy));
+ operations.Enqueue(new DelegateOperation(UpdateAppConfig));
operations.Enqueue(new DelayedInitializationOperation(BuildCommunicationHostOperation));
// TODO
//operations.Enqueue(new DelayedInitializationOperation(BuildKeyboardInterceptorOperation));
@@ -202,9 +203,13 @@ namespace SafeExamBrowser.Client
return operation;
}
- private void UpdateClientControllerDependencies()
+ private void UpdateAppConfig()
{
ClientController.AppConfig = configuration.AppConfig;
+ }
+
+ private void UpdateClientControllerDependencies()
+ {
ClientController.Browser = browserController;
ClientController.ClientHost = clientHost;
ClientController.SessionId = configuration.SessionId;
diff --git a/SafeExamBrowser.Contracts/Communication/ICommunicationProxy.cs b/SafeExamBrowser.Contracts/Communication/ICommunicationProxy.cs
index 510d2ded..665adb50 100644
--- a/SafeExamBrowser.Contracts/Communication/ICommunicationProxy.cs
+++ b/SafeExamBrowser.Contracts/Communication/ICommunicationProxy.cs
@@ -23,17 +23,14 @@ namespace SafeExamBrowser.Contracts.Communication
event CommunicationEventHandler ConnectionLost;
///
- /// Tries to establish a connection. Returns true if the connection has been accepted, otherwise false. If a
+ /// Tries to establish a connection. Returns true if the connection has been successful, otherwise false. If a
/// connection was successfully established and the auto-ping flag is set, the connection status will be periodically checked.
///
- /// If the communication failed.
bool Connect(Guid? token = null, bool autoPing = true);
///
- /// Terminates an open connection. Returns true if the disconnection has been acknowledged, otherwise false.
+ /// Terminates an open connection. Returns true if the disconnection has been successful, otherwise false.
///
- /// If no connection has been established.
- /// If the communication failed.
bool Disconnect();
}
}
diff --git a/SafeExamBrowser.Contracts/Communication/Proxies/CommunicationResult.cs b/SafeExamBrowser.Contracts/Communication/Proxies/CommunicationResult.cs
new file mode 100644
index 00000000..e2369b48
--- /dev/null
+++ b/SafeExamBrowser.Contracts/Communication/Proxies/CommunicationResult.cs
@@ -0,0 +1,43 @@
+/*
+ * 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/.
+ */
+
+namespace SafeExamBrowser.Contracts.Communication.Proxies
+{
+ ///
+ /// Defines the result of a communication between an and its .
+ ///
+ public class CommunicationResult
+ {
+ ///
+ /// Defines whether the communication was successful or not.
+ ///
+ public bool Success { get; protected set; }
+
+ public CommunicationResult(bool success)
+ {
+ Success = success;
+ }
+ }
+
+ ///
+ /// Defines the result of a communication between an and its .
+ ///
+ /// The type of the expected response value.
+ public class CommunicationResult : CommunicationResult
+ {
+ ///
+ /// The response value. Can be null or default(T) in case the communication has failed!
+ ///
+ public T Value { get; protected set; }
+
+ public CommunicationResult(bool success, T value) : base(success)
+ {
+ Value = value;
+ }
+ }
+}
diff --git a/SafeExamBrowser.Contracts/Communication/Proxies/IClientProxy.cs b/SafeExamBrowser.Contracts/Communication/Proxies/IClientProxy.cs
index 13e0ed36..9f3c049e 100644
--- a/SafeExamBrowser.Contracts/Communication/Proxies/IClientProxy.cs
+++ b/SafeExamBrowser.Contracts/Communication/Proxies/IClientProxy.cs
@@ -19,24 +19,21 @@ namespace SafeExamBrowser.Contracts.Communication.Proxies
///
/// Informs the client that the reconfiguration request for the specified file was denied.
///
- void InformReconfigurationDenied(string filePath);
+ CommunicationResult InformReconfigurationDenied(string filePath);
///
/// Instructs the client to initiate its shutdown procedure.
///
- /// If the communication failed.
- void InitiateShutdown();
+ CommunicationResult InitiateShutdown();
///
/// Instructs the client to submit its authentication data.
///
- /// If the communication failed.
- AuthenticationResponse RequestAuthentication();
+ CommunicationResult RequestAuthentication();
///
/// Requests the client to render a password dialog and subsequently return the interaction result as separate message.
///
- /// If the communication failed.
- void RequestPassword(PasswordRequestPurpose purpose, Guid requestId);
+ CommunicationResult RequestPassword(PasswordRequestPurpose purpose, Guid requestId);
}
}
diff --git a/SafeExamBrowser.Contracts/Communication/Proxies/IRuntimeProxy.cs b/SafeExamBrowser.Contracts/Communication/Proxies/IRuntimeProxy.cs
index 5a261088..5140e5c4 100644
--- a/SafeExamBrowser.Contracts/Communication/Proxies/IRuntimeProxy.cs
+++ b/SafeExamBrowser.Contracts/Communication/Proxies/IRuntimeProxy.cs
@@ -7,7 +7,7 @@
*/
using System;
-using SafeExamBrowser.Contracts.Configuration;
+using SafeExamBrowser.Contracts.Communication.Data;
namespace SafeExamBrowser.Contracts.Communication.Proxies
{
@@ -19,32 +19,27 @@ namespace SafeExamBrowser.Contracts.Communication.Proxies
///
/// Retrieves the application configuration from the runtime.
///
- /// If the communication failed.
- ClientConfiguration GetConfiguration();
+ CommunicationResult GetConfiguration();
///
/// Informs the runtime that the client is ready.
///
- /// If the communication failed.
- void InformClientReady();
+ CommunicationResult InformClientReady();
///
/// Requests the runtime to shut down the application.
///
- /// If the communication failed.
- void RequestShutdown();
+ CommunicationResult RequestShutdown();
///
/// Requests the runtime to reconfigure the application with the specified configuration.
///
- /// If the communication failed.
- void RequestReconfiguration(string filePath);
+ CommunicationResult RequestReconfiguration(string filePath);
///
/// Submits the result of a password input previously requested by the runtime. If the procedure was aborted by the user,
/// the password parameter will be null!
///
- /// /// If the communication failed.
- void SubmitPassword(Guid requestId, bool success, string password = null);
+ CommunicationResult SubmitPassword(Guid requestId, bool success, string password = null);
}
}
diff --git a/SafeExamBrowser.Contracts/Communication/Proxies/IServiceProxy.cs b/SafeExamBrowser.Contracts/Communication/Proxies/IServiceProxy.cs
index 82e96968..b8f15b1c 100644
--- a/SafeExamBrowser.Contracts/Communication/Proxies/IServiceProxy.cs
+++ b/SafeExamBrowser.Contracts/Communication/Proxies/IServiceProxy.cs
@@ -25,13 +25,11 @@ namespace SafeExamBrowser.Contracts.Communication.Proxies
///
/// Instructs the service to start a new session according to the given parameters.
///
- /// If the communication failed.
- void StartSession(Guid sessionId, Settings settings);
+ CommunicationResult StartSession(Guid sessionId, Settings settings);
///
/// Instructs the service to stop the specified session.
///
- /// If the communication failed.
- void StopSession(Guid sessionId);
+ CommunicationResult StopSession(Guid sessionId);
}
}
diff --git a/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj b/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj
index 2a9d5031..623bed9f 100644
--- a/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj
+++ b/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj
@@ -75,6 +75,7 @@
+
diff --git a/SafeExamBrowser.Core.UnitTests/Communication/Proxies/BaseProxyTests.cs b/SafeExamBrowser.Core.UnitTests/Communication/Proxies/BaseProxyTests.cs
index 24d9cca9..1efcab54 100644
--- a/SafeExamBrowser.Core.UnitTests/Communication/Proxies/BaseProxyTests.cs
+++ b/SafeExamBrowser.Core.UnitTests/Communication/Proxies/BaseProxyTests.cs
@@ -106,14 +106,14 @@ namespace SafeExamBrowser.Core.UnitTests.Communication.Proxies
}
[TestMethod]
- [ExpectedException(typeof(InvalidOperationException))]
public void MustFailToDisconnectIfNotConnected()
{
- sut.Disconnect();
+ var success = sut.Disconnect();
+
+ Assert.IsFalse(success);
}
[TestMethod]
- [ExpectedException(typeof(CommunicationException))]
public void MustFailToDisconnectIfChannelNotOpen()
{
var proxy = new Mock();
@@ -130,7 +130,10 @@ namespace SafeExamBrowser.Core.UnitTests.Communication.Proxies
var token = Guid.NewGuid();
sut.Connect(token);
- sut.Disconnect();
+
+ var success = sut.Disconnect();
+
+ Assert.IsFalse(success);
}
[TestMethod]
@@ -141,7 +144,7 @@ namespace SafeExamBrowser.Core.UnitTests.Communication.Proxies
}
[TestMethod]
- [ExpectedException(typeof(CommunicationException))]
+ [ExpectedException(typeof(InvalidOperationException))]
public void MustFailToSendIfChannelNotOpen()
{
var proxy = new Mock();
diff --git a/SafeExamBrowser.Core.UnitTests/Communication/Proxies/ClientProxyTests.cs b/SafeExamBrowser.Core.UnitTests/Communication/Proxies/ClientProxyTests.cs
index 7424271b..c95ad41e 100644
--- a/SafeExamBrowser.Core.UnitTests/Communication/Proxies/ClientProxyTests.cs
+++ b/SafeExamBrowser.Core.UnitTests/Communication/Proxies/ClientProxyTests.cs
@@ -10,7 +10,6 @@ using System;
using System.ServiceModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
-using SafeExamBrowser.Contracts.Communication;
using SafeExamBrowser.Contracts.Communication.Data;
using SafeExamBrowser.Contracts.Communication.Proxies;
using SafeExamBrowser.Contracts.Logging;
@@ -52,18 +51,20 @@ namespace SafeExamBrowser.Core.UnitTests.Communication.Proxies
{
proxy.Setup(p => p.Send(It.Is(m => m.Purport == SimpleMessagePurport.Shutdown))).Returns(new SimpleResponse(SimpleResponsePurport.Acknowledged));
- sut.InitiateShutdown();
+ var communication = sut.InitiateShutdown();
proxy.Verify(p => p.Send(It.Is(m => m.Purport == SimpleMessagePurport.Shutdown)), Times.Once);
+ Assert.IsTrue(communication.Success);
}
[TestMethod]
- [ExpectedException(typeof(CommunicationException))]
- public void MustFailIfShutdownCommandNotAcknowledged()
+ public void MustIndicateIfShutdownCommandNotAcknowledged()
{
proxy.Setup(p => p.Send(It.Is(m => m.Purport == SimpleMessagePurport.Shutdown))).Returns(null);
- sut.InitiateShutdown();
+ var communication = sut.InitiateShutdown();
+
+ Assert.IsFalse(communication.Success);
}
[TestMethod]
@@ -71,20 +72,24 @@ namespace SafeExamBrowser.Core.UnitTests.Communication.Proxies
{
proxy.Setup(p => p.Send(It.Is(m => m.Purport == SimpleMessagePurport.Authenticate))).Returns(new AuthenticationResponse());
- var response = sut.RequestAuthentication();
+ var communication = sut.RequestAuthentication();
+ var response = communication.Value;
proxy.Verify(p => p.Send(It.Is(m => m.Purport == SimpleMessagePurport.Authenticate)), Times.Once);
+ Assert.IsTrue(communication.Success);
Assert.IsInstanceOfType(response, typeof(AuthenticationResponse));
}
[TestMethod]
- [ExpectedException(typeof(CommunicationException))]
- public void MustFailIfAuthenticationCommandNotFollowed()
+ public void MustIndicateIfAuthenticationCommandNotAcknowledged()
{
proxy.Setup(p => p.Send(It.Is(m => m.Purport == SimpleMessagePurport.Authenticate))).Returns(null);
- sut.RequestAuthentication();
+ var communication = sut.RequestAuthentication();
+
+ Assert.AreEqual(default(AuthenticationResponse), communication.Value);
+ Assert.IsFalse(communication.Success);
}
}
}
diff --git a/SafeExamBrowser.Core.UnitTests/Communication/Proxies/RuntimeProxyTests.cs b/SafeExamBrowser.Core.UnitTests/Communication/Proxies/RuntimeProxyTests.cs
index 58de0025..f593ce69 100644
--- a/SafeExamBrowser.Core.UnitTests/Communication/Proxies/RuntimeProxyTests.cs
+++ b/SafeExamBrowser.Core.UnitTests/Communication/Proxies/RuntimeProxyTests.cs
@@ -57,20 +57,23 @@ namespace SafeExamBrowser.Core.UnitTests.Communication.Proxies
proxy.Setup(p => p.Send(It.Is(m => m.Purport == SimpleMessagePurport.ConfigurationNeeded))).Returns(response);
- var configuration = sut.GetConfiguration();
+ var communication = sut.GetConfiguration();
+ var configuration = communication.Value.Configuration;
proxy.Verify(p => p.Send(It.Is(m => m.Purport == SimpleMessagePurport.ConfigurationNeeded)), Times.Once);
+ Assert.IsTrue(communication.Success);
Assert.IsInstanceOfType(configuration, typeof(ClientConfiguration));
}
[TestMethod]
- [ExpectedException(typeof(CommunicationException))]
public void MustFailIfConfigurationNotRetrieved()
{
proxy.Setup(p => p.Send(It.Is(m => m.Purport == SimpleMessagePurport.ConfigurationNeeded))).Returns(null);
- sut.GetConfiguration();
+ var communication = sut.GetConfiguration();
+
+ Assert.IsFalse(communication.Success);
}
[TestMethod]
@@ -78,18 +81,20 @@ namespace SafeExamBrowser.Core.UnitTests.Communication.Proxies
{
proxy.Setup(p => p.Send(It.Is(m => m.Purport == SimpleMessagePurport.ClientIsReady))).Returns(new SimpleResponse(SimpleResponsePurport.Acknowledged));
- sut.InformClientReady();
+ var communication = sut.InformClientReady();
+ Assert.IsTrue(communication.Success);
proxy.Verify(p => p.Send(It.Is(m => m.Purport == SimpleMessagePurport.ClientIsReady)), Times.Once);
}
[TestMethod]
- [ExpectedException(typeof(CommunicationException))]
public void MustFailIfClientReadyNotAcknowledged()
{
proxy.Setup(p => p.Send(It.Is(m => m.Purport == SimpleMessagePurport.ClientIsReady))).Returns(null);
- sut.InformClientReady();
+ var communication = sut.InformClientReady();
+
+ Assert.IsFalse(communication.Success);
}
[TestMethod]
@@ -99,20 +104,22 @@ namespace SafeExamBrowser.Core.UnitTests.Communication.Proxies
proxy.Setup(p => p.Send(It.Is(m => m.ConfigurationPath == url))).Returns(new SimpleResponse(SimpleResponsePurport.Acknowledged));
- sut.RequestReconfiguration(url);
+ var communication = sut.RequestReconfiguration(url);
+ Assert.IsTrue(communication.Success);
proxy.Verify(p => p.Send(It.Is(m => m.ConfigurationPath == url)), Times.Once);
}
[TestMethod]
- [ExpectedException(typeof(CommunicationException))]
public void MustFailIfReconfigurationRequestNotAcknowledged()
{
var url = "file:///C:/Some/file/url.seb";
proxy.Setup(p => p.Send(It.Is(m => m.ConfigurationPath == url))).Returns(null);
- sut.RequestReconfiguration(url);
+ var communication = sut.RequestReconfiguration(url);
+
+ Assert.IsFalse(communication.Success);
}
[TestMethod]
@@ -120,18 +127,20 @@ namespace SafeExamBrowser.Core.UnitTests.Communication.Proxies
{
proxy.Setup(p => p.Send(It.Is(m => m.Purport == SimpleMessagePurport.RequestShutdown))).Returns(new SimpleResponse(SimpleResponsePurport.Acknowledged));
- sut.RequestShutdown();
+ var communication = sut.RequestShutdown();
+ Assert.IsTrue(communication.Success);
proxy.Verify(p => p.Send(It.Is(m => m.Purport == SimpleMessagePurport.RequestShutdown)), Times.Once);
}
[TestMethod]
- [ExpectedException(typeof(CommunicationException))]
public void MustFailIfShutdownRequestNotAcknowledged()
{
proxy.Setup(p => p.Send(It.Is(m => m.Purport == SimpleMessagePurport.RequestShutdown))).Returns(null);
- sut.RequestShutdown();
+ var communication = sut.RequestShutdown();
+
+ Assert.IsFalse(communication.Success);
}
}
}
diff --git a/SafeExamBrowser.Core.UnitTests/Communication/Proxies/ServiceProxyTests.cs b/SafeExamBrowser.Core.UnitTests/Communication/Proxies/ServiceProxyTests.cs
index 3385aa36..c496e3a6 100644
--- a/SafeExamBrowser.Core.UnitTests/Communication/Proxies/ServiceProxyTests.cs
+++ b/SafeExamBrowser.Core.UnitTests/Communication/Proxies/ServiceProxyTests.cs
@@ -10,7 +10,6 @@ using System;
using System.ServiceModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
-using SafeExamBrowser.Contracts.Communication;
using SafeExamBrowser.Contracts.Communication.Data;
using SafeExamBrowser.Contracts.Communication.Proxies;
using SafeExamBrowser.Contracts.Logging;
@@ -68,8 +67,10 @@ namespace SafeExamBrowser.Core.UnitTests.Communication.Proxies
public void MustIgnoreStartSessionIfUnavaiable()
{
sut.Ignore = true;
- sut.StartSession(Guid.Empty, null);
+ var communication = sut.StartSession(Guid.Empty, null);
+
+ Assert.IsTrue(communication.Success);
proxy.Verify(p => p.Send(It.IsAny()), Times.Never);
}
@@ -77,8 +78,10 @@ namespace SafeExamBrowser.Core.UnitTests.Communication.Proxies
public void MustIgnoreStopSessionIfUnavaiable()
{
sut.Ignore = true;
- sut.StopSession(Guid.Empty);
+ var communication = sut.StopSession(Guid.Empty);
+
+ Assert.IsTrue(communication.Success);
proxy.Verify(p => p.Send(It.IsAny()), Times.Never);
}
}
diff --git a/SafeExamBrowser.Core/Communication/Proxies/BaseProxy.cs b/SafeExamBrowser.Core/Communication/Proxies/BaseProxy.cs
index c2817488..982c4e61 100644
--- a/SafeExamBrowser.Core/Communication/Proxies/BaseProxy.cs
+++ b/SafeExamBrowser.Core/Communication/Proxies/BaseProxy.cs
@@ -31,6 +31,7 @@ namespace SafeExamBrowser.Core.Communication.Proxies
private Guid? communicationToken;
private Timer timer;
+ protected bool IsConnected { get { return communicationToken.HasValue; } }
protected ILogger Logger { get; private set; }
public event CommunicationEventHandler ConnectionLost;
@@ -44,50 +45,76 @@ namespace SafeExamBrowser.Core.Communication.Proxies
public virtual bool Connect(Guid? token = null, bool autoPing = true)
{
- Logger.Debug($"Trying to connect to endpoint '{address}'{(token.HasValue ? $" with authentication token '{token}'" : string.Empty)}...");
-
- InitializeProxyObject();
-
- var response = proxy.Connect(token);
-
- communicationToken = response.CommunicationToken;
- Logger.Debug($"Connection was {(response.ConnectionEstablished ? "established" : "refused")}.");
-
- if (response.ConnectionEstablished && autoPing)
+ try
{
- StartAutoPing();
- }
+ Logger.Debug($"Trying to connect to endpoint '{address}'{(token.HasValue ? $" with authentication token '{token}'" : string.Empty)}...");
- return response.ConnectionEstablished;
+ InitializeProxyObject();
+
+ var response = proxy.Connect(token);
+ var success = response.ConnectionEstablished;
+
+ communicationToken = response.CommunicationToken;
+ Logger.Debug($"Connection was {(success ? "established" : "refused")}.");
+
+ if (success && autoPing)
+ {
+ StartAutoPing();
+ }
+
+ return success;
+ }
+ catch (Exception e)
+ {
+ Logger.Error($"Failed to connect to endpoint '{address}'!", e);
+
+ return false;
+ }
}
public virtual bool Disconnect()
{
- FailIfNotConnected(nameof(Disconnect));
- StopAutoPing();
+ try
+ {
+ if (!IsConnected)
+ {
+ Logger.Warn($"Cannot disconnect from endpoint '{address}' before being connected!");
- var message = new DisconnectionMessage { CommunicationToken = communicationToken.Value };
- var response = proxy.Disconnect(message);
+ return false;
+ }
- Logger.Debug($"{(response.ConnectionTerminated ? "Disconnected" : "Failed to disconnect")} from {address}.");
+ StopAutoPing();
- return response.ConnectionTerminated;
+ var message = new DisconnectionMessage { CommunicationToken = communicationToken.Value };
+ var response = proxy.Disconnect(message);
+ var success = response.ConnectionTerminated;
+
+ Logger.Debug($"{(success ? "Disconnected" : "Failed to disconnect")} from {address}.");
+
+ if (success)
+ {
+ communicationToken = null;
+ }
+
+ return success;
+ }
+ catch (Exception e)
+ {
+ Logger.Error($"Failed to disconnect from endpoint '{address}'!", e);
+
+ return false;
+ }
}
///
/// Sends the given message, optionally returning a response. If no response is expected, null will be returned.
///
/// If the given message is null.
- /// If no connection has been established yet.
- /// If the communication failed.
+ /// If no connection has been established yet or the connection is corrupted.
protected virtual Response Send(Message message)
{
- if (message is null)
- {
- throw new ArgumentNullException(nameof(message));
- }
-
- FailIfNotConnected(nameof(Send));
+ FailIfNull(message);
+ FailIfNotConnected();
message.CommunicationToken = communicationToken.Value;
@@ -195,16 +222,24 @@ namespace SafeExamBrowser.Core.Communication.Proxies
Logger.Debug("Communication channel is opening...");
}
- private void FailIfNotConnected(string operationName)
+ private void FailIfNull(Message message)
{
- if (!communicationToken.HasValue)
+ if (message is null)
{
- throw new InvalidOperationException($"Cannot perform '{operationName}' before being connected to endpoint!");
+ throw new ArgumentNullException(nameof(message));
+ }
+ }
+
+ private void FailIfNotConnected()
+ {
+ if (!IsConnected)
+ {
+ throw new InvalidOperationException($"Cannot send message before being connected to endpoint '{address}'!");
}
if (proxy == null || proxy.State != CommunicationState.Opened)
{
- throw new CommunicationException($"Tried to perform {operationName}, but channel was {GetChannelState()}!");
+ throw new InvalidOperationException($"Tried to send message, but channel was {GetChannelState()}!");
}
}
diff --git a/SafeExamBrowser.Core/Communication/Proxies/ClientProxy.cs b/SafeExamBrowser.Core/Communication/Proxies/ClientProxy.cs
index 81f6db3e..e940abbc 100644
--- a/SafeExamBrowser.Core/Communication/Proxies/ClientProxy.cs
+++ b/SafeExamBrowser.Core/Communication/Proxies/ClientProxy.cs
@@ -7,7 +7,6 @@
*/
using System;
-using System.ServiceModel;
using SafeExamBrowser.Contracts.Communication.Data;
using SafeExamBrowser.Contracts.Communication.Proxies;
using SafeExamBrowser.Contracts.Logging;
@@ -23,45 +22,107 @@ namespace SafeExamBrowser.Core.Communication.Proxies
{
}
- public void InformReconfigurationDenied(string filePath)
+ public CommunicationResult InformReconfigurationDenied(string filePath)
{
- var response = Send(new ReconfigurationDeniedMessage(filePath));
-
- if (!IsAcknowledged(response))
+ try
{
- throw new CommunicationException($"Client did not acknowledge shutdown request! Received: {ToString(response)}.");
+ var response = Send(new ReconfigurationDeniedMessage(filePath));
+ var success = IsAcknowledged(response);
+
+ if (success)
+ {
+ Logger.Debug("Client acknowledged reconfiguration denial.");
+ }
+ else
+ {
+ Logger.Error($"Client did not acknowledge reconfiguration denial! Received: {ToString(response)}.");
+ }
+
+ return new CommunicationResult(success);
+ }
+ catch (Exception e)
+ {
+ Logger.Error($"Failed to perform '{nameof(InformReconfigurationDenied)}'", e);
+
+ return new CommunicationResult(false);
}
}
- public void InitiateShutdown()
+ public CommunicationResult InitiateShutdown()
{
- var response = Send(SimpleMessagePurport.Shutdown);
-
- if (!IsAcknowledged(response))
+ try
{
- throw new CommunicationException($"Client did not acknowledge shutdown request! Received: {ToString(response)}.");
+ var response = Send(SimpleMessagePurport.Shutdown);
+ var success = IsAcknowledged(response);
+
+ if (success)
+ {
+ Logger.Debug("Client acknowledged shutdown request.");
+ }
+ else
+ {
+ Logger.Error($"Client did not acknowledge shutdown request! Received: {ToString(response)}.");
+ }
+
+ return new CommunicationResult(success);
+ }
+ catch (Exception e)
+ {
+ Logger.Error($"Failed to perform '{nameof(InitiateShutdown)}'", e);
+
+ return new CommunicationResult(false);
}
}
- public AuthenticationResponse RequestAuthentication()
+ public CommunicationResult RequestAuthentication()
{
- var response = Send(SimpleMessagePurport.Authenticate);
-
- if (response is AuthenticationResponse authenticationResponse)
+ try
{
- return authenticationResponse;
- }
+ var response = Send(SimpleMessagePurport.Authenticate);
+ var success = response is AuthenticationResponse;
- throw new CommunicationException($"Did not receive authentication response! Received: {ToString(response)}.");
+ if (success)
+ {
+ Logger.Debug("Received authentication response.");
+ }
+ else
+ {
+ Logger.Error($"Did not receive authentication response! Received: {ToString(response)}.");
+ }
+
+ return new CommunicationResult(success, response as AuthenticationResponse);
+ }
+ catch (Exception e)
+ {
+ Logger.Error($"Failed to perform '{nameof(RequestAuthentication)}'", e);
+
+ return new CommunicationResult(false, default(AuthenticationResponse));
+ }
}
- public void RequestPassword(PasswordRequestPurpose purpose, Guid requestId)
+ public CommunicationResult RequestPassword(PasswordRequestPurpose purpose, Guid requestId)
{
- var response = Send(new PasswordRequestMessage(purpose, requestId));
-
- if (!IsAcknowledged(response))
+ try
{
- throw new CommunicationException($"Client did not acknowledge shutdown request! Received: {ToString(response)}.");
+ var response = Send(new PasswordRequestMessage(purpose, requestId));
+ var success = IsAcknowledged(response);
+
+ if (success)
+ {
+ Logger.Debug("Client acknowledged password request.");
+ }
+ else
+ {
+ Logger.Error($"Client did not acknowledge password request! Received: {ToString(response)}.");
+ }
+
+ return new CommunicationResult(success);
+ }
+ catch (Exception e)
+ {
+ Logger.Error($"Failed to perform '{nameof(RequestPassword)}'", e);
+
+ return new CommunicationResult(false);
}
}
}
diff --git a/SafeExamBrowser.Core/Communication/Proxies/RuntimeProxy.cs b/SafeExamBrowser.Core/Communication/Proxies/RuntimeProxy.cs
index 6cb7e0bc..7406e2cd 100644
--- a/SafeExamBrowser.Core/Communication/Proxies/RuntimeProxy.cs
+++ b/SafeExamBrowser.Core/Communication/Proxies/RuntimeProxy.cs
@@ -7,10 +7,8 @@
*/
using System;
-using System.ServiceModel;
using SafeExamBrowser.Contracts.Communication.Data;
using SafeExamBrowser.Contracts.Communication.Proxies;
-using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Logging;
namespace SafeExamBrowser.Core.Communication.Proxies
@@ -24,55 +22,133 @@ namespace SafeExamBrowser.Core.Communication.Proxies
{
}
- public ClientConfiguration GetConfiguration()
+ public CommunicationResult GetConfiguration()
{
- var response = Send(SimpleMessagePurport.ConfigurationNeeded);
-
- if (response is ConfigurationResponse configurationResponse)
+ try
{
- return configurationResponse.Configuration;
+ var response = Send(SimpleMessagePurport.ConfigurationNeeded);
+ var success = response is ConfigurationResponse;
+
+ if (success)
+ {
+ Logger.Debug("Received configuration response.");
+ }
+ else
+ {
+ Logger.Error($"Did not retrieve configuration response! Received: {ToString(response)}.");
+ }
+
+ return new CommunicationResult(success, response as ConfigurationResponse);
}
-
- throw new CommunicationException($"Could not retrieve client configuration! Received: {ToString(response)}.");
- }
-
- public void InformClientReady()
- {
- var response = Send(SimpleMessagePurport.ClientIsReady);
-
- if (!IsAcknowledged(response))
+ catch (Exception e)
{
- throw new CommunicationException($"Runtime did not acknowledge that client is ready! Response: {ToString(response)}.");
+ Logger.Error($"Failed to perform '{nameof(GetConfiguration)}'", e);
+
+ return new CommunicationResult(false, default(ConfigurationResponse));
}
}
- public void RequestReconfiguration(string filePath)
+ public CommunicationResult InformClientReady()
{
- var response = Send(new ReconfigurationMessage(filePath));
-
- if (!IsAcknowledged(response))
+ try
{
- throw new CommunicationException($"Runtime did not acknowledge reconfiguration request! Response: {ToString(response)}.");
+ var response = Send(SimpleMessagePurport.ClientIsReady);
+ var success = IsAcknowledged(response);
+
+ if (success)
+ {
+ Logger.Debug("Runtime acknowledged that the client is ready.");
+ }
+ else
+ {
+ Logger.Error($"Runtime did not acknowledge that the client is ready! Response: {ToString(response)}.");
+ }
+
+ return new CommunicationResult(success);
+ }
+ catch (Exception e)
+ {
+ Logger.Error($"Failed to perform '{nameof(InformClientReady)}'", e);
+
+ return new CommunicationResult(false);
}
}
- public void RequestShutdown()
+ public CommunicationResult RequestReconfiguration(string filePath)
{
- var response = Send(SimpleMessagePurport.RequestShutdown);
-
- if (!IsAcknowledged(response))
+ try
{
- throw new CommunicationException($"Runtime did not acknowledge shutdown request! Response: {ToString(response)}.");
+ var response = Send(new ReconfigurationMessage(filePath));
+ var success = IsAcknowledged(response);
+
+ if (success)
+ {
+ Logger.Debug("Runtime acknowledged reconfiguration request.");
+ }
+ else
+ {
+ Logger.Error($"Runtime did not acknowledge reconfiguration request! Response: {ToString(response)}.");
+ }
+
+ return new CommunicationResult(success);
+ }
+ catch (Exception e)
+ {
+ Logger.Error($"Failed to perform '{nameof(RequestReconfiguration)}'", e);
+
+ return new CommunicationResult(false);
}
}
- public void SubmitPassword(Guid requestId, bool success, string password = null)
+ public CommunicationResult RequestShutdown()
{
- var response = Send(new PasswordReplyMessage(requestId, success, password));
-
- if (!IsAcknowledged(response))
+ try
{
- throw new CommunicationException($"Runtime did not acknowledge password submission! Response: {ToString(response)}.");
+ var response = Send(SimpleMessagePurport.RequestShutdown);
+ var success = IsAcknowledged(response);
+
+ if (success)
+ {
+ Logger.Debug("Runtime acknowledged shutdown request.");
+ }
+ else
+ {
+ Logger.Error($"Runtime did not acknowledge shutdown request! Response: {ToString(response)}.");
+ }
+
+ return new CommunicationResult(success);
+ }
+ catch (Exception e)
+ {
+ Logger.Error($"Failed to perform '{nameof(RequestShutdown)}'", e);
+
+ return new CommunicationResult(false);
+ }
+ }
+
+ public CommunicationResult SubmitPassword(Guid requestId, bool success, string password = null)
+ {
+ try
+ {
+ var response = Send(new PasswordReplyMessage(requestId, success, password));
+ var acknowledged = IsAcknowledged(response);
+
+ if (acknowledged)
+ {
+ Logger.Debug("Runtime acknowledged password transmission.");
+ }
+ else
+ {
+ Logger.Error($"Runtime did not acknowledge password transmission! Response: {ToString(response)}.");
+ }
+
+ return new CommunicationResult(acknowledged);
+ }
+ catch (Exception e)
+ {
+ Logger.Error($"Failed to perform '{nameof(SubmitPassword)}'", e);
+
+ return new CommunicationResult(false);
}
}
}
diff --git a/SafeExamBrowser.Core/Communication/Proxies/ServiceProxy.cs b/SafeExamBrowser.Core/Communication/Proxies/ServiceProxy.cs
index 2a4740e8..da5dd5d6 100644
--- a/SafeExamBrowser.Core/Communication/Proxies/ServiceProxy.cs
+++ b/SafeExamBrowser.Core/Communication/Proxies/ServiceProxy.cs
@@ -38,32 +38,36 @@ namespace SafeExamBrowser.Core.Communication.Proxies
{
if (IgnoreOperation(nameof(Disconnect)))
{
- return true;
+ return false;
}
return base.Disconnect();
}
- public void StartSession(Guid sessionId, Settings settings)
+ public CommunicationResult StartSession(Guid sessionId, Settings settings)
{
if (IgnoreOperation(nameof(StartSession)))
{
- return;
+ return new CommunicationResult(true);
}
// TODO: Implement service communication
// Send(new StartSessionMessage { Id = sessionId, Settings = settings });
+
+ throw new NotImplementedException();
}
- public void StopSession(Guid sessionId)
+ public CommunicationResult StopSession(Guid sessionId)
{
if (IgnoreOperation(nameof(StopSession)))
{
- return;
+ return new CommunicationResult(true);
}
// TODO: Implement service communication
// Send(new StopSessionMessage { SessionId = sessionId });
+
+ throw new NotImplementedException();
}
private bool IgnoreOperation(string operationName)
diff --git a/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ClientOperationTests.cs b/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ClientOperationTests.cs
index cd31681e..36e73bda 100644
--- a/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ClientOperationTests.cs
+++ b/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ClientOperationTests.cs
@@ -67,10 +67,11 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
{
var result = default(OperationResult);
var response = new AuthenticationResponse { ProcessId = 1234 };
+ var communication = new CommunicationResult(true, response);
process.SetupGet(p => p.Id).Returns(response.ProcessId);
processFactory.Setup(f => f.StartNew(It.IsAny(), It.IsAny())).Returns(process.Object).Callback(clientReady);
- proxy.Setup(p => p.RequestAuthentication()).Returns(response);
+ proxy.Setup(p => p.RequestAuthentication()).Returns(communication);
proxy.Setup(p => p.Connect(It.IsAny(), true)).Returns(true);
result = sut.Perform();
@@ -86,10 +87,11 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
{
var result = default(OperationResult);
var response = new AuthenticationResponse { ProcessId = 1234 };
+ var communication = new CommunicationResult(true, response);
process.SetupGet(p => p.Id).Returns(response.ProcessId);
processFactory.Setup(f => f.StartNew(It.IsAny(), It.IsAny())).Returns(process.Object).Callback(clientReady);
- proxy.Setup(p => p.RequestAuthentication()).Returns(response);
+ proxy.Setup(p => p.RequestAuthentication()).Returns(communication);
proxy.Setup(p => p.Connect(It.IsAny(), true)).Returns(true);
result = sut.Repeat();
@@ -134,10 +136,11 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
{
var result = default(OperationResult);
var response = new AuthenticationResponse { ProcessId = -1 };
+ var communication = new CommunicationResult(true, response);
process.SetupGet(p => p.Id).Returns(1234);
processFactory.Setup(f => f.StartNew(It.IsAny(), It.IsAny())).Returns(process.Object).Callback(clientReady);
- proxy.Setup(p => p.RequestAuthentication()).Returns(response);
+ proxy.Setup(p => p.RequestAuthentication()).Returns(communication);
proxy.Setup(p => p.Connect(It.IsAny(), true)).Returns(true);
result = sut.Perform();
@@ -204,10 +207,11 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
private void PerformNormally()
{
var response = new AuthenticationResponse { ProcessId = 1234 };
+ var communication = new CommunicationResult(true, response);
process.SetupGet(p => p.Id).Returns(response.ProcessId);
processFactory.Setup(f => f.StartNew(It.IsAny(), It.IsAny())).Returns(process.Object).Callback(clientReady);
- proxy.Setup(p => p.RequestAuthentication()).Returns(response);
+ proxy.Setup(p => p.RequestAuthentication()).Returns(communication);
proxy.Setup(p => p.Connect(It.IsAny(), true)).Returns(true);
sut.Perform();
diff --git a/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ConfigurationOperationTests.cs b/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ConfigurationOperationTests.cs
index 04af1235..1f621e01 100644
--- a/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ConfigurationOperationTests.cs
+++ b/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ConfigurationOperationTests.cs
@@ -335,6 +335,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
public void MustRequestPasswordViaClientDuringReconfigurationOnNewDesktop()
{
var clientProxy = new Mock();
+ var communication = new CommunicationResult(true);
var passwordReceived = new Action((p, id) =>
{
runtimeHost.Raise(r => r.PasswordReceived += null, new PasswordReplyEventArgs { RequestId = id, Success = true });
@@ -342,7 +343,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
var session = new Mock();
var url = @"http://www.safeexambrowser.org/whatever.seb";
- clientProxy.Setup(c => c.RequestPassword(It.IsAny(), It.IsAny())).Callback(passwordReceived);
+ clientProxy.Setup(c => c.RequestPassword(It.IsAny(), It.IsAny())).Returns(communication).Callback(passwordReceived);
passwordDialog.Setup(d => d.Show(null)).Returns(new PasswordDialogResultStub { Success = true });
repository.SetupGet(r => r.CurrentSession).Returns(session.Object);
repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.SettingsPasswordNeeded);
@@ -361,6 +362,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
public void MustAbortAskingForPasswordViaClientIfDecidedByUser()
{
var clientProxy = new Mock();
+ var communication = new CommunicationResult(true);
var passwordReceived = new Action((p, id) =>
{
runtimeHost.Raise(r => r.PasswordReceived += null, new PasswordReplyEventArgs { RequestId = id, Success = false });
@@ -368,8 +370,28 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
var session = new Mock();
var url = @"http://www.safeexambrowser.org/whatever.seb";
- clientProxy.Setup(c => c.RequestPassword(It.IsAny(), It.IsAny())).Callback(passwordReceived);
- passwordDialog.Setup(d => d.Show(null)).Returns(new PasswordDialogResultStub { Success = true });
+ clientProxy.Setup(c => c.RequestPassword(It.IsAny(), It.IsAny())).Returns(communication).Callback(passwordReceived);
+ repository.SetupGet(r => r.CurrentSession).Returns(session.Object);
+ repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.SettingsPasswordNeeded);
+ session.SetupGet(r => r.ClientProxy).Returns(clientProxy.Object);
+ settings.KioskMode = KioskMode.CreateNewDesktop;
+
+ sut = new ConfigurationOperation(appConfig, repository.Object, logger.Object, messageBox.Object, resourceLoader.Object, runtimeHost.Object, text.Object, uiFactory.Object, new[] { "blubb.exe", url });
+
+ var result = sut.Perform();
+
+ Assert.AreEqual(OperationResult.Aborted, result);
+ }
+
+ [TestMethod]
+ public void MustNotWaitForPasswordViaClientIfCommunicationHasFailed()
+ {
+ var clientProxy = new Mock();
+ var communication = new CommunicationResult(false);
+ var session = new Mock();
+ var url = @"http://www.safeexambrowser.org/whatever.seb";
+
+ clientProxy.Setup(c => c.RequestPassword(It.IsAny(), It.IsAny())).Returns(communication);
repository.SetupGet(r => r.CurrentSession).Returns(session.Object);
repository.Setup(r => r.LoadSettings(It.IsAny(), null, null)).Returns(LoadStatus.SettingsPasswordNeeded);
session.SetupGet(r => r.ClientProxy).Returns(clientProxy.Object);
diff --git a/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ServiceOperationTests.cs b/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ServiceOperationTests.cs
index a1c04cdb..90a71111 100644
--- a/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ServiceOperationTests.cs
+++ b/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ServiceOperationTests.cs
@@ -97,16 +97,6 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
configuration.SetupGet(s => s.CurrentSettings).Returns(new Settings { ServicePolicy = ServicePolicy.Optional });
sut.Perform();
-
- service.Setup(s => s.Connect(null, true)).Throws();
- configuration.SetupGet(s => s.CurrentSettings).Returns(new Settings { ServicePolicy = ServicePolicy.Mandatory });
-
- sut.Perform();
-
- service.Setup(s => s.Connect(null, true)).Throws();
- configuration.SetupGet(s => s.CurrentSettings).Returns(new Settings { ServicePolicy = ServicePolicy.Optional });
-
- sut.Perform();
}
[TestMethod]
@@ -177,7 +167,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
public void MustNotFailWhenDisconnecting()
{
service.Setup(s => s.Connect(null, true)).Returns(true);
- service.Setup(s => s.Disconnect()).Throws();
+ service.Setup(s => s.Disconnect()).Returns(false);
configuration.SetupGet(s => s.CurrentSettings).Returns(new Settings { ServicePolicy = ServicePolicy.Optional });
sut.Perform();
@@ -201,18 +191,6 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
sut.Perform();
sut.Revert();
- service.Setup(s => s.Connect(null, true)).Throws();
- configuration.SetupGet(s => s.CurrentSettings).Returns(new Settings { ServicePolicy = ServicePolicy.Mandatory });
-
- sut.Perform();
- sut.Revert();
-
- service.Setup(s => s.Connect(null, true)).Throws();
- configuration.SetupGet(s => s.CurrentSettings).Returns(new Settings { ServicePolicy = ServicePolicy.Optional });
-
- sut.Perform();
- sut.Revert();
-
service.Verify(s => s.Disconnect(), Times.Never);
}
}
diff --git a/SafeExamBrowser.Runtime/Behaviour/Operations/ClientOperation.cs b/SafeExamBrowser.Runtime/Behaviour/Operations/ClientOperation.cs
index 74f7258e..25de60ef 100644
--- a/SafeExamBrowser.Runtime/Behaviour/Operations/ClientOperation.cs
+++ b/SafeExamBrowser.Runtime/Behaviour/Operations/ClientOperation.cs
@@ -120,9 +120,10 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
logger.Info("Connection with client has been established. Requesting authentication...");
- var response = ClientProxy.RequestAuthentication();
+ var communication = ClientProxy.RequestAuthentication();
+ var response = communication.Value;
- if (ClientProcess.Id != response?.ProcessId)
+ if (!communication.Success || ClientProcess.Id != response?.ProcessId)
{
logger.Error("Failed to verify client integrity!");
diff --git a/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs b/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs
index a24c8dba..03ac810b 100644
--- a/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs
+++ b/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs
@@ -172,17 +172,11 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
var title = isAdmin ? TextKey.PasswordDialog_AdminPasswordRequiredTitle : TextKey.PasswordDialog_SettingsPasswordRequiredTitle;
var dialog = uiFactory.CreatePasswordDialog(text.Get(message), text.Get(title));
var result = dialog.Show();
+ var success = result.Success;
- if (result.Success)
- {
- password = result.Password;
- }
- else
- {
- password = default(string);
- }
+ password = success ? result.Password : default(string);
- return result.Success;
+ return success;
}
private bool TryGetPasswordViaClient(PasswordRequestPurpose purpose, out string password)
@@ -200,20 +194,20 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
});
runtimeHost.PasswordReceived += responseEventHandler;
- configuration.CurrentSession.ClientProxy.RequestPassword(purpose, requestId);
- responseEvent.WaitOne();
+
+ var communication = configuration.CurrentSession.ClientProxy.RequestPassword(purpose, requestId);
+
+ if (communication.Success)
+ {
+ responseEvent.WaitOne();
+ }
+
+ var success = response?.Success == true;
+
runtimeHost.PasswordReceived -= responseEventHandler;
+ password = success ? response.Password : default(string);
- if (response.Success)
- {
- password = response.Password;
- }
- else
- {
- password = default(string);
- }
-
- return response.Success;
+ return success;
}
private void HandleInvalidData(ref LoadStatus status, Uri uri)
diff --git a/SafeExamBrowser.Runtime/Behaviour/Operations/ServiceOperation.cs b/SafeExamBrowser.Runtime/Behaviour/Operations/ServiceOperation.cs
index 2a6c99f3..90ae10ac 100644
--- a/SafeExamBrowser.Runtime/Behaviour/Operations/ServiceOperation.cs
+++ b/SafeExamBrowser.Runtime/Behaviour/Operations/ServiceOperation.cs
@@ -6,7 +6,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-using System;
using SafeExamBrowser.Contracts.Behaviour.OperationModel;
using SafeExamBrowser.Contracts.Communication.Proxies;
using SafeExamBrowser.Contracts.Configuration;
@@ -40,15 +39,8 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
logger.Info($"Initializing service session...");
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeServiceSession);
- try
- {
- mandatory = configuration.CurrentSettings.ServicePolicy == ServicePolicy.Mandatory;
- connected = service.Connect();
- }
- catch (Exception e)
- {
- LogException(e);
- }
+ mandatory = configuration.CurrentSettings.ServicePolicy == ServicePolicy.Mandatory;
+ connected = service.Connect();
if (mandatory && !connected)
{
@@ -89,13 +81,15 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
{
StopServiceSession();
- try
+ var success = service.Disconnect();
+
+ if (success)
{
- service.Disconnect();
+ logger.Info("Successfully disconnected from the service.");
}
- catch (Exception e)
+ else
{
- logger.Error("Failed to disconnect from the service!", e);
+ logger.Error("Failed to disconnect from the service!");
}
}
}
@@ -109,19 +103,5 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
{
service.StopSession(configuration.CurrentSession.Id);
}
-
- private void LogException(Exception e)
- {
- var message = "Failed to connect to the service component!";
-
- if (mandatory)
- {
- logger.Error(message, e);
- }
- else
- {
- logger.Info($"{message} Reason: {e.Message}");
- }
- }
}
}