SEBWIN-405: Implemented loading of server exam configuration.
This commit is contained in:
parent
7915d4dff9
commit
ef13cfe9c5
4 changed files with 96 additions and 20 deletions
|
@ -63,11 +63,12 @@ namespace SafeExamBrowser.Runtime
|
||||||
var uiFactory = new UserInterfaceFactory(text);
|
var uiFactory = new UserInterfaceFactory(text);
|
||||||
var desktopFactory = new DesktopFactory(ModuleLogger(nameof(DesktopFactory)));
|
var desktopFactory = new DesktopFactory(ModuleLogger(nameof(DesktopFactory)));
|
||||||
var explorerShell = new ExplorerShell(ModuleLogger(nameof(ExplorerShell)), nativeMethods);
|
var explorerShell = new ExplorerShell(ModuleLogger(nameof(ExplorerShell)), nativeMethods);
|
||||||
|
var fileSystem = new FileSystem();
|
||||||
var processFactory = new ProcessFactory(ModuleLogger(nameof(ProcessFactory)));
|
var processFactory = new ProcessFactory(ModuleLogger(nameof(ProcessFactory)));
|
||||||
var proxyFactory = new ProxyFactory(new ProxyObjectFactory(), ModuleLogger(nameof(ProxyFactory)));
|
var proxyFactory = new ProxyFactory(new ProxyObjectFactory(), ModuleLogger(nameof(ProxyFactory)));
|
||||||
var runtimeHost = new RuntimeHost(appConfig.RuntimeAddress, new HostObjectFactory(), ModuleLogger(nameof(RuntimeHost)), FIVE_SECONDS);
|
var runtimeHost = new RuntimeHost(appConfig.RuntimeAddress, new HostObjectFactory(), ModuleLogger(nameof(RuntimeHost)), FIVE_SECONDS);
|
||||||
var runtimeWindow = uiFactory.CreateRuntimeWindow(appConfig);
|
var runtimeWindow = uiFactory.CreateRuntimeWindow(appConfig);
|
||||||
var server = new ServerProxy(ModuleLogger(nameof(ServerProxy)));
|
var server = new ServerProxy(appConfig, ModuleLogger(nameof(ServerProxy)));
|
||||||
var serviceProxy = new ServiceProxy(appConfig.ServiceAddress, new ProxyObjectFactory(), ModuleLogger(nameof(ServiceProxy)), Interlocutor.Runtime);
|
var serviceProxy = new ServiceProxy(appConfig.ServiceAddress, new ProxyObjectFactory(), ModuleLogger(nameof(ServiceProxy)), Interlocutor.Runtime);
|
||||||
var sessionContext = new SessionContext();
|
var sessionContext = new SessionContext();
|
||||||
var splashScreen = uiFactory.CreateSplashScreen(appConfig);
|
var splashScreen = uiFactory.CreateSplashScreen(appConfig);
|
||||||
|
@ -82,7 +83,7 @@ namespace SafeExamBrowser.Runtime
|
||||||
|
|
||||||
sessionOperations.Enqueue(new SessionInitializationOperation(configuration, logger, runtimeHost, sessionContext));
|
sessionOperations.Enqueue(new SessionInitializationOperation(configuration, logger, runtimeHost, sessionContext));
|
||||||
sessionOperations.Enqueue(new ConfigurationOperation(args, configuration, new FileSystem(), new HashAlgorithm(), logger, sessionContext));
|
sessionOperations.Enqueue(new ConfigurationOperation(args, configuration, new FileSystem(), new HashAlgorithm(), logger, sessionContext));
|
||||||
sessionOperations.Enqueue(new ServerOperation(args, configuration, logger, sessionContext, server));
|
sessionOperations.Enqueue(new ServerOperation(args, configuration, fileSystem, logger, sessionContext, server));
|
||||||
sessionOperations.Enqueue(new VirtualMachineOperation(vmDetector, logger, sessionContext));
|
sessionOperations.Enqueue(new VirtualMachineOperation(vmDetector, logger, sessionContext));
|
||||||
sessionOperations.Enqueue(new ServiceOperation(logger, runtimeHost, serviceProxy, sessionContext, THIRTY_SECONDS, userInfo));
|
sessionOperations.Enqueue(new ServiceOperation(logger, runtimeHost, serviceProxy, sessionContext, THIRTY_SECONDS, userInfo));
|
||||||
sessionOperations.Enqueue(new ClientTerminationOperation(logger, processFactory, proxyFactory, runtimeHost, sessionContext, THIRTY_SECONDS));
|
sessionOperations.Enqueue(new ClientTerminationOperation(logger, processFactory, proxyFactory, runtimeHost, sessionContext, THIRTY_SECONDS));
|
||||||
|
|
|
@ -16,11 +16,13 @@ using SafeExamBrowser.Logging.Contracts;
|
||||||
using SafeExamBrowser.Runtime.Operations.Events;
|
using SafeExamBrowser.Runtime.Operations.Events;
|
||||||
using SafeExamBrowser.Server.Contracts;
|
using SafeExamBrowser.Server.Contracts;
|
||||||
using SafeExamBrowser.Settings;
|
using SafeExamBrowser.Settings;
|
||||||
|
using SafeExamBrowser.SystemComponents.Contracts;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Runtime.Operations
|
namespace SafeExamBrowser.Runtime.Operations
|
||||||
{
|
{
|
||||||
internal class ServerOperation : ConfigurationBaseOperation
|
internal class ServerOperation : ConfigurationBaseOperation
|
||||||
{
|
{
|
||||||
|
private readonly IFileSystem fileSystem;
|
||||||
private readonly ILogger logger;
|
private readonly ILogger logger;
|
||||||
private readonly IServerProxy server;
|
private readonly IServerProxy server;
|
||||||
|
|
||||||
|
@ -30,10 +32,12 @@ namespace SafeExamBrowser.Runtime.Operations
|
||||||
public ServerOperation(
|
public ServerOperation(
|
||||||
string[] commandLineArgs,
|
string[] commandLineArgs,
|
||||||
IConfigurationRepository configuration,
|
IConfigurationRepository configuration,
|
||||||
|
IFileSystem fileSystem,
|
||||||
ILogger logger,
|
ILogger logger,
|
||||||
SessionContext context,
|
SessionContext context,
|
||||||
IServerProxy server) : base(commandLineArgs, configuration, context)
|
IServerProxy server) : base(commandLineArgs, configuration, context)
|
||||||
{
|
{
|
||||||
|
this.fileSystem = fileSystem;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
}
|
}
|
||||||
|
@ -67,6 +71,8 @@ namespace SafeExamBrowser.Runtime.Operations
|
||||||
{
|
{
|
||||||
var status = TryLoadSettings(uri, UriSource.Server, out _, out var settings);
|
var status = TryLoadSettings(uri, UriSource.Server, out _, out var settings);
|
||||||
|
|
||||||
|
fileSystem.Delete(uri.LocalPath);
|
||||||
|
|
||||||
if (status == LoadStatus.Success)
|
if (status == LoadStatus.Success)
|
||||||
{
|
{
|
||||||
Context.Next.Settings = settings;
|
Context.Next.Settings = settings;
|
||||||
|
|
|
@ -63,6 +63,10 @@
|
||||||
<Compile Include="ServerProxy.cs" />
|
<Compile Include="ServerProxy.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\SafeExamBrowser.Configuration.Contracts\SafeExamBrowser.Configuration.Contracts.csproj">
|
||||||
|
<Project>{7d74555e-63e1-4c46-bd0a-8580552368c8}</Project>
|
||||||
|
<Name>SafeExamBrowser.Configuration.Contracts</Name>
|
||||||
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\SafeExamBrowser.Logging.Contracts\SafeExamBrowser.Logging.Contracts.csproj">
|
<ProjectReference Include="..\SafeExamBrowser.Logging.Contracts\SafeExamBrowser.Logging.Contracts.csproj">
|
||||||
<Project>{64ea30fb-11d4-436a-9c2b-88566285363e}</Project>
|
<Project>{64ea30fb-11d4-436a-9c2b-88566285363e}</Project>
|
||||||
<Name>SafeExamBrowser.Logging.Contracts</Name>
|
<Name>SafeExamBrowser.Logging.Contracts</Name>
|
||||||
|
|
|
@ -16,6 +16,7 @@ using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using SafeExamBrowser.Configuration.Contracts;
|
||||||
using SafeExamBrowser.Logging.Contracts;
|
using SafeExamBrowser.Logging.Contracts;
|
||||||
using SafeExamBrowser.Server.Contracts;
|
using SafeExamBrowser.Server.Contracts;
|
||||||
using SafeExamBrowser.Server.Data;
|
using SafeExamBrowser.Server.Data;
|
||||||
|
@ -28,13 +29,15 @@ namespace SafeExamBrowser.Server
|
||||||
private ApiVersion1 api;
|
private ApiVersion1 api;
|
||||||
private string connectionToken;
|
private string connectionToken;
|
||||||
private HttpClient httpClient;
|
private HttpClient httpClient;
|
||||||
|
private readonly AppConfig appConfig;
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private string oauth2Token;
|
private string oauth2Token;
|
||||||
private ServerSettings settings;
|
private ServerSettings settings;
|
||||||
|
|
||||||
public ServerProxy(ILogger logger)
|
public ServerProxy(AppConfig appConfig, ILogger logger)
|
||||||
{
|
{
|
||||||
this.api = new ApiVersion1();
|
this.api = new ApiVersion1();
|
||||||
|
this.appConfig = appConfig;
|
||||||
this.httpClient = new HttpClient();
|
this.httpClient = new HttpClient();
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
}
|
}
|
||||||
|
@ -75,7 +78,7 @@ namespace SafeExamBrowser.Server
|
||||||
|
|
||||||
public ServerResponse Disconnect()
|
public ServerResponse Disconnect()
|
||||||
{
|
{
|
||||||
return new ServerResponse(false, "Some error message here");
|
return new ServerResponse(false, "TODO!");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerResponse<IEnumerable<Exam>> GetAvailableExams()
|
public ServerResponse<IEnumerable<Exam>> GetAvailableExams()
|
||||||
|
@ -83,13 +86,19 @@ namespace SafeExamBrowser.Server
|
||||||
var authorization = ("Authorization", $"Bearer {oauth2Token}");
|
var authorization = ("Authorization", $"Bearer {oauth2Token}");
|
||||||
var content = $"institutionId={settings.Institution}";
|
var content = $"institutionId={settings.Institution}";
|
||||||
var contentType = "application/x-www-form-urlencoded";
|
var contentType = "application/x-www-form-urlencoded";
|
||||||
|
var exams = default(IList<Exam>);
|
||||||
|
|
||||||
var success = TryExecute(HttpMethod.Post, api.HandshakeEndpoint, out var response, content, contentType, authorization);
|
var success = TryExecute(HttpMethod.Post, api.HandshakeEndpoint, out var response, content, contentType, authorization);
|
||||||
var message = ToString(response);
|
var message = ToString(response);
|
||||||
var hasToken = TryParseConnectionToken(response);
|
|
||||||
var hasExams = TryParseExams(response.Content, out var exams);
|
|
||||||
|
|
||||||
if (success && hasExams && hasToken)
|
if (success)
|
||||||
|
{
|
||||||
|
var hasExams = TryParseExams(response.Content, out exams);
|
||||||
|
var hasToken = TryParseConnectionToken(response);
|
||||||
|
|
||||||
|
success = hasExams && hasToken;
|
||||||
|
|
||||||
|
if (success)
|
||||||
{
|
{
|
||||||
logger.Info("Successfully retrieved connection token and available exams.");
|
logger.Info("Successfully retrieved connection token and available exams.");
|
||||||
}
|
}
|
||||||
|
@ -101,19 +110,45 @@ namespace SafeExamBrowser.Server
|
||||||
{
|
{
|
||||||
logger.Error("Failed to retrieve connection token!");
|
logger.Error("Failed to retrieve connection token!");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logger.Error("Failed to load connection token and available exams!");
|
logger.Error("Failed to load connection token and available exams!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ServerResponse<IEnumerable<Exam>>(hasExams && hasToken, exams, message);
|
return new ServerResponse<IEnumerable<Exam>>(success, exams, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerResponse<Uri> GetConfigurationFor(Exam exam)
|
public ServerResponse<Uri> GetConfigurationFor(Exam exam)
|
||||||
{
|
{
|
||||||
// 4. Send exam ID
|
var authorization = ("Authorization", $"Bearer {oauth2Token}");
|
||||||
|
var token = ("SEBConnectionToken", connectionToken);
|
||||||
|
var uri = default(Uri);
|
||||||
|
|
||||||
return new ServerResponse<Uri>(false, default(Uri), "Some error message here");
|
var success = TryExecute(HttpMethod.Get, $"{api.ConfigurationEndpoint}?examId={exam.Id}", out var response, default(string), default(string), authorization, token);
|
||||||
|
var message = ToString(response);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
logger.Info("Successfully retrieved exam configuration.");
|
||||||
|
|
||||||
|
success = TrySaveFile(response.Content, out uri);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
logger.Info($"Successfully saved exam configuration as '{uri}'.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Error("Failed to save exam configuration!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Error("Failed to retrieve exam configuration!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ServerResponse<Uri>(success, uri, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(ServerSettings settings)
|
public void Initialize(ServerSettings settings)
|
||||||
|
@ -129,7 +164,7 @@ namespace SafeExamBrowser.Server
|
||||||
|
|
||||||
public ServerResponse SendSessionInfo(string sessionId)
|
public ServerResponse SendSessionInfo(string sessionId)
|
||||||
{
|
{
|
||||||
return new ServerResponse(false, "Some error message here");
|
return new ServerResponse(false, "TODO!");
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryParseApi(HttpContent content)
|
private bool TryParseApi(HttpContent content)
|
||||||
|
@ -301,6 +336,36 @@ namespace SafeExamBrowser.Server
|
||||||
return response != default(HttpResponseMessage) && response.IsSuccessStatusCode;
|
return response != default(HttpResponseMessage) && response.IsSuccessStatusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool TrySaveFile(HttpContent content, out Uri uri)
|
||||||
|
{
|
||||||
|
uri = new Uri(Path.Combine(appConfig.TemporaryDirectory, $"ServerExam{appConfig.ConfigurationFileExtension}"));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var task = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
return await content.ReadAsStreamAsync();
|
||||||
|
});
|
||||||
|
|
||||||
|
using (var data = task.GetAwaiter().GetResult())
|
||||||
|
using (var file = new FileStream(uri.LocalPath, FileMode.Create))
|
||||||
|
{
|
||||||
|
data.Seek(0, SeekOrigin.Begin);
|
||||||
|
data.CopyTo(file);
|
||||||
|
data.Flush();
|
||||||
|
file.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.Error($"Failed to save file '{uri.LocalPath}'!", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private string Extract(HttpContent content)
|
private string Extract(HttpContent content)
|
||||||
{
|
{
|
||||||
var task = Task.Run(async () =>
|
var task = Task.Run(async () =>
|
||||||
|
|
Loading…
Reference in a new issue