SEBWIN-301: Switched from interface to data container for session configuration (separated client and service session configuration) and implemented mapping of service policy including the respective message boxes.
This commit is contained in:
parent
73c7e28a33
commit
e9d91cb898
45 changed files with 319 additions and 237 deletions
|
@ -49,7 +49,7 @@ namespace SafeExamBrowser.Client.UnitTests.Communication
|
|||
{
|
||||
var token = Guid.NewGuid();
|
||||
|
||||
sut.StartupToken = token;
|
||||
sut.AuthenticationToken = token;
|
||||
|
||||
var response = sut.Connect(token);
|
||||
|
||||
|
@ -64,7 +64,7 @@ namespace SafeExamBrowser.Client.UnitTests.Communication
|
|||
{
|
||||
var token = Guid.NewGuid();
|
||||
|
||||
sut.StartupToken = token;
|
||||
sut.AuthenticationToken = token;
|
||||
|
||||
var response = sut.Connect(Guid.NewGuid());
|
||||
|
||||
|
@ -78,7 +78,7 @@ namespace SafeExamBrowser.Client.UnitTests.Communication
|
|||
{
|
||||
var token = Guid.NewGuid();
|
||||
|
||||
sut.StartupToken = token;
|
||||
sut.AuthenticationToken = token;
|
||||
|
||||
var response1 = sut.Connect(token);
|
||||
var response2 = sut.Connect(token);
|
||||
|
@ -102,7 +102,7 @@ namespace SafeExamBrowser.Client.UnitTests.Communication
|
|||
var token = Guid.NewGuid();
|
||||
|
||||
sut.RuntimeDisconnected += () => eventFired = true;
|
||||
sut.StartupToken = token;
|
||||
sut.AuthenticationToken = token;
|
||||
|
||||
var connectionResponse = sut.Connect(token);
|
||||
var response = sut.Disconnect(new DisconnectionMessage { CommunicationToken = connectionResponse.CommunicationToken.Value });
|
||||
|
@ -116,11 +116,11 @@ namespace SafeExamBrowser.Client.UnitTests.Communication
|
|||
[TestMethod]
|
||||
public void MustNotAllowReconnectionAfterDisconnection()
|
||||
{
|
||||
var token = sut.StartupToken = Guid.NewGuid();
|
||||
var token = sut.AuthenticationToken = Guid.NewGuid();
|
||||
var response = sut.Connect(token);
|
||||
|
||||
sut.Disconnect(new DisconnectionMessage { CommunicationToken = response.CommunicationToken.Value });
|
||||
sut.StartupToken = token = Guid.NewGuid();
|
||||
sut.AuthenticationToken = token = Guid.NewGuid();
|
||||
|
||||
response = sut.Connect(token);
|
||||
|
||||
|
@ -130,7 +130,7 @@ namespace SafeExamBrowser.Client.UnitTests.Communication
|
|||
[TestMethod]
|
||||
public void MustHandleAuthenticationRequestCorrectly()
|
||||
{
|
||||
sut.StartupToken = Guid.Empty;
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new SimpleMessage(SimpleMessagePurport.Authenticate) { CommunicationToken = token };
|
||||
|
@ -157,7 +157,7 @@ namespace SafeExamBrowser.Client.UnitTests.Communication
|
|||
messageBoxRequested = args.Action == action && args.Icon == icon && args.Message == message && args.RequestId == requestId && args.Title == title;
|
||||
resetEvent.Set();
|
||||
};
|
||||
sut.StartupToken = Guid.Empty;
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var request = new MessageBoxRequestMessage(action, icon, message, requestId, title) { CommunicationToken = token };
|
||||
|
@ -184,7 +184,7 @@ namespace SafeExamBrowser.Client.UnitTests.Communication
|
|||
passwordRequested = args.Purpose == purpose && args.RequestId == requestId;
|
||||
resetEvent.Set();
|
||||
};
|
||||
sut.StartupToken = Guid.Empty;
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new PasswordRequestMessage(purpose, requestId) { CommunicationToken = token };
|
||||
|
@ -210,7 +210,7 @@ namespace SafeExamBrowser.Client.UnitTests.Communication
|
|||
reconfigurationDenied = new Uri(args.ConfigurationPath).Equals(new Uri(filePath));
|
||||
resetEvent.Set();
|
||||
};
|
||||
sut.StartupToken = Guid.Empty;
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new ReconfigurationDeniedMessage(filePath) { CommunicationToken = token };
|
||||
|
@ -230,7 +230,7 @@ namespace SafeExamBrowser.Client.UnitTests.Communication
|
|||
var shutdownRequested = false;
|
||||
|
||||
sut.Shutdown += () => shutdownRequested = true;
|
||||
sut.StartupToken = Guid.Empty;
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new SimpleMessage(SimpleMessagePurport.Shutdown) { CommunicationToken = token };
|
||||
|
@ -245,7 +245,7 @@ namespace SafeExamBrowser.Client.UnitTests.Communication
|
|||
[TestMethod]
|
||||
public void MustReturnUnknownMessageAsDefault()
|
||||
{
|
||||
sut.StartupToken = Guid.Empty;
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new TestMessage { CommunicationToken = token } as Message;
|
||||
|
@ -266,7 +266,7 @@ namespace SafeExamBrowser.Client.UnitTests.Communication
|
|||
[TestMethod]
|
||||
public void MustNotFailIfNoEventHandlersSubscribed()
|
||||
{
|
||||
sut.StartupToken = Guid.Empty;
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace SafeExamBrowser.Client.Communication
|
|||
private bool allowConnection = true;
|
||||
private int processId;
|
||||
|
||||
public Guid StartupToken { private get; set; }
|
||||
public Guid AuthenticationToken { private get; set; }
|
||||
public bool IsConnected { get; private set; }
|
||||
|
||||
public event CommunicationEventHandler<MessageBoxRequestEventArgs> MessageBoxRequested;
|
||||
|
@ -41,7 +41,7 @@ namespace SafeExamBrowser.Client.Communication
|
|||
|
||||
protected override bool OnConnect(Guid? token)
|
||||
{
|
||||
var authenticated = StartupToken == token;
|
||||
var authenticated = AuthenticationToken == token;
|
||||
var accepted = allowConnection && authenticated;
|
||||
|
||||
if (accepted)
|
||||
|
|
|
@ -51,11 +51,11 @@ namespace SafeExamBrowser.Client
|
|||
{
|
||||
internal class CompositionRoot
|
||||
{
|
||||
private Guid authenticationToken;
|
||||
private ClientConfiguration configuration;
|
||||
private string logFilePath;
|
||||
private LogLevel logLevel;
|
||||
private string runtimeHostUri;
|
||||
private Guid startupToken;
|
||||
private UserInterfaceMode uiMode;
|
||||
|
||||
private IActionCenter actionCenter;
|
||||
|
@ -110,7 +110,7 @@ namespace SafeExamBrowser.Client
|
|||
var operations = new Queue<IOperation>();
|
||||
|
||||
operations.Enqueue(new I18nOperation(logger, text, textResource));
|
||||
operations.Enqueue(new RuntimeConnectionOperation(logger, runtimeProxy, startupToken));
|
||||
operations.Enqueue(new RuntimeConnectionOperation(logger, runtimeProxy, authenticationToken));
|
||||
operations.Enqueue(new ConfigurationOperation(configuration, logger, runtimeProxy));
|
||||
operations.Enqueue(new DelegateOperation(UpdateAppConfig));
|
||||
operations.Enqueue(new LazyInitializationOperation(BuildClientHostOperation));
|
||||
|
@ -166,14 +166,14 @@ namespace SafeExamBrowser.Client
|
|||
var hasLogfilePath = Uri.TryCreate(args[1], UriKind.Absolute, out Uri filePath) && filePath.IsFile;
|
||||
var hasLogLevel = Enum.TryParse(args[2], out LogLevel level);
|
||||
var hasHostUri = Uri.TryCreate(args[3], UriKind.Absolute, out Uri hostUri) && hostUri.IsWellFormedOriginalString();
|
||||
var hasToken = Guid.TryParse(args[4], out Guid token);
|
||||
var hasAuthenticationToken = Guid.TryParse(args[4], out Guid token);
|
||||
|
||||
if (hasLogfilePath && hasLogLevel && hasHostUri && hasToken)
|
||||
if (hasLogfilePath && hasLogLevel && hasHostUri && hasAuthenticationToken)
|
||||
{
|
||||
logFilePath = args[1];
|
||||
logLevel = level;
|
||||
runtimeHostUri = args[3];
|
||||
startupToken = token;
|
||||
authenticationToken = token;
|
||||
uiMode = args.Length == 6 && Enum.TryParse(args[5], out uiMode) ? uiMode : UserInterfaceMode.Desktop;
|
||||
|
||||
return;
|
||||
|
@ -222,7 +222,7 @@ namespace SafeExamBrowser.Client
|
|||
var operation = new CommunicationHostOperation(host, logger);
|
||||
|
||||
clientHost = host;
|
||||
clientHost.StartupToken = startupToken;
|
||||
clientHost.AuthenticationToken = authenticationToken;
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace SafeExamBrowser.Communication.UnitTests.Proxies
|
|||
{
|
||||
sut.Ignore = true;
|
||||
|
||||
var communication = sut.StartSession(Guid.Empty, null);
|
||||
var communication = sut.StartSession(null);
|
||||
|
||||
Assert.IsTrue(communication.Success);
|
||||
proxy.Verify(p => p.Send(It.IsAny<Message>()), Times.Never);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
using System;
|
||||
using SafeExamBrowser.Contracts.Communication.Proxies;
|
||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
|
||||
namespace SafeExamBrowser.Communication.Proxies
|
||||
|
@ -45,7 +45,7 @@ namespace SafeExamBrowser.Communication.Proxies
|
|||
return base.Disconnect();
|
||||
}
|
||||
|
||||
public CommunicationResult StartSession(Guid sessionId, Settings settings)
|
||||
public CommunicationResult StartSession(ServiceConfiguration configuration)
|
||||
{
|
||||
if (IgnoreOperation(nameof(StartSession)))
|
||||
{
|
||||
|
|
|
@ -275,10 +275,11 @@ namespace SafeExamBrowser.Configuration.UnitTests
|
|||
var appConfig = sut.InitializeAppConfig();
|
||||
var configuration = sut.InitializeSessionConfiguration();
|
||||
|
||||
Assert.IsInstanceOfType(configuration.AppConfig, typeof(AppConfig));
|
||||
Assert.IsInstanceOfType(configuration.Id, typeof(Guid));
|
||||
Assert.IsNull(configuration.Settings);
|
||||
Assert.IsInstanceOfType(configuration.StartupToken, typeof(Guid));
|
||||
Assert.IsInstanceOfType(configuration.AppConfig, typeof(AppConfig));
|
||||
Assert.IsInstanceOfType(configuration.ClientAuthenticationToken, typeof(Guid));
|
||||
Assert.IsInstanceOfType(configuration.ServiceAuthenticationToken, typeof(Guid));
|
||||
Assert.IsInstanceOfType(configuration.SessionId, typeof(Guid));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -309,10 +310,12 @@ namespace SafeExamBrowser.Configuration.UnitTests
|
|||
var secondSession = sut.InitializeSessionConfiguration();
|
||||
var thirdSession = sut.InitializeSessionConfiguration();
|
||||
|
||||
Assert.AreNotEqual(firstSession.Id, secondSession.Id);
|
||||
Assert.AreNotEqual(firstSession.StartupToken, secondSession.StartupToken);
|
||||
Assert.AreNotEqual(secondSession.Id, thirdSession.Id);
|
||||
Assert.AreNotEqual(secondSession.StartupToken, thirdSession.StartupToken);
|
||||
Assert.AreNotEqual(firstSession.SessionId, secondSession.SessionId);
|
||||
Assert.AreNotEqual(firstSession.ClientAuthenticationToken, secondSession.ClientAuthenticationToken);
|
||||
Assert.AreNotEqual(firstSession.ServiceAuthenticationToken, secondSession.ServiceAuthenticationToken);
|
||||
Assert.AreNotEqual(secondSession.SessionId, thirdSession.SessionId);
|
||||
Assert.AreNotEqual(secondSession.ClientAuthenticationToken, thirdSession.ClientAuthenticationToken);
|
||||
Assert.AreNotEqual(secondSession.ServiceAuthenticationToken, thirdSession.ServiceAuthenticationToken);
|
||||
}
|
||||
|
||||
private void RegisterModules()
|
||||
|
|
|
@ -33,5 +33,16 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
|||
settings.KioskMode = KioskMode.None;
|
||||
}
|
||||
}
|
||||
|
||||
private void MapServicePolicy(Settings settings, object value)
|
||||
{
|
||||
const int WARN = 1;
|
||||
const int FORCE = 2;
|
||||
|
||||
if (value is int policy)
|
||||
{
|
||||
settings.ServicePolicy = policy == FORCE ? ServicePolicy.Mandatory : (policy == WARN ? ServicePolicy.Warn : ServicePolicy.Optional);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
|||
MapConfigurationFileSettings(item.Key, item.Value, settings);
|
||||
MapGeneralSettings(item.Key, item.Value, settings);
|
||||
MapInputSettings(item.Key, item.Value, settings);
|
||||
MapSecuritySettings(item.Key, item.Value, settings);
|
||||
MapUserInterfaceSettings(item.Key, item.Value, settings);
|
||||
}
|
||||
|
||||
|
@ -174,6 +175,16 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
|||
}
|
||||
}
|
||||
|
||||
private void MapSecuritySettings(string key, object value, Settings settings)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case Keys.Security.ServicePolicy:
|
||||
MapServicePolicy(settings, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void MapUserInterfaceSettings(string key, object value, Settings settings)
|
||||
{
|
||||
switch (key)
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
|||
return appConfig;
|
||||
}
|
||||
|
||||
internal ISessionConfiguration InitializeSessionConfiguration()
|
||||
internal SessionConfiguration InitializeSessionConfiguration()
|
||||
{
|
||||
var configuration = new SessionConfiguration();
|
||||
|
||||
|
@ -80,8 +80,9 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
|||
appConfig.ClientAddress = $"{BASE_ADDRESS}/client/{Guid.NewGuid()}";
|
||||
|
||||
configuration.AppConfig = appConfig.Clone();
|
||||
configuration.Id = Guid.NewGuid();
|
||||
configuration.StartupToken = Guid.NewGuid();
|
||||
configuration.ClientAuthenticationToken = Guid.NewGuid();
|
||||
configuration.ServiceAuthenticationToken = Guid.NewGuid();
|
||||
configuration.SessionId = Guid.NewGuid();
|
||||
|
||||
return configuration;
|
||||
}
|
||||
|
|
|
@ -116,6 +116,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
|||
{
|
||||
internal const string KioskModeCreateNewDesktop = "createNewDesktop";
|
||||
internal const string KioskModeDisableExplorerShell = "killExplorerShell";
|
||||
internal const string ServicePolicy = "sebServicePolicy";
|
||||
}
|
||||
|
||||
internal static class UserInterface
|
||||
|
|
|
@ -94,7 +94,7 @@ namespace SafeExamBrowser.Configuration
|
|||
return dataValues.InitializeAppConfig();
|
||||
}
|
||||
|
||||
public ISessionConfiguration InitializeSessionConfiguration()
|
||||
public SessionConfiguration InitializeSessionConfiguration()
|
||||
{
|
||||
return dataValues.InitializeSessionConfiguration();
|
||||
}
|
||||
|
|
|
@ -94,7 +94,6 @@
|
|||
<Compile Include="ConfigurationRepository.cs" />
|
||||
<Compile Include="DataResources\FileResourceLoader.cs" />
|
||||
<Compile Include="DataResources\NetworkResourceLoader.cs" />
|
||||
<Compile Include="SessionConfiguration.cs" />
|
||||
<Compile Include="SubStream.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||
|
||||
namespace SafeExamBrowser.Configuration
|
||||
{
|
||||
internal class SessionConfiguration : ISessionConfiguration
|
||||
{
|
||||
public AppConfig AppConfig { get; set; }
|
||||
public Guid Id { get; set; }
|
||||
public Settings Settings { get; set; }
|
||||
public Guid StartupToken { get; set; }
|
||||
}
|
||||
}
|
|
@ -16,16 +16,16 @@ namespace SafeExamBrowser.Contracts.Communication.Hosts
|
|||
/// </summary>
|
||||
public interface IClientHost : ICommunicationHost
|
||||
{
|
||||
/// <summary>
|
||||
/// The token used for initial authentication with the runtime.
|
||||
/// </summary>
|
||||
Guid AuthenticationToken { set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the runtime has established a connection to this host.
|
||||
/// </summary>
|
||||
bool IsConnected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The startup token used for initial authentication.
|
||||
/// </summary>
|
||||
Guid StartupToken { set; }
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when the runtime requests a message box input from the user.
|
||||
/// </summary>
|
||||
|
|
|
@ -22,9 +22,9 @@ namespace SafeExamBrowser.Contracts.Communication.Hosts
|
|||
bool AllowConnection { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The startup token used for initial authentication.
|
||||
/// The token used for initial authentication.
|
||||
/// </summary>
|
||||
Guid StartupToken { set; }
|
||||
Guid AuthenticationToken { set; }
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when the client disconnected from the runtime.
|
||||
|
|
|
@ -10,6 +10,7 @@ using System;
|
|||
using System.ServiceModel;
|
||||
using SafeExamBrowser.Contracts.Communication.Data;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using ServiceConfiguration = SafeExamBrowser.Contracts.Configuration.ServiceConfiguration;
|
||||
|
||||
namespace SafeExamBrowser.Contracts.Communication
|
||||
{
|
||||
|
@ -26,6 +27,7 @@ namespace SafeExamBrowser.Contracts.Communication
|
|||
[ServiceKnownType(typeof(PasswordRequestMessage))]
|
||||
[ServiceKnownType(typeof(ReconfigurationMessage))]
|
||||
[ServiceKnownType(typeof(ReconfigurationDeniedMessage))]
|
||||
[ServiceKnownType(typeof(ServiceConfiguration))]
|
||||
[ServiceKnownType(typeof(SimpleMessage))]
|
||||
[ServiceKnownType(typeof(SimpleResponse))]
|
||||
public interface ICommunication
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
|
||||
namespace SafeExamBrowser.Contracts.Communication.Proxies
|
||||
{
|
||||
|
@ -28,9 +28,9 @@ namespace SafeExamBrowser.Contracts.Communication.Proxies
|
|||
bool IsConnected { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Instructs the service to start a new session according to the given parameters.
|
||||
/// Instructs the service to start a new session according to the given configuration.
|
||||
/// </summary>
|
||||
CommunicationResult StartSession(Guid sessionId, Settings settings);
|
||||
CommunicationResult StartSession(ServiceConfiguration configuration);
|
||||
|
||||
/// <summary>
|
||||
/// Instructs the service to stop the specified session.
|
||||
|
|
|
@ -11,7 +11,7 @@ using System;
|
|||
namespace SafeExamBrowser.Contracts.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// Container for the configuration of the client application component.
|
||||
/// The configuration for a session of the client application component.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ClientConfiguration
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace SafeExamBrowser.Contracts.Configuration
|
|||
/// <summary>
|
||||
/// Initializes all relevant configuration data for a new session.
|
||||
/// </summary>
|
||||
ISessionConfiguration InitializeSessionConfiguration();
|
||||
SessionConfiguration InitializeSessionConfiguration();
|
||||
|
||||
/// <summary>
|
||||
/// Loads the default settings.
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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;
|
||||
|
||||
namespace SafeExamBrowser.Contracts.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// The configuration for a session of the service application component.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ServiceConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// The global application configuration.
|
||||
/// </summary>
|
||||
public AppConfig AppConfig { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The token used for initial authentication with the runtime.
|
||||
/// </summary>
|
||||
public Guid AuthenticationToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The unique identifier for the current session.
|
||||
/// </summary>
|
||||
public Guid SessionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The application settings to be used by the service.
|
||||
/// </summary>
|
||||
public Settings.Settings Settings { get; set; }
|
||||
}
|
||||
}
|
|
@ -11,28 +11,33 @@ using System;
|
|||
namespace SafeExamBrowser.Contracts.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds all session-related configuration data.
|
||||
/// Container holding all session-related configuration data.
|
||||
/// </summary>
|
||||
public interface ISessionConfiguration
|
||||
public class SessionConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// The active application configuration for this session.
|
||||
/// </summary>
|
||||
AppConfig AppConfig { get; }
|
||||
public AppConfig AppConfig { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The token used for initial communication authentication with the client.
|
||||
/// </summary>
|
||||
public Guid ClientAuthenticationToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The token used for initial communication authentication with the service.
|
||||
/// </summary>
|
||||
public Guid ServiceAuthenticationToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The unique session identifier.
|
||||
/// </summary>
|
||||
Guid Id { get; }
|
||||
public Guid SessionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The settings used for this session.
|
||||
/// </summary>
|
||||
Settings.Settings Settings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The startup token used by the client and runtime components for initial authentication.
|
||||
/// </summary>
|
||||
Guid StartupToken { get; }
|
||||
public Settings.Settings Settings { get; set; }
|
||||
}
|
||||
}
|
|
@ -21,6 +21,11 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings
|
|||
/// <summary>
|
||||
/// The service component is optional. If it is not running, all service-related actions are simply skipped.
|
||||
/// </summary>
|
||||
Optional
|
||||
Optional,
|
||||
|
||||
/// <summary>
|
||||
/// The service component should be running. If it is not running, the user will be warned that all service-related actions are skipped.
|
||||
/// </summary>
|
||||
Warn
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,10 @@ namespace SafeExamBrowser.Contracts.I18n
|
|||
MessageBox_ReconfigurationQuestionTitle,
|
||||
MessageBox_ReloadConfirmation,
|
||||
MessageBox_ReloadConfirmationTitle,
|
||||
MessageBox_ServiceUnavailableError,
|
||||
MessageBox_ServiceUnavailableErrorTitle,
|
||||
MessageBox_ServiceUnavailableWarning,
|
||||
MessageBox_ServiceUnavailableWarningTitle,
|
||||
MessageBox_SessionStartError,
|
||||
MessageBox_SessionStartErrorTitle,
|
||||
MessageBox_ShutdownError,
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
<Compile Include="Communication\Events\MessageBoxReplyEventArgs.cs" />
|
||||
<Compile Include="Communication\Events\MessageBoxRequestEventArgs.cs" />
|
||||
<Compile Include="Communication\Hosts\IServiceHost.cs" />
|
||||
<Compile Include="Configuration\ClientConfiguration.cs" />
|
||||
<Compile Include="Configuration\Cryptography\EncryptionParameters.cs" />
|
||||
<Compile Include="Configuration\Cryptography\ICertificateStore.cs" />
|
||||
<Compile Include="Configuration\Cryptography\IPasswordEncryption.cs" />
|
||||
|
@ -76,6 +77,7 @@
|
|||
<Compile Include="Configuration\DataResources\IResourceLoader.cs" />
|
||||
<Compile Include="Configuration\DataResources\IResourceSaver.cs" />
|
||||
<Compile Include="Configuration\SaveStatus.cs" />
|
||||
<Compile Include="Configuration\ServiceConfiguration.cs" />
|
||||
<Compile Include="Configuration\Settings\ActionCenterSettings.cs" />
|
||||
<Compile Include="Configuration\Settings\BrowserWindowSettings.cs" />
|
||||
<Compile Include="Configuration\Settings\UserInterfaceMode.cs" />
|
||||
|
@ -133,10 +135,9 @@
|
|||
<Compile Include="Communication\Data\Response.cs" />
|
||||
<Compile Include="Communication\Data\SimpleResponsePurport.cs" />
|
||||
<Compile Include="Communication\Data\SimpleResponse.cs" />
|
||||
<Compile Include="Configuration\ClientConfiguration.cs" />
|
||||
<Compile Include="Configuration\LoadStatus.cs" />
|
||||
<Compile Include="Configuration\AppConfig.cs" />
|
||||
<Compile Include="Configuration\ISessionConfiguration.cs" />
|
||||
<Compile Include="Configuration\SessionConfiguration.cs" />
|
||||
<Compile Include="Configuration\Settings\ConfigurationMode.cs" />
|
||||
<Compile Include="Client\INotificationController.cs" />
|
||||
<Compile Include="Core\OperationModel\IOperation.cs" />
|
||||
|
|
|
@ -102,6 +102,18 @@
|
|||
<Entry key="MessageBox_ReloadConfirmationTitle">
|
||||
Reload?
|
||||
</Entry>
|
||||
<Entry key="MessageBox_ServiceUnavailableError">
|
||||
Failed to initialize the Safe Exam Browser service! The application is not allowed to start since the current configuration requires the service to be running.
|
||||
</Entry>
|
||||
<Entry key="MessageBox_ServiceUnavailableErrorTitle">
|
||||
Service Unavailable
|
||||
</Entry>
|
||||
<Entry key="MessageBox_ServiceUnavailableWarning">
|
||||
Failed to initialize the Safe Exam Browser service. The application is allowed to start, but it should be ensured that the service is installed and running.
|
||||
</Entry>
|
||||
<Entry key="MessageBox_ServiceUnavailableWarningTitle">
|
||||
Service Unavailable
|
||||
</Entry>
|
||||
<Entry key="MessageBox_SessionStartError">
|
||||
The application failed to start a new session! Please consult the application log for more information...
|
||||
</Entry>
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication
|
|||
var token = Guid.NewGuid();
|
||||
|
||||
sut.AllowConnection = true;
|
||||
sut.StartupToken = token;
|
||||
sut.AuthenticationToken = token;
|
||||
|
||||
var response = sut.Connect(token);
|
||||
|
||||
|
@ -62,7 +62,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication
|
|||
var token = Guid.NewGuid();
|
||||
|
||||
sut.AllowConnection = true;
|
||||
sut.StartupToken = token;
|
||||
sut.AuthenticationToken = token;
|
||||
|
||||
var response = sut.Connect(Guid.NewGuid());
|
||||
|
||||
|
@ -76,7 +76,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication
|
|||
var token = Guid.NewGuid();
|
||||
|
||||
sut.AllowConnection = true;
|
||||
sut.StartupToken = token;
|
||||
sut.AuthenticationToken = token;
|
||||
|
||||
var response1 = sut.Connect(token);
|
||||
var response2 = sut.Connect(token);
|
||||
|
@ -100,7 +100,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication
|
|||
var token = Guid.NewGuid();
|
||||
|
||||
sut.AllowConnection = true;
|
||||
sut.StartupToken = token;
|
||||
sut.AuthenticationToken = token;
|
||||
sut.ClientDisconnected += () => disconnected = true;
|
||||
|
||||
var connectionResponse = sut.Connect(token);
|
||||
|
@ -117,13 +117,13 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication
|
|||
var token = Guid.NewGuid();
|
||||
|
||||
sut.AllowConnection = true;
|
||||
sut.StartupToken = token;
|
||||
sut.AuthenticationToken = token;
|
||||
|
||||
var response = sut.Connect(token);
|
||||
|
||||
sut.Disconnect(new DisconnectionMessage { CommunicationToken = response.CommunicationToken.Value });
|
||||
sut.AllowConnection = true;
|
||||
sut.StartupToken = token = Guid.NewGuid();
|
||||
sut.AuthenticationToken = token = Guid.NewGuid();
|
||||
|
||||
response = sut.Connect(token);
|
||||
|
||||
|
@ -137,7 +137,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication
|
|||
|
||||
sut.AllowConnection = true;
|
||||
sut.ClientReady += () => clientReady = true;
|
||||
sut.StartupToken = Guid.Empty;
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new SimpleMessage(SimpleMessagePurport.ClientIsReady) { CommunicationToken = token };
|
||||
|
@ -157,7 +157,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication
|
|||
|
||||
sut.AllowConnection = true;
|
||||
sut.ClientConfigurationNeeded += (a) => { args = a; args.ClientConfiguration = configuration; };
|
||||
sut.StartupToken = Guid.Empty;
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new SimpleMessage(SimpleMessagePurport.ConfigurationNeeded) { CommunicationToken = token };
|
||||
|
@ -176,7 +176,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication
|
|||
|
||||
sut.AllowConnection = true;
|
||||
sut.ShutdownRequested += () => shutdownRequested = true;
|
||||
sut.StartupToken = Guid.Empty;
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new SimpleMessage(SimpleMessagePurport.RequestShutdown) { CommunicationToken = token };
|
||||
|
@ -198,7 +198,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication
|
|||
|
||||
sut.AllowConnection = true;
|
||||
sut.MessageBoxReplyReceived += (a) => { args = a; sync.Set(); };
|
||||
sut.StartupToken = Guid.Empty;
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new MessageBoxReplyMessage(requestId, result) { CommunicationToken = token };
|
||||
|
@ -225,7 +225,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication
|
|||
|
||||
sut.AllowConnection = true;
|
||||
sut.PasswordReceived += (a) => { args = a; sync.Set(); };
|
||||
sut.StartupToken = Guid.Empty;
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new PasswordReplyMessage(requestId, success, password) { CommunicationToken = token };
|
||||
|
@ -251,7 +251,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication
|
|||
|
||||
sut.AllowConnection = true;
|
||||
sut.ReconfigurationRequested += (a) => { args = a; sync.Set(); };
|
||||
sut.StartupToken = Guid.Empty;
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new ReconfigurationMessage(path) { CommunicationToken = token };
|
||||
|
@ -270,7 +270,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication
|
|||
public void MustReturnUnknownMessageAsDefault()
|
||||
{
|
||||
sut.AllowConnection = true;
|
||||
sut.StartupToken = Guid.Empty;
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
var message = new TestMessage { CommunicationToken = token } as Message;
|
||||
|
@ -292,7 +292,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication
|
|||
public void MustNotFailIfNoEventHandlersSubscribed()
|
||||
{
|
||||
sut.AllowConnection = true;
|
||||
sut.StartupToken = Guid.Empty;
|
||||
sut.AuthenticationToken = Guid.Empty;
|
||||
|
||||
var token = sut.Connect(Guid.Empty).CommunicationToken.Value;
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
private Mock<IProcessFactory> processFactory;
|
||||
private Mock<IProxyFactory> proxyFactory;
|
||||
private Mock<IRuntimeHost> runtimeHost;
|
||||
private Mock<ISessionConfiguration> session;
|
||||
private SessionConfiguration session;
|
||||
private SessionContext sessionContext;
|
||||
private Settings settings;
|
||||
private ClientOperation sut;
|
||||
|
@ -50,7 +50,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
proxy = new Mock<IClientProxy>();
|
||||
proxyFactory = new Mock<IProxyFactory>();
|
||||
runtimeHost = new Mock<IRuntimeHost>();
|
||||
session = new Mock<ISessionConfiguration>();
|
||||
session = new SessionConfiguration();
|
||||
sessionContext = new SessionContext();
|
||||
settings = new Settings();
|
||||
terminated = new Action(() =>
|
||||
|
@ -59,10 +59,10 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
process.Raise(p => p.Terminated += null, 0);
|
||||
});
|
||||
|
||||
session.SetupGet(s => s.AppConfig).Returns(appConfig);
|
||||
session.SetupGet(s => s.Settings).Returns(settings);
|
||||
sessionContext.Current = session.Object;
|
||||
sessionContext.Next = session.Object;
|
||||
session.AppConfig = appConfig;
|
||||
session.Settings = settings;
|
||||
sessionContext.Current = session;
|
||||
sessionContext.Next = session;
|
||||
proxyFactory.Setup(f => f.CreateClientProxy(It.IsAny<string>())).Returns(proxy.Object);
|
||||
|
||||
sut = new ClientOperation(logger.Object, processFactory.Object, proxyFactory.Object, runtimeHost.Object, sessionContext, 0);
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
private Mock<IProcessFactory> processFactory;
|
||||
private Mock<IProxyFactory> proxyFactory;
|
||||
private Mock<IRuntimeHost> runtimeHost;
|
||||
private Mock<ISessionConfiguration> session;
|
||||
private SessionConfiguration session;
|
||||
private SessionContext sessionContext;
|
||||
|
||||
private ClientTerminationOperation sut;
|
||||
|
@ -47,7 +47,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
proxy = new Mock<IClientProxy>();
|
||||
proxyFactory = new Mock<IProxyFactory>();
|
||||
runtimeHost = new Mock<IRuntimeHost>();
|
||||
session = new Mock<ISessionConfiguration>();
|
||||
session = new SessionConfiguration();
|
||||
sessionContext = new SessionContext();
|
||||
terminated = new Action(() =>
|
||||
{
|
||||
|
@ -55,11 +55,11 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
process.Raise(p => p.Terminated += null, 0);
|
||||
});
|
||||
|
||||
session.SetupGet(s => s.AppConfig).Returns(appConfig);
|
||||
session.AppConfig = appConfig;
|
||||
sessionContext.ClientProcess = process.Object;
|
||||
sessionContext.ClientProxy = proxy.Object;
|
||||
sessionContext.Current = session.Object;
|
||||
sessionContext.Next = session.Object;
|
||||
sessionContext.Current = session;
|
||||
sessionContext.Next = session;
|
||||
proxyFactory.Setup(f => f.CreateClientProxy(It.IsAny<string>())).Returns(proxy.Object);
|
||||
|
||||
sut = new ClientTerminationOperation(logger.Object, processFactory.Object, proxyFactory.Object, runtimeHost.Object, sessionContext, 0);
|
||||
|
|
|
@ -30,8 +30,8 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
private Mock<IHashAlgorithm> hashAlgorithm;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<IConfigurationRepository> repository;
|
||||
private Mock<ISessionConfiguration> currentSession;
|
||||
private Mock<ISessionConfiguration> nextSession;
|
||||
private SessionConfiguration currentSession;
|
||||
private SessionConfiguration nextSession;
|
||||
private SessionContext sessionContext;
|
||||
|
||||
[TestInitialize]
|
||||
|
@ -41,16 +41,16 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
hashAlgorithm = new Mock<IHashAlgorithm>();
|
||||
logger = new Mock<ILogger>();
|
||||
repository = new Mock<IConfigurationRepository>();
|
||||
currentSession = new Mock<ISessionConfiguration>();
|
||||
nextSession = new Mock<ISessionConfiguration>();
|
||||
currentSession = new SessionConfiguration();
|
||||
nextSession = new SessionConfiguration();
|
||||
sessionContext = new SessionContext();
|
||||
|
||||
appConfig.AppDataFilePath = $@"C:\Not\Really\AppData\File.xml";
|
||||
appConfig.ProgramDataFilePath = $@"C:\Not\Really\ProgramData\File.xml";
|
||||
currentSession.SetupGet(s => s.AppConfig).Returns(appConfig);
|
||||
nextSession.SetupGet(s => s.AppConfig).Returns(appConfig);
|
||||
sessionContext.Current = currentSession.Object;
|
||||
sessionContext.Next = nextSession.Object;
|
||||
currentSession.AppConfig = appConfig;
|
||||
nextSession.AppConfig = appConfig;
|
||||
sessionContext.Current = currentSession;
|
||||
sessionContext.Next = nextSession;
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -112,7 +112,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
var settings = new Settings { ConfigurationMode = ConfigurationMode.Exam };
|
||||
var url = @"http://www.safeexambrowser.org/whatever.seb";
|
||||
|
||||
nextSession.SetupGet(s => s.Settings).Returns(settings);
|
||||
nextSession.Settings = settings;
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.LoadWithBrowser);
|
||||
|
||||
var sut = new ConfigurationOperation(new[] { "blubb.exe", url }, repository.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
|
@ -125,20 +125,17 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
[TestMethod]
|
||||
public void Perform_MustFallbackToDefaultsAsLastPrio()
|
||||
{
|
||||
var actualSettings = default(Settings);
|
||||
var defaultSettings = new Settings();
|
||||
|
||||
repository.Setup(r => r.LoadDefaultSettings()).Returns(defaultSettings);
|
||||
nextSession.SetupSet<Settings>(s => s.Settings = It.IsAny<Settings>()).Callback(s => actualSettings = s);
|
||||
|
||||
var sut = new ConfigurationOperation(null, repository.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
var result = sut.Perform();
|
||||
|
||||
repository.Verify(r => r.LoadDefaultSettings(), Times.Once);
|
||||
nextSession.VerifySet(s => s.Settings = defaultSettings);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreSame(defaultSettings, actualSettings);
|
||||
Assert.AreSame(defaultSettings, nextSession.Settings);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -241,26 +238,24 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
[TestMethod]
|
||||
public void Perform_MustNotFailWithoutCommandLineArgs()
|
||||
{
|
||||
var actualSettings = default(Settings);
|
||||
var defaultSettings = new Settings();
|
||||
var result = OperationResult.Failed;
|
||||
|
||||
repository.Setup(r => r.LoadDefaultSettings()).Returns(defaultSettings);
|
||||
nextSession.SetupSet<Settings>(s => s.Settings = It.IsAny<Settings>()).Callback(s => actualSettings = s);
|
||||
|
||||
var sut = new ConfigurationOperation(null, repository.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
result = sut.Perform();
|
||||
|
||||
repository.Verify(r => r.LoadDefaultSettings(), Times.Once);
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreSame(defaultSettings, actualSettings);
|
||||
Assert.AreSame(defaultSettings, nextSession.Settings);
|
||||
|
||||
sut = new ConfigurationOperation(new string[] { }, repository.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
result = sut.Perform();
|
||||
|
||||
repository.Verify(r => r.LoadDefaultSettings(), Times.Exactly(2));
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreSame(defaultSettings, actualSettings);
|
||||
Assert.AreSame(defaultSettings, nextSession.Settings);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -285,7 +280,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
repository.Setup(r => r.TryLoadSettings(It.Is<Uri>(u => u.LocalPath.Contains(FILE_NAME)), out localSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
nextSession.SetupGet(s => s.Settings).Returns(settings);
|
||||
nextSession.Settings = settings;
|
||||
|
||||
var sut = new ConfigurationOperation(new[] { "blubb.exe", url }, repository.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
sut.ActionRequired += args =>
|
||||
|
@ -338,7 +333,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
var nextSettings = new Settings { AdminPasswordHash = "9876", ConfigurationMode = ConfigurationMode.ConfigureClient };
|
||||
var url = @"http://www.safeexambrowser.org/whatever.seb";
|
||||
|
||||
nextSession.SetupGet(s => s.Settings).Returns(nextSettings);
|
||||
nextSession.Settings = nextSettings;
|
||||
hashAlgorithm.Setup(h => h.GenerateHashFor(It.Is<string>(p => p == password))).Returns(currentSettings.AdminPasswordHash);
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out currentSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
repository.Setup(r => r.TryLoadSettings(It.Is<Uri>(u => u.AbsoluteUri == url), out nextSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
|
@ -368,7 +363,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
var nextSettings = new Settings { AdminPasswordHash = "1234", ConfigurationMode = ConfigurationMode.ConfigureClient };
|
||||
var url = @"http://www.safeexambrowser.org/whatever.seb";
|
||||
|
||||
nextSession.SetupGet(s => s.Settings).Returns(nextSettings);
|
||||
nextSession.Settings = nextSettings;
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out currentSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
repository.Setup(r => r.TryLoadSettings(It.Is<Uri>(u => u.AbsoluteUri == url), out nextSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
repository.Setup(r => r.ConfigureClientWith(It.IsAny<Uri>(), It.IsAny<PasswordParameters>())).Returns(SaveStatus.Success);
|
||||
|
@ -452,7 +447,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
var url = @"http://www.safeexambrowser.org/whatever.seb";
|
||||
|
||||
appConfig.AppDataFilePath = Path.Combine(Path.GetDirectoryName(GetType().Assembly.Location), nameof(Operations), "Testdata", FILE_NAME);
|
||||
nextSession.SetupGet(s => s.Settings).Returns(nextSettings);
|
||||
nextSession.Settings = nextSettings;
|
||||
|
||||
hashAlgorithm.Setup(h => h.GenerateHashFor(It.Is<string>(p => p == password))).Returns(currentSettings.AdminPasswordHash);
|
||||
repository.Setup(r => r.TryLoadSettings(It.IsAny<Uri>(), out currentSettings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
|
@ -504,14 +499,13 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
var resource = new Uri(Path.Combine(location, nameof(Operations), "Testdata", FILE_NAME));
|
||||
var settings = new Settings { ConfigurationMode = ConfigurationMode.Exam };
|
||||
|
||||
currentSession.SetupGet(s => s.Settings).Returns(currentSettings);
|
||||
currentSession.Settings = currentSettings;
|
||||
sessionContext.ReconfigurationFilePath = resource.LocalPath;
|
||||
repository.Setup(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(resource)), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
|
||||
var sut = new ConfigurationOperation(null, repository.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
var result = sut.Repeat();
|
||||
|
||||
nextSession.VerifySet(s => s.Settings = settings, Times.Once);
|
||||
repository.Verify(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(resource)), out settings, It.IsAny<PasswordParameters>()), Times.AtLeastOnce);
|
||||
repository.Verify(r => r.ConfigureClientWith(It.Is<Uri>(u => u.Equals(resource)), It.IsAny<PasswordParameters>()), Times.Never);
|
||||
|
||||
|
@ -526,7 +520,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
var resource = new Uri(Path.Combine(location, nameof(Operations), "Testdata", FILE_NAME));
|
||||
var settings = new Settings { ConfigurationMode = ConfigurationMode.ConfigureClient };
|
||||
|
||||
currentSession.SetupGet(s => s.Settings).Returns(currentSettings);
|
||||
currentSession.Settings = currentSettings;
|
||||
sessionContext.ReconfigurationFilePath = resource.LocalPath;
|
||||
repository.Setup(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(resource)), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.Success);
|
||||
repository.Setup(r => r.ConfigureClientWith(It.Is<Uri>(u => u.Equals(resource)), It.IsAny<PasswordParameters>())).Returns(SaveStatus.Success);
|
||||
|
@ -534,7 +528,6 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
var sut = new ConfigurationOperation(null, repository.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
var result = sut.Repeat();
|
||||
|
||||
nextSession.VerifySet(s => s.Settings = settings, Times.Once);
|
||||
repository.Verify(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(resource)), out settings, It.IsAny<PasswordParameters>()), Times.AtLeastOnce);
|
||||
repository.Verify(r => r.ConfigureClientWith(It.Is<Uri>(u => u.Equals(resource)), It.IsAny<PasswordParameters>()), Times.Once);
|
||||
|
||||
|
@ -571,7 +564,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
var resource = new Uri(Path.Combine(location, nameof(Operations), "Testdata", FILE_NAME));
|
||||
var settings = new Settings { ConfigurationMode = ConfigurationMode.ConfigureClient };
|
||||
|
||||
currentSession.SetupGet(s => s.Settings).Returns(currentSettings);
|
||||
currentSession.Settings = currentSettings;
|
||||
sessionContext.ReconfigurationFilePath = resource.LocalPath;
|
||||
repository.Setup(r => r.TryLoadSettings(It.Is<Uri>(u => u.Equals(resource)), out settings, It.IsAny<PasswordParameters>())).Returns(LoadStatus.PasswordNeeded);
|
||||
|
||||
|
@ -590,14 +583,12 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Rever_MustDoNothing()
|
||||
public void Revert_MustDoNothing()
|
||||
{
|
||||
var sut = new ConfigurationOperation(null, repository.Object, hashAlgorithm.Object, logger.Object, sessionContext);
|
||||
var result = sut.Revert();
|
||||
|
||||
currentSession.VerifyNoOtherCalls();
|
||||
hashAlgorithm.VerifyNoOtherCalls();
|
||||
nextSession.VerifyNoOtherCalls();
|
||||
repository.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
|
|
|
@ -20,12 +20,12 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
[TestClass]
|
||||
public class KioskModeOperationTests
|
||||
{
|
||||
private Mock<ISessionConfiguration> currentSession;
|
||||
private SessionConfiguration currentSession;
|
||||
private Settings currentSettings;
|
||||
private Mock<IDesktopFactory> desktopFactory;
|
||||
private Mock<IExplorerShell> explorerShell;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<ISessionConfiguration> nextSession;
|
||||
private SessionConfiguration nextSession;
|
||||
private Settings nextSettings;
|
||||
private Mock<IProcessFactory> processFactory;
|
||||
private SessionContext sessionContext;
|
||||
|
@ -35,20 +35,20 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
currentSession = new Mock<ISessionConfiguration>();
|
||||
currentSession = new SessionConfiguration();
|
||||
currentSettings = new Settings();
|
||||
desktopFactory = new Mock<IDesktopFactory>();
|
||||
explorerShell = new Mock<IExplorerShell>();
|
||||
logger = new Mock<ILogger>();
|
||||
nextSession = new Mock<ISessionConfiguration>();
|
||||
nextSession = new SessionConfiguration();
|
||||
nextSettings = new Settings();
|
||||
processFactory = new Mock<IProcessFactory>();
|
||||
sessionContext = new SessionContext();
|
||||
|
||||
currentSession.SetupGet(s => s.Settings).Returns(currentSettings);
|
||||
nextSession.SetupGet(s => s.Settings).Returns(nextSettings);
|
||||
sessionContext.Current = currentSession.Object;
|
||||
sessionContext.Next = nextSession.Object;
|
||||
currentSession.Settings = currentSettings;
|
||||
nextSession.Settings = nextSettings;
|
||||
sessionContext.Current = currentSession;
|
||||
sessionContext.Next = nextSession;
|
||||
|
||||
sut = new KioskModeOperation(desktopFactory.Object, explorerShell.Object, logger.Object, processFactory.Object, sessionContext);
|
||||
}
|
||||
|
|
|
@ -23,32 +23,32 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
private Mock<IDesktopFactory> desktopFactory;
|
||||
private Mock<IExplorerShell> explorerShell;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<ISessionConfiguration> nextSession;
|
||||
private SessionConfiguration nextSession;
|
||||
private Settings nextSettings;
|
||||
private Mock<IProcessFactory> processFactory;
|
||||
private SessionContext sessionContext;
|
||||
|
||||
private KioskModeTerminationOperation sut;
|
||||
private Mock<ISessionConfiguration> currentSession;
|
||||
private SessionConfiguration currentSession;
|
||||
private Settings currentSettings;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
currentSession = new Mock<ISessionConfiguration>();
|
||||
currentSession = new SessionConfiguration();
|
||||
currentSettings = new Settings();
|
||||
desktopFactory = new Mock<IDesktopFactory>();
|
||||
explorerShell = new Mock<IExplorerShell>();
|
||||
logger = new Mock<ILogger>();
|
||||
nextSession = new Mock<ISessionConfiguration>();
|
||||
nextSession = new SessionConfiguration();
|
||||
nextSettings = new Settings();
|
||||
processFactory = new Mock<IProcessFactory>();
|
||||
sessionContext = new SessionContext();
|
||||
|
||||
currentSession.SetupGet(s => s.Settings).Returns(currentSettings);
|
||||
nextSession.SetupGet(s => s.Settings).Returns(nextSettings);
|
||||
sessionContext.Current = currentSession.Object;
|
||||
sessionContext.Next = nextSession.Object;
|
||||
currentSession.Settings = currentSettings;
|
||||
nextSession.Settings = nextSettings;
|
||||
sessionContext.Current = currentSession;
|
||||
sessionContext.Next = nextSession;
|
||||
|
||||
sut = new KioskModeTerminationOperation(desktopFactory.Object, explorerShell.Object, logger.Object, processFactory.Object, sessionContext);
|
||||
}
|
||||
|
@ -58,11 +58,9 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
{
|
||||
var result = sut.Perform();
|
||||
|
||||
currentSession.VerifyNoOtherCalls();
|
||||
desktopFactory.VerifyNoOtherCalls();
|
||||
explorerShell.VerifyNoOtherCalls();
|
||||
logger.VerifyNoOtherCalls();
|
||||
nextSession.VerifyNoOtherCalls();
|
||||
processFactory.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
|
@ -178,11 +176,9 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
{
|
||||
var result = sut.Revert();
|
||||
|
||||
currentSession.VerifyNoOtherCalls();
|
||||
desktopFactory.VerifyNoOtherCalls();
|
||||
explorerShell.VerifyNoOtherCalls();
|
||||
logger.VerifyNoOtherCalls();
|
||||
nextSession.VerifyNoOtherCalls();
|
||||
processFactory.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
private Mock<ILogger> logger;
|
||||
private Mock<IRuntimeHost> runtimeHost;
|
||||
private Mock<IServiceProxy> service;
|
||||
private Mock<ISessionConfiguration> session;
|
||||
private SessionConfiguration session;
|
||||
private SessionContext sessionContext;
|
||||
private Settings settings;
|
||||
private ServiceOperation sut;
|
||||
|
@ -36,13 +36,13 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
logger = new Mock<ILogger>();
|
||||
runtimeHost = new Mock<IRuntimeHost>();
|
||||
service = new Mock<IServiceProxy>();
|
||||
session = new Mock<ISessionConfiguration>();
|
||||
session = new SessionConfiguration();
|
||||
sessionContext = new SessionContext();
|
||||
settings = new Settings();
|
||||
|
||||
sessionContext.Current = session.Object;
|
||||
sessionContext.Next = session.Object;
|
||||
session.SetupGet(s => s.Settings).Returns(settings);
|
||||
sessionContext.Current = session;
|
||||
sessionContext.Next = session;
|
||||
session.Settings = settings;
|
||||
settings.ServicePolicy = ServicePolicy.Mandatory;
|
||||
|
||||
sut = new ServiceOperation(logger.Object, runtimeHost.Object, service.Object, sessionContext, 0);
|
||||
|
@ -70,13 +70,13 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
service.SetupGet(s => s.IsConnected).Returns(true);
|
||||
service.Setup(s => s.Connect(null, true)).Returns(true);
|
||||
service
|
||||
.Setup(s => s.StartSession(It.IsAny<Guid>(), It.IsAny<Settings>()))
|
||||
.Setup(s => s.StartSession(It.IsAny<ServiceConfiguration>()))
|
||||
.Returns(new CommunicationResult(true))
|
||||
.Callback(() => runtimeHost.Raise(h => h.ServiceSessionStarted += null));
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
service.Verify(s => s.StartSession(It.IsAny<Guid>(), It.IsAny<Settings>()), Times.Once);
|
||||
service.Verify(s => s.StartSession(It.IsAny<ServiceConfiguration>()), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
|
@ -87,13 +87,13 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
service.SetupGet(s => s.IsConnected).Returns(true);
|
||||
service.Setup(s => s.Connect(null, true)).Returns(true);
|
||||
service
|
||||
.Setup(s => s.StartSession(It.IsAny<Guid>(), It.IsAny<Settings>()))
|
||||
.Setup(s => s.StartSession(It.IsAny<ServiceConfiguration>()))
|
||||
.Returns(new CommunicationResult(true))
|
||||
.Callback(() => runtimeHost.Raise(h => h.ServiceFailed += null));
|
||||
|
||||
var result = sut.Perform();
|
||||
|
||||
service.Verify(s => s.StartSession(It.IsAny<Guid>(), It.IsAny<Settings>()), Times.Once);
|
||||
service.Verify(s => s.StartSession(It.IsAny<ServiceConfiguration>()), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
|
||||
service.SetupGet(s => s.IsConnected).Returns(true);
|
||||
service.Setup(s => s.Connect(null, true)).Returns(true);
|
||||
service.Setup(s => s.StartSession(It.IsAny<Guid>(), It.IsAny<Settings>())).Returns(new CommunicationResult(true));
|
||||
service.Setup(s => s.StartSession(It.IsAny<ServiceConfiguration>())).Returns(new CommunicationResult(true));
|
||||
|
||||
sut = new ServiceOperation(logger.Object, runtimeHost.Object, service.Object, sessionContext, TIMEOUT);
|
||||
|
||||
|
@ -116,7 +116,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
var result = sut.Perform();
|
||||
after = DateTime.Now;
|
||||
|
||||
service.Verify(s => s.StartSession(It.IsAny<Guid>(), It.IsAny<Settings>()), Times.Once);
|
||||
service.Verify(s => s.StartSession(It.IsAny<ServiceConfiguration>()), Times.Once);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
Assert.IsTrue(after - before >= new TimeSpan(0, 0, 0, 0, TIMEOUT));
|
||||
|
@ -130,7 +130,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
|
||||
sut.Perform();
|
||||
|
||||
service.Verify(s => s.StartSession(It.IsAny<Guid>(), It.IsAny<Settings>()), Times.Never);
|
||||
service.Verify(s => s.StartSession(It.IsAny<ServiceConfiguration>()), Times.Never);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -172,7 +172,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
|
||||
service.Verify(s => s.Connect(It.IsAny<Guid?>(), It.IsAny<bool>()), Times.Once);
|
||||
service.Verify(s => s.StopSession(It.IsAny<Guid>()), Times.Once);
|
||||
service.Verify(s => s.StartSession(It.IsAny<Guid>(), It.IsAny<Settings>()), Times.Exactly(2));
|
||||
service.Verify(s => s.StartSession(It.IsAny<ServiceConfiguration>()), Times.Exactly(2));
|
||||
service.Verify(s => s.Disconnect(), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
|
@ -188,7 +188,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
var result = sut.Repeat();
|
||||
|
||||
service.Verify(s => s.StopSession(It.IsAny<Guid>()), Times.Once);
|
||||
service.Verify(s => s.StartSession(It.IsAny<Guid>(), It.IsAny<Settings>()), Times.Once);
|
||||
service.Verify(s => s.StartSession(It.IsAny<ServiceConfiguration>()), Times.Once);
|
||||
service.Verify(s => s.Disconnect(), Times.Never);
|
||||
|
||||
Assert.AreEqual(OperationResult.Failed, result);
|
||||
|
@ -320,7 +320,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
service.SetupGet(s => s.IsConnected).Returns(true);
|
||||
service.Setup(s => s.Connect(null, true)).Returns(true);
|
||||
service
|
||||
.Setup(s => s.StartSession(It.IsAny<Guid>(), It.IsAny<Settings>()))
|
||||
.Setup(s => s.StartSession(It.IsAny<ServiceConfiguration>()))
|
||||
.Returns(new CommunicationResult(true))
|
||||
.Callback(() => runtimeHost.Raise(h => h.ServiceSessionStarted += null));
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
[TestClass]
|
||||
public class SessionActivationOperationTests
|
||||
{
|
||||
private Mock<ISessionConfiguration> currentSession;
|
||||
private SessionConfiguration currentSession;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<ISessionConfiguration> nextSession;
|
||||
private SessionConfiguration nextSession;
|
||||
private Settings nextSettings;
|
||||
private SessionContext sessionContext;
|
||||
|
||||
|
@ -30,15 +30,15 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
currentSession = new Mock<ISessionConfiguration>();
|
||||
currentSession = new SessionConfiguration();
|
||||
logger = new Mock<ILogger>();
|
||||
nextSession = new Mock<ISessionConfiguration>();
|
||||
nextSession = new SessionConfiguration();
|
||||
nextSettings = new Settings();
|
||||
sessionContext = new SessionContext();
|
||||
|
||||
nextSession.SetupGet(s => s.Settings).Returns(nextSettings);
|
||||
sessionContext.Current = currentSession.Object;
|
||||
sessionContext.Next = nextSession.Object;
|
||||
nextSession.Settings = nextSettings;
|
||||
sessionContext.Current = currentSession;
|
||||
sessionContext.Next = nextSession;
|
||||
|
||||
sut = new SessionActivationOperation(logger.Object, sessionContext);
|
||||
}
|
||||
|
@ -50,11 +50,8 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
|
||||
var result = sut.Perform();
|
||||
|
||||
currentSession.VerifyNoOtherCalls();
|
||||
nextSession.VerifyGet(s => s.Id);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreSame(sessionContext.Current, nextSession.Object);
|
||||
Assert.AreSame(sessionContext.Current, nextSession);
|
||||
Assert.IsNull(sessionContext.Next);
|
||||
}
|
||||
|
||||
|
@ -73,11 +70,8 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
{
|
||||
var result = sut.Repeat();
|
||||
|
||||
currentSession.VerifyGet(s => s.Id);
|
||||
nextSession.VerifyGet(s => s.Id);
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
Assert.AreSame(sessionContext.Current, nextSession.Object);
|
||||
Assert.AreSame(sessionContext.Current, nextSession);
|
||||
Assert.IsNull(sessionContext.Next);
|
||||
}
|
||||
|
||||
|
@ -96,9 +90,6 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
{
|
||||
var result = sut.Revert();
|
||||
|
||||
currentSession.VerifyNoOtherCalls();
|
||||
nextSession.VerifyNoOtherCalls();
|
||||
|
||||
Assert.AreEqual(OperationResult.Success, result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
private Mock<IConfigurationRepository> configuration;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<IRuntimeHost> runtimeHost;
|
||||
private Mock<ISessionConfiguration> session;
|
||||
private SessionConfiguration session;
|
||||
private SessionContext sessionContext;
|
||||
|
||||
private SessionInitializationOperation sut;
|
||||
|
@ -35,12 +35,12 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
configuration = new Mock<IConfigurationRepository>();
|
||||
logger = new Mock<ILogger>();
|
||||
runtimeHost = new Mock<IRuntimeHost>();
|
||||
session = new Mock<ISessionConfiguration>();
|
||||
session = new SessionConfiguration();
|
||||
sessionContext = new SessionContext();
|
||||
|
||||
configuration.Setup(c => c.InitializeSessionConfiguration()).Returns(session.Object);
|
||||
session.SetupGet(s => s.AppConfig).Returns(appConfig);
|
||||
sessionContext.Next = session.Object;
|
||||
configuration.Setup(c => c.InitializeSessionConfiguration()).Returns(session);
|
||||
session.AppConfig = appConfig;
|
||||
sessionContext.Next = session;
|
||||
|
||||
sut = new SessionInitializationOperation(configuration.Object, logger.Object, runtimeHost.Object, sessionContext);
|
||||
}
|
||||
|
@ -50,12 +50,12 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
{
|
||||
var token = Guid.NewGuid();
|
||||
|
||||
session.SetupGet(s => s.StartupToken).Returns(token);
|
||||
session.ClientAuthenticationToken = token;
|
||||
|
||||
sut.Perform();
|
||||
|
||||
configuration.Verify(c => c.InitializeSessionConfiguration(), Times.Once);
|
||||
runtimeHost.VerifySet(r => r.StartupToken = token, Times.Once);
|
||||
runtimeHost.VerifySet(r => r.AuthenticationToken = token, Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
@ -63,12 +63,12 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
|
|||
{
|
||||
var token = Guid.NewGuid();
|
||||
|
||||
session.SetupGet(s => s.StartupToken).Returns(token);
|
||||
session.ClientAuthenticationToken = token;
|
||||
|
||||
sut.Repeat();
|
||||
|
||||
configuration.Verify(c => c.InitializeSessionConfiguration(), Times.Once);
|
||||
runtimeHost.VerifySet(r => r.StartupToken = token, Times.Once);
|
||||
runtimeHost.VerifySet(r => r.AuthenticationToken = token, Times.Once);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
|
|
@ -34,11 +34,11 @@ namespace SafeExamBrowser.Runtime.UnitTests
|
|||
private Mock<IOperationSequence> bootstrapSequence;
|
||||
private Mock<IProcess> clientProcess;
|
||||
private Mock<IClientProxy> clientProxy;
|
||||
private Mock<ISessionConfiguration> currentSession;
|
||||
private SessionConfiguration currentSession;
|
||||
private Settings currentSettings;
|
||||
private Mock<ILogger> logger;
|
||||
private Mock<IMessageBox> messageBox;
|
||||
private Mock<ISessionConfiguration> nextSession;
|
||||
private SessionConfiguration nextSession;
|
||||
private Settings nextSettings;
|
||||
private Mock<Action> shutdown;
|
||||
private Mock<IText> text;
|
||||
|
@ -56,11 +56,11 @@ namespace SafeExamBrowser.Runtime.UnitTests
|
|||
bootstrapSequence = new Mock<IOperationSequence>();
|
||||
clientProcess = new Mock<IProcess>();
|
||||
clientProxy = new Mock<IClientProxy>();
|
||||
currentSession = new Mock<ISessionConfiguration>();
|
||||
currentSession = new SessionConfiguration();
|
||||
currentSettings = new Settings();
|
||||
logger = new Mock<ILogger>();
|
||||
messageBox = new Mock<IMessageBox>();
|
||||
nextSession = new Mock<ISessionConfiguration>();
|
||||
nextSession = new SessionConfiguration();
|
||||
nextSettings = new Settings();
|
||||
runtimeHost = new Mock<IRuntimeHost>();
|
||||
service = new Mock<IServiceProxy>();
|
||||
|
@ -70,13 +70,13 @@ namespace SafeExamBrowser.Runtime.UnitTests
|
|||
text = new Mock<IText>();
|
||||
uiFactory = new Mock<IUserInterfaceFactory>();
|
||||
|
||||
currentSession.SetupGet(s => s.Settings).Returns(currentSettings);
|
||||
nextSession.SetupGet(s => s.Settings).Returns(nextSettings);
|
||||
currentSession.Settings = currentSettings;
|
||||
nextSession.Settings = nextSettings;
|
||||
|
||||
sessionContext.ClientProcess = clientProcess.Object;
|
||||
sessionContext.ClientProxy = clientProxy.Object;
|
||||
sessionContext.Current = currentSession.Object;
|
||||
sessionContext.Next = nextSession.Object;
|
||||
sessionContext.Current = currentSession;
|
||||
sessionContext.Next = nextSession;
|
||||
|
||||
uiFactory.Setup(u => u.CreateRuntimeWindow(It.IsAny<AppConfig>())).Returns(new Mock<IRuntimeWindow>().Object);
|
||||
uiFactory.Setup(u => u.CreateSplashScreen(It.IsAny<AppConfig>())).Returns(new Mock<ISplashScreen>().Object);
|
||||
|
@ -135,9 +135,9 @@ namespace SafeExamBrowser.Runtime.UnitTests
|
|||
var nextSessionId = Guid.NewGuid();
|
||||
var nextSettings = new Settings();
|
||||
|
||||
nextSession.SetupGet(s => s.AppConfig).Returns(nextAppConfig);
|
||||
nextSession.SetupGet(s => s.Id).Returns(nextSessionId);
|
||||
nextSession.SetupGet(s => s.Settings).Returns(nextSettings);
|
||||
nextSession.AppConfig = nextAppConfig;
|
||||
nextSession.SessionId = nextSessionId;
|
||||
nextSession.Settings = nextSettings;
|
||||
StartSession();
|
||||
|
||||
runtimeHost.Raise(r => r.ClientConfigurationNeeded += null, args);
|
||||
|
@ -472,7 +472,7 @@ namespace SafeExamBrowser.Runtime.UnitTests
|
|||
var session = 0;
|
||||
|
||||
bootstrapSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success).Callback(() => bootstrap = ++order);
|
||||
sessionSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success).Callback(() => { session = ++order; sessionContext.Current = currentSession.Object; });
|
||||
sessionSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success).Callback(() => { session = ++order; sessionContext.Current = currentSession; });
|
||||
sessionContext.Current = null;
|
||||
|
||||
var success = sut.TryStart();
|
||||
|
@ -496,7 +496,7 @@ namespace SafeExamBrowser.Runtime.UnitTests
|
|||
var session = 0;
|
||||
|
||||
bootstrapSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Failed).Callback(() => bootstrap = ++order);
|
||||
sessionSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success).Callback(() => { session = ++order; sessionContext.Current = currentSession.Object; });
|
||||
sessionSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success).Callback(() => { session = ++order; sessionContext.Current = currentSession; });
|
||||
sessionContext.Current = null;
|
||||
|
||||
var success = sut.TryStart();
|
||||
|
@ -516,7 +516,7 @@ namespace SafeExamBrowser.Runtime.UnitTests
|
|||
public void Startup_MustTerminateOnSessionStartFailure()
|
||||
{
|
||||
bootstrapSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success);
|
||||
sessionSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Failed).Callback(() => sessionContext.Current = currentSession.Object);
|
||||
sessionSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Failed).Callback(() => sessionContext.Current = currentSession);
|
||||
sessionContext.Current = null;
|
||||
|
||||
var success = sut.TryStart();
|
||||
|
@ -534,7 +534,7 @@ namespace SafeExamBrowser.Runtime.UnitTests
|
|||
public void Startup_MustNotTerminateOnSessionStartAbortion()
|
||||
{
|
||||
bootstrapSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success);
|
||||
sessionSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Aborted).Callback(() => sessionContext.Current = currentSession.Object);
|
||||
sessionSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Aborted).Callback(() => sessionContext.Current = currentSession);
|
||||
sessionContext.Current = null;
|
||||
|
||||
var success = sut.TryStart();
|
||||
|
@ -551,7 +551,7 @@ namespace SafeExamBrowser.Runtime.UnitTests
|
|||
private void StartSession()
|
||||
{
|
||||
bootstrapSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success);
|
||||
sessionSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success).Callback(() => sessionContext.Current = currentSession.Object);
|
||||
sessionSequence.Setup(b => b.TryPerform()).Returns(OperationResult.Success).Callback(() => sessionContext.Current = currentSession);
|
||||
sessionContext.Current = null;
|
||||
|
||||
sut.TryStart();
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace SafeExamBrowser.Runtime.Communication
|
|||
internal class RuntimeHost : BaseHost, IRuntimeHost
|
||||
{
|
||||
public bool AllowConnection { get; set; }
|
||||
public Guid StartupToken { private get; set; }
|
||||
public Guid AuthenticationToken { private get; set; }
|
||||
|
||||
public event CommunicationEventHandler ClientDisconnected;
|
||||
public event CommunicationEventHandler ClientReady;
|
||||
|
@ -38,7 +38,7 @@ namespace SafeExamBrowser.Runtime.Communication
|
|||
|
||||
protected override bool OnConnect(Guid? token = null)
|
||||
{
|
||||
var authenticated = StartupToken == token;
|
||||
var authenticated = AuthenticationToken == token;
|
||||
var accepted = AllowConnection && authenticated;
|
||||
|
||||
if (accepted)
|
||||
|
|
|
@ -95,11 +95,11 @@ namespace SafeExamBrowser.Runtime.Operations
|
|||
|
||||
private bool TryStartClient()
|
||||
{
|
||||
var clientExecutable = Context.Next.AppConfig.ClientExecutablePath;
|
||||
var clientLogFile = $"{'"' + Context.Next.AppConfig.ClientLogFilePath + '"'}";
|
||||
var clientLogLevel = Context.Next.Settings.LogLevel.ToString();
|
||||
var authenticationToken = Context.Next.ClientAuthenticationToken.ToString("D");
|
||||
var executablePath = Context.Next.AppConfig.ClientExecutablePath;
|
||||
var logFilePath = $"{'"' + Context.Next.AppConfig.ClientLogFilePath + '"'}";
|
||||
var logLevel = Context.Next.Settings.LogLevel.ToString();
|
||||
var runtimeHostUri = Context.Next.AppConfig.RuntimeAddress;
|
||||
var startupToken = Context.Next.StartupToken.ToString("D");
|
||||
var uiMode = Context.Next.Settings.UserInterfaceMode.ToString();
|
||||
|
||||
var clientReady = false;
|
||||
|
@ -112,7 +112,7 @@ namespace SafeExamBrowser.Runtime.Operations
|
|||
logger.Info("Starting new client process...");
|
||||
runtimeHost.AllowConnection = true;
|
||||
runtimeHost.ClientReady += clientReadyEventHandler;
|
||||
ClientProcess = processFactory.StartNew(clientExecutable, clientLogFile, clientLogLevel, runtimeHostUri, startupToken, uiMode);
|
||||
ClientProcess = processFactory.StartNew(executablePath, logFilePath, logLevel, runtimeHostUri, authenticationToken, uiMode);
|
||||
ClientProcess.Terminated += clientTerminatedEventHandler;
|
||||
|
||||
logger.Info("Waiting for client to complete initialization...");
|
||||
|
@ -147,7 +147,7 @@ namespace SafeExamBrowser.Runtime.Operations
|
|||
logger.Info("Client has been successfully started and initialized. Creating communication proxy for client host...");
|
||||
ClientProxy = proxyFactory.CreateClientProxy(Context.Next.AppConfig.ClientAddress);
|
||||
|
||||
if (ClientProxy.Connect(Context.Next.StartupToken))
|
||||
if (ClientProxy.Connect(Context.Next.ClientAuthenticationToken))
|
||||
{
|
||||
logger.Info("Connection with client has been established. Requesting authentication...");
|
||||
|
||||
|
|
|
@ -10,11 +10,14 @@ using System.Threading;
|
|||
using SafeExamBrowser.Contracts.Communication.Events;
|
||||
using SafeExamBrowser.Contracts.Communication.Hosts;
|
||||
using SafeExamBrowser.Contracts.Communication.Proxies;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||
using SafeExamBrowser.Contracts.Core.OperationModel;
|
||||
using SafeExamBrowser.Contracts.Core.OperationModel.Events;
|
||||
using SafeExamBrowser.Contracts.I18n;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.UserInterface.MessageBox;
|
||||
using SafeExamBrowser.Runtime.Operations.Events;
|
||||
|
||||
namespace SafeExamBrowser.Runtime.Operations
|
||||
{
|
||||
|
@ -25,7 +28,7 @@ namespace SafeExamBrowser.Runtime.Operations
|
|||
private IServiceProxy service;
|
||||
private int timeout_ms;
|
||||
|
||||
public override event ActionRequiredEventHandler ActionRequired { add { } remove { } }
|
||||
public override event ActionRequiredEventHandler ActionRequired;
|
||||
public override event StatusChangedEventHandler StatusChanged;
|
||||
|
||||
public ServiceOperation(
|
||||
|
@ -99,6 +102,7 @@ namespace SafeExamBrowser.Runtime.Operations
|
|||
private bool TryEstablishConnection()
|
||||
{
|
||||
var mandatory = Context.Next.Settings.ServicePolicy == ServicePolicy.Mandatory;
|
||||
var warn = Context.Next.Settings.ServicePolicy == ServicePolicy.Warn;
|
||||
var connected = service.Connect();
|
||||
var success = connected || !mandatory;
|
||||
|
||||
|
@ -106,10 +110,26 @@ namespace SafeExamBrowser.Runtime.Operations
|
|||
{
|
||||
service.Ignore = !connected;
|
||||
logger.Info($"The service is {(mandatory ? "mandatory" : "optional")} and {(connected ? "connected." : "not connected. All service-related operations will be ignored!")}");
|
||||
|
||||
if (!connected && warn)
|
||||
{
|
||||
ActionRequired?.Invoke(new MessageEventArgs
|
||||
{
|
||||
Icon = MessageBoxIcon.Warning,
|
||||
Message = TextKey.MessageBox_ServiceUnavailableWarning,
|
||||
Title = TextKey.MessageBox_ServiceUnavailableWarningTitle
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error("The service is mandatory but no connection could be established!");
|
||||
ActionRequired?.Invoke(new MessageEventArgs
|
||||
{
|
||||
Icon = MessageBoxIcon.Error,
|
||||
Message = TextKey.MessageBox_ServiceUnavailableError,
|
||||
Title = TextKey.MessageBox_ServiceUnavailableErrorTitle
|
||||
});
|
||||
}
|
||||
|
||||
return success;
|
||||
|
@ -151,6 +171,13 @@ namespace SafeExamBrowser.Runtime.Operations
|
|||
|
||||
private bool TryStartSession()
|
||||
{
|
||||
var configuration = new ServiceConfiguration
|
||||
{
|
||||
AppConfig = Context.Next.AppConfig,
|
||||
AuthenticationToken = Context.Next.ServiceAuthenticationToken,
|
||||
SessionId = Context.Next.SessionId,
|
||||
Settings = Context.Next.Settings
|
||||
};
|
||||
var failure = false;
|
||||
var success = false;
|
||||
var serviceEvent = new AutoResetEvent(false);
|
||||
|
@ -162,7 +189,7 @@ namespace SafeExamBrowser.Runtime.Operations
|
|||
|
||||
logger.Info("Starting new service session...");
|
||||
|
||||
var communication = service.StartSession(Context.Next.Id, Context.Next.Settings);
|
||||
var communication = service.StartSession(configuration);
|
||||
|
||||
if (communication.Success)
|
||||
{
|
||||
|
@ -205,7 +232,7 @@ namespace SafeExamBrowser.Runtime.Operations
|
|||
|
||||
logger.Info("Stopping current service session...");
|
||||
|
||||
var communication = service.StopSession(Context.Current.Id);
|
||||
var communication = service.StopSession(Context.Current.SessionId);
|
||||
|
||||
if (communication.Success)
|
||||
{
|
||||
|
|
|
@ -63,11 +63,11 @@ namespace SafeExamBrowser.Runtime.Operations
|
|||
|
||||
if (isFirstSession)
|
||||
{
|
||||
logger.Info($"Successfully activated first session '{Context.Next.Id}'.");
|
||||
logger.Info($"Successfully activated first session '{Context.Next.SessionId}'.");
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info($"Successfully terminated old session '{Context.Current.Id}' and activated new session '{Context.Next.Id}'.");
|
||||
logger.Info($"Successfully terminated old session '{Context.Current.SessionId}' and activated new session '{Context.Next.SessionId}'.");
|
||||
}
|
||||
|
||||
Context.Current = Context.Next;
|
||||
|
|
|
@ -63,11 +63,11 @@ namespace SafeExamBrowser.Runtime.Operations
|
|||
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeSession);
|
||||
|
||||
Context.Next = configuration.InitializeSessionConfiguration();
|
||||
runtimeHost.StartupToken = Context.Next.StartupToken;
|
||||
runtimeHost.AuthenticationToken = Context.Next.ClientAuthenticationToken;
|
||||
|
||||
logger.Info($" -> Client-ID: {Context.Next.AppConfig.ClientId}");
|
||||
logger.Info($" -> Runtime-ID: {Context.Next.AppConfig.RuntimeId}");
|
||||
logger.Info($" -> Session-ID: {Context.Next.Id}");
|
||||
logger.Info($" -> Session-ID: {Context.Next.SessionId}");
|
||||
}
|
||||
|
||||
private void FinalizeSessionConfiguration()
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace SafeExamBrowser.Runtime
|
|||
private IText text;
|
||||
private IUserInterfaceFactory uiFactory;
|
||||
|
||||
private ISessionConfiguration Session
|
||||
private SessionConfiguration Session
|
||||
{
|
||||
get { return sessionContext.Current; }
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ namespace SafeExamBrowser.Runtime
|
|||
args.ClientConfiguration = new ClientConfiguration
|
||||
{
|
||||
AppConfig = sessionContext.Next.AppConfig,
|
||||
SessionId = sessionContext.Next.Id,
|
||||
SessionId = sessionContext.Next.SessionId,
|
||||
Settings = sessionContext.Next.Settings
|
||||
};
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace SafeExamBrowser.Runtime
|
|||
/// <summary>
|
||||
/// The configuration of the currently active session.
|
||||
/// </summary>
|
||||
internal ISessionConfiguration Current { get; set; }
|
||||
internal SessionConfiguration Current { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The new desktop, if <see cref="KioskMode.CreateNewDesktop"/> is currently active.
|
||||
|
@ -46,7 +46,7 @@ namespace SafeExamBrowser.Runtime
|
|||
/// <summary>
|
||||
/// The configuration of the next session to be activated.
|
||||
/// </summary>
|
||||
internal ISessionConfiguration Next { get; set; }
|
||||
internal SessionConfiguration Next { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The original desktop, if <see cref="KioskMode.CreateNewDesktop"/> is currently active.
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Contracts.Communication.Hosts;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Core.OperationModel;
|
||||
|
||||
namespace SafeExamBrowser.Service.UnitTests
|
||||
|
@ -65,6 +66,7 @@ namespace SafeExamBrowser.Service.UnitTests
|
|||
|
||||
bootstrapSequence.Setup(b => b.TryRevert()).Returns(OperationResult.Success).Callback(() => bootstrap = ++order);
|
||||
sessionSequence.Setup(b => b.TryRevert()).Returns(OperationResult.Success).Callback(() => session = ++order);
|
||||
sessionContext.Current = new ServiceConfiguration();
|
||||
|
||||
sut.Terminate();
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
using SafeExamBrowser.Contracts.Communication.Hosts;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Core.OperationModel;
|
||||
using SafeExamBrowser.Contracts.Service;
|
||||
|
||||
|
@ -19,7 +20,7 @@ namespace SafeExamBrowser.Service
|
|||
private IServiceHost serviceHost;
|
||||
private SessionContext sessionContext;
|
||||
|
||||
private object Session
|
||||
private ServiceConfiguration Session
|
||||
{
|
||||
get { return sessionContext.Current; }
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
|
||||
namespace SafeExamBrowser.Service
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -16,11 +18,11 @@ namespace SafeExamBrowser.Service
|
|||
/// <summary>
|
||||
/// The configuration of the currently active session.
|
||||
/// </summary>
|
||||
internal object Current { get; set; }
|
||||
internal ServiceConfiguration Current { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The configuration of the next session to be activated.
|
||||
/// </summary>
|
||||
internal object Next { get; set; }
|
||||
internal ServiceConfiguration Next { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue