SEBWIN-405: Fixed and improved LMS session detection.
This commit is contained in:
parent
682c2a2ce5
commit
8d94750078
9 changed files with 113 additions and 70 deletions
|
@ -18,6 +18,7 @@ using SafeExamBrowser.Settings.Browser.Filter;
|
||||||
using SafeExamBrowser.Settings.Browser.Proxy;
|
using SafeExamBrowser.Settings.Browser.Proxy;
|
||||||
using BrowserSettings = SafeExamBrowser.Settings.Browser.BrowserSettings;
|
using BrowserSettings = SafeExamBrowser.Settings.Browser.BrowserSettings;
|
||||||
using Request = SafeExamBrowser.Browser.Contracts.Filters.Request;
|
using Request = SafeExamBrowser.Browser.Contracts.Filters.Request;
|
||||||
|
using ResourceHandler = SafeExamBrowser.Browser.Handlers.ResourceHandler;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Browser.UnitTests.Handlers
|
namespace SafeExamBrowser.Browser.UnitTests.Handlers
|
||||||
{
|
{
|
||||||
|
@ -28,6 +29,7 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
|
||||||
private Mock<IRequestFilter> filter;
|
private Mock<IRequestFilter> filter;
|
||||||
private Mock<ILogger> logger;
|
private Mock<ILogger> logger;
|
||||||
private BrowserSettings settings;
|
private BrowserSettings settings;
|
||||||
|
private ResourceHandler resourceHandler;
|
||||||
private Mock<IText> text;
|
private Mock<IText> text;
|
||||||
private TestableRequestHandler sut;
|
private TestableRequestHandler sut;
|
||||||
|
|
||||||
|
@ -39,8 +41,9 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
|
||||||
logger = new Mock<ILogger>();
|
logger = new Mock<ILogger>();
|
||||||
settings = new BrowserSettings();
|
settings = new BrowserSettings();
|
||||||
text = new Mock<IText>();
|
text = new Mock<IText>();
|
||||||
|
resourceHandler = new ResourceHandler(appConfig, settings, filter.Object, logger.Object, text.Object);
|
||||||
|
|
||||||
sut = new TestableRequestHandler(appConfig, filter.Object, logger.Object, settings, text.Object);
|
sut = new TestableRequestHandler(appConfig, filter.Object, logger.Object, settings, resourceHandler, text.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -194,7 +197,13 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
|
||||||
|
|
||||||
private class TestableRequestHandler : RequestHandler
|
private class TestableRequestHandler : RequestHandler
|
||||||
{
|
{
|
||||||
internal TestableRequestHandler(AppConfig appConfig, IRequestFilter filter, ILogger logger, BrowserSettings settings, IText text) : base(appConfig, filter, logger, settings, text)
|
internal TestableRequestHandler(
|
||||||
|
AppConfig appConfig,
|
||||||
|
IRequestFilter filter,
|
||||||
|
ILogger logger,
|
||||||
|
BrowserSettings settings,
|
||||||
|
ResourceHandler resourceHandler,
|
||||||
|
IText text) : base(appConfig, filter, logger, settings, resourceHandler, text)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,6 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Timers;
|
|
||||||
using CefSharp;
|
using CefSharp;
|
||||||
using CefSharp.WinForms;
|
using CefSharp.WinForms;
|
||||||
using SafeExamBrowser.Applications.Contracts;
|
using SafeExamBrowser.Applications.Contracts;
|
||||||
|
@ -41,10 +39,8 @@ namespace SafeExamBrowser.Browser
|
||||||
private IFileSystemDialog fileSystemDialog;
|
private IFileSystemDialog fileSystemDialog;
|
||||||
private IMessageBox messageBox;
|
private IMessageBox messageBox;
|
||||||
private IModuleLogger logger;
|
private IModuleLogger logger;
|
||||||
private List<string> sessionCookies;
|
|
||||||
private BrowserSettings settings;
|
private BrowserSettings settings;
|
||||||
private IText text;
|
private IText text;
|
||||||
private Timer timer;
|
|
||||||
private IUserInterfaceFactory uiFactory;
|
private IUserInterfaceFactory uiFactory;
|
||||||
|
|
||||||
public bool AutoStart { get; private set; }
|
public bool AutoStart { get; private set; }
|
||||||
|
@ -72,10 +68,8 @@ namespace SafeExamBrowser.Browser
|
||||||
this.instances = new List<BrowserApplicationInstance>();
|
this.instances = new List<BrowserApplicationInstance>();
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.messageBox = messageBox;
|
this.messageBox = messageBox;
|
||||||
this.sessionCookies = new List<string>();
|
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.timer = new Timer();
|
|
||||||
this.uiFactory = uiFactory;
|
this.uiFactory = uiFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,15 +105,12 @@ namespace SafeExamBrowser.Browser
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
CreateNewInstance();
|
CreateNewInstance();
|
||||||
StartMonitoringCookies();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Terminate()
|
public void Terminate()
|
||||||
{
|
{
|
||||||
logger.Info("Initiating termination...");
|
logger.Info("Initiating termination...");
|
||||||
|
|
||||||
StopMonitoringCookies();
|
|
||||||
|
|
||||||
foreach (var instance in instances)
|
foreach (var instance in instances)
|
||||||
{
|
{
|
||||||
instance.Terminated -= Instance_Terminated;
|
instance.Terminated -= Instance_Terminated;
|
||||||
|
@ -155,6 +146,7 @@ namespace SafeExamBrowser.Browser
|
||||||
|
|
||||||
instance.ConfigurationDownloadRequested += (fileName, args) => ConfigurationDownloadRequested?.Invoke(fileName, args);
|
instance.ConfigurationDownloadRequested += (fileName, args) => ConfigurationDownloadRequested?.Invoke(fileName, args);
|
||||||
instance.PopupRequested += Instance_PopupRequested;
|
instance.PopupRequested += Instance_PopupRequested;
|
||||||
|
instance.SessionIdentifierDetected += (i) => SessionIdentifierDetected?.Invoke(i);
|
||||||
instance.Terminated += Instance_Terminated;
|
instance.Terminated += Instance_Terminated;
|
||||||
instance.TerminationRequested += () => TerminationRequested?.Invoke();
|
instance.TerminationRequested += () => TerminationRequested?.Invoke();
|
||||||
|
|
||||||
|
@ -304,20 +296,6 @@ namespace SafeExamBrowser.Browser
|
||||||
return userAgent;
|
return userAgent;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartMonitoringCookies()
|
|
||||||
{
|
|
||||||
timer.AutoReset = false;
|
|
||||||
timer.Interval = 1000;
|
|
||||||
timer.Elapsed += Timer_Elapsed;
|
|
||||||
timer.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void StopMonitoringCookies()
|
|
||||||
{
|
|
||||||
timer.Stop();
|
|
||||||
timer.Elapsed -= Timer_Elapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string ToScheme(ProxyProtocol protocol)
|
private string ToScheme(ProxyProtocol protocol)
|
||||||
{
|
{
|
||||||
switch (protocol)
|
switch (protocol)
|
||||||
|
@ -346,40 +324,5 @@ namespace SafeExamBrowser.Browser
|
||||||
instances.Remove(instances.First(i => i.Id == id));
|
instances.Remove(instances.First(i => i.Id == id));
|
||||||
WindowsChanged?.Invoke();
|
WindowsChanged?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Timer_Elapsed(object sender, ElapsedEventArgs args)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var manager = Cef.GetGlobalCookieManager();
|
|
||||||
var task = manager.VisitAllCookiesAsync();
|
|
||||||
var cookies = task.GetAwaiter().GetResult();
|
|
||||||
var edxLogin = cookies.FirstOrDefault(c => c.Name == "edxloggedin");
|
|
||||||
var moodleSession = cookies.FirstOrDefault(c => c.Name == "MoodleSession");
|
|
||||||
|
|
||||||
if (edxLogin != default(Cookie))
|
|
||||||
{
|
|
||||||
var edxSession = cookies.FirstOrDefault(c => c.Domain == edxLogin.Domain && c.Name == "sessionid");
|
|
||||||
|
|
||||||
if (edxSession != default(Cookie) && !sessionCookies.Contains(edxSession.Domain))
|
|
||||||
{
|
|
||||||
sessionCookies.Add(edxSession.Domain);
|
|
||||||
Task.Run(() => SessionIdentifierDetected?.Invoke(edxSession.Value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (moodleSession != default(Cookie) && !sessionCookies.Contains(moodleSession.Domain))
|
|
||||||
{
|
|
||||||
sessionCookies.Add(moodleSession.Domain);
|
|
||||||
Task.Run(() => SessionIdentifierDetected?.Invoke(moodleSession.Value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
logger.Error("Failed to read cookies!", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
timer.Start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ using SafeExamBrowser.UserInterface.Contracts.FileSystemDialog;
|
||||||
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
|
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
|
||||||
using BrowserSettings = SafeExamBrowser.Settings.Browser.BrowserSettings;
|
using BrowserSettings = SafeExamBrowser.Settings.Browser.BrowserSettings;
|
||||||
using Request = SafeExamBrowser.Browser.Contracts.Filters.Request;
|
using Request = SafeExamBrowser.Browser.Contracts.Filters.Request;
|
||||||
|
using ResourceHandler = SafeExamBrowser.Browser.Handlers.ResourceHandler;
|
||||||
using TitleChangedEventHandler = SafeExamBrowser.Applications.Contracts.Events.TitleChangedEventHandler;
|
using TitleChangedEventHandler = SafeExamBrowser.Applications.Contracts.Events.TitleChangedEventHandler;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Browser
|
namespace SafeExamBrowser.Browser
|
||||||
|
@ -65,6 +66,7 @@ namespace SafeExamBrowser.Browser
|
||||||
|
|
||||||
internal event DownloadRequestedEventHandler ConfigurationDownloadRequested;
|
internal event DownloadRequestedEventHandler ConfigurationDownloadRequested;
|
||||||
internal event PopupRequestedEventHandler PopupRequested;
|
internal event PopupRequestedEventHandler PopupRequested;
|
||||||
|
internal event SessionIdentifierDetectedEventHandler SessionIdentifierDetected;
|
||||||
internal event InstanceTerminatedEventHandler Terminated;
|
internal event InstanceTerminatedEventHandler Terminated;
|
||||||
internal event TerminationRequestedEventHandler TerminationRequested;
|
internal event TerminationRequestedEventHandler TerminationRequested;
|
||||||
|
|
||||||
|
@ -124,7 +126,8 @@ namespace SafeExamBrowser.Browser
|
||||||
var lifeSpanHandler = new LifeSpanHandler();
|
var lifeSpanHandler = new LifeSpanHandler();
|
||||||
var requestFilter = new RequestFilter();
|
var requestFilter = new RequestFilter();
|
||||||
var requestLogger = logger.CloneFor($"{nameof(RequestHandler)} #{Id}");
|
var requestLogger = logger.CloneFor($"{nameof(RequestHandler)} #{Id}");
|
||||||
var requestHandler = new RequestHandler(appConfig, requestFilter, requestLogger, settings, text);
|
var resourceHandler = new ResourceHandler(appConfig, settings, requestFilter, logger, text);
|
||||||
|
var requestHandler = new RequestHandler(appConfig, requestFilter, requestLogger, settings, resourceHandler, text);
|
||||||
|
|
||||||
Icon = new BrowserIconResource();
|
Icon = new BrowserIconResource();
|
||||||
|
|
||||||
|
@ -138,6 +141,7 @@ namespace SafeExamBrowser.Browser
|
||||||
keyboardHandler.ZoomOutRequested += ZoomOutRequested;
|
keyboardHandler.ZoomOutRequested += ZoomOutRequested;
|
||||||
keyboardHandler.ZoomResetRequested += ZoomResetRequested;
|
keyboardHandler.ZoomResetRequested += ZoomResetRequested;
|
||||||
lifeSpanHandler.PopupRequested += LifeSpanHandler_PopupRequested;
|
lifeSpanHandler.PopupRequested += LifeSpanHandler_PopupRequested;
|
||||||
|
resourceHandler.SessionIdentifierDetected += (id) => SessionIdentifierDetected?.Invoke(id);
|
||||||
requestHandler.QuitUrlVisited += RequestHandler_QuitUrlVisited;
|
requestHandler.QuitUrlVisited += RequestHandler_QuitUrlVisited;
|
||||||
requestHandler.RequestBlocked += RequestHandler_RequestBlocked;
|
requestHandler.RequestBlocked += RequestHandler_RequestBlocked;
|
||||||
|
|
||||||
|
|
|
@ -31,12 +31,18 @@ namespace SafeExamBrowser.Browser.Handlers
|
||||||
internal event UrlEventHandler QuitUrlVisited;
|
internal event UrlEventHandler QuitUrlVisited;
|
||||||
internal event UrlEventHandler RequestBlocked;
|
internal event UrlEventHandler RequestBlocked;
|
||||||
|
|
||||||
internal RequestHandler(AppConfig appConfig, IRequestFilter filter, ILogger logger, BrowserSettings settings, IText text)
|
internal RequestHandler(
|
||||||
|
AppConfig appConfig,
|
||||||
|
IRequestFilter filter,
|
||||||
|
ILogger logger,
|
||||||
|
BrowserSettings settings,
|
||||||
|
ResourceHandler resourceHandler,
|
||||||
|
IText text)
|
||||||
{
|
{
|
||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.resourceHandler = new ResourceHandler(appConfig, settings, filter, logger, text);
|
this.resourceHandler = resourceHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool GetAuthCredentials(IWebBrowser webBrowser, IBrowser browser, string originUrl, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
|
protected override bool GetAuthCredentials(IWebBrowser webBrowser, IBrowser browser, string originUrl, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
|
||||||
|
|
|
@ -8,10 +8,15 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
|
using System.Linq;
|
||||||
using System.Net.Mime;
|
using System.Net.Mime;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using CefSharp;
|
using CefSharp;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using SafeExamBrowser.Browser.Contracts.Events;
|
||||||
using SafeExamBrowser.Browser.Contracts.Filters;
|
using SafeExamBrowser.Browser.Contracts.Filters;
|
||||||
using SafeExamBrowser.Browser.Pages;
|
using SafeExamBrowser.Browser.Pages;
|
||||||
using SafeExamBrowser.Configuration.Contracts;
|
using SafeExamBrowser.Configuration.Contracts;
|
||||||
|
@ -36,6 +41,8 @@ namespace SafeExamBrowser.Browser.Handlers
|
||||||
private BrowserSettings settings;
|
private BrowserSettings settings;
|
||||||
private IText text;
|
private IText text;
|
||||||
|
|
||||||
|
internal event SessionIdentifierDetectedEventHandler SessionIdentifierDetected;
|
||||||
|
|
||||||
internal ResourceHandler(AppConfig appConfig, BrowserSettings settings, IRequestFilter filter, ILogger logger, IText text)
|
internal ResourceHandler(AppConfig appConfig, BrowserSettings settings, IRequestFilter filter, ILogger logger, IText text)
|
||||||
{
|
{
|
||||||
this.appConfig = appConfig;
|
this.appConfig = appConfig;
|
||||||
|
@ -70,6 +77,13 @@ namespace SafeExamBrowser.Browser.Handlers
|
||||||
return base.OnBeforeResourceLoad(webBrowser, browser, frame, request, callback);
|
return base.OnBeforeResourceLoad(webBrowser, browser, frame, request, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnResourceRedirect(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response, ref string newUrl)
|
||||||
|
{
|
||||||
|
SearchSessionIdentifiers(response);
|
||||||
|
|
||||||
|
base.OnResourceRedirect(chromiumWebBrowser, browser, frame, request, response, ref newUrl);
|
||||||
|
}
|
||||||
|
|
||||||
protected override bool OnResourceResponse(IWebBrowser webBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response)
|
protected override bool OnResourceResponse(IWebBrowser webBrowser, IBrowser browser, IFrame frame, IRequest request, IResponse response)
|
||||||
{
|
{
|
||||||
if (RedirectToDisablePdfToolbar(request, response, out var url))
|
if (RedirectToDisablePdfToolbar(request, response, out var url))
|
||||||
|
@ -79,6 +93,8 @@ namespace SafeExamBrowser.Browser.Handlers
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SearchSessionIdentifiers(response);
|
||||||
|
|
||||||
return base.OnResourceResponse(webBrowser, browser, frame, request, response);
|
return base.OnResourceResponse(webBrowser, browser, frame, request, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,5 +222,64 @@ namespace SafeExamBrowser.Browser.Handlers
|
||||||
return contentHandler;
|
return contentHandler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SearchSessionIdentifiers(IResponse response)
|
||||||
|
{
|
||||||
|
SearchEdxIdentifier(response);
|
||||||
|
SearchMoodleIdentifier(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SearchEdxIdentifier(IResponse response)
|
||||||
|
{
|
||||||
|
var cookies = response.Headers.GetValues("Set-Cookie");
|
||||||
|
|
||||||
|
if (cookies != default(string[]))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var userInfo = cookies.FirstOrDefault(c => c.Contains("edx-user-info"));
|
||||||
|
|
||||||
|
if (userInfo != default(string))
|
||||||
|
{
|
||||||
|
var start = userInfo.IndexOf("=") + 1;
|
||||||
|
var end = userInfo.IndexOf("; expires");
|
||||||
|
var cookie = userInfo.Substring(start, end - start);
|
||||||
|
var sanitized = cookie.Replace("\\\"", "\"").Replace("\\054", ",").Trim('"');
|
||||||
|
var json = JsonConvert.DeserializeObject(sanitized) as JObject;
|
||||||
|
var userName = json["username"].Value<string>();
|
||||||
|
|
||||||
|
Task.Run(() => SessionIdentifierDetected?.Invoke(userName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.Error("Failed to parse edX session identifier!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SearchMoodleIdentifier(IResponse response)
|
||||||
|
{
|
||||||
|
var locations = response.Headers.GetValues("Location");
|
||||||
|
|
||||||
|
if (locations != default(string[]))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var location = locations.FirstOrDefault(l => l.Contains("moodle/login/index.php?testsession"));
|
||||||
|
|
||||||
|
if (location != default(string))
|
||||||
|
{
|
||||||
|
var userId = location.Substring(location.IndexOf("=") + 1);
|
||||||
|
|
||||||
|
Task.Run(() => SessionIdentifierDetected?.Invoke(userId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.Error("Failed to parse Moodle session identifier!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,9 @@
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Syroot.KnownFolders, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Syroot.KnownFolders, Version=1.2.3.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Syroot.Windows.IO.KnownFolders.1.2.3\lib\netstandard2.0\Syroot.KnownFolders.dll</HintPath>
|
<HintPath>..\packages\Syroot.Windows.IO.KnownFolders.1.2.3\lib\netstandard2.0\Syroot.KnownFolders.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<package id="cef.redist.x86" version="81.3.10" targetFramework="net472" />
|
<package id="cef.redist.x86" version="81.3.10" targetFramework="net472" />
|
||||||
<package id="CefSharp.Common" version="81.3.100" targetFramework="net472" />
|
<package id="CefSharp.Common" version="81.3.100" targetFramework="net472" />
|
||||||
<package id="CefSharp.WinForms" version="81.3.100" targetFramework="net472" />
|
<package id="CefSharp.WinForms" version="81.3.100" targetFramework="net472" />
|
||||||
|
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net472" />
|
||||||
<package id="Syroot.Windows.IO.KnownFolders" version="1.2.3" targetFramework="net472" />
|
<package id="Syroot.Windows.IO.KnownFolders" version="1.2.3" targetFramework="net472" />
|
||||||
<package id="System.Security.Principal.Windows" version="4.7.0" targetFramework="net472" />
|
<package id="System.Security.Principal.Windows" version="4.7.0" targetFramework="net472" />
|
||||||
</packages>
|
</packages>
|
|
@ -77,7 +77,6 @@ namespace SafeExamBrowser.Runtime.Operations
|
||||||
|
|
||||||
if (status == LoadStatus.Success)
|
if (status == LoadStatus.Success)
|
||||||
{
|
{
|
||||||
// TODO: Why aren't the server settings and SEB mode correctly set in the exam configuration?
|
|
||||||
var serverSettings = Context.Next.Settings.Server;
|
var serverSettings = Context.Next.Settings.Server;
|
||||||
|
|
||||||
Context.Next.AppConfig.ServerApi = info.Api;
|
Context.Next.AppConfig.ServerApi = info.Api;
|
||||||
|
|
|
@ -256,20 +256,28 @@ namespace SafeExamBrowser.Server
|
||||||
task = new Task(SendLog, cancellationTokenSource.Token);
|
task = new Task(SendLog, cancellationTokenSource.Token);
|
||||||
task.Start();
|
task.Start();
|
||||||
|
|
||||||
|
logger.Info("Started sending log items.");
|
||||||
|
|
||||||
timer.AutoReset = false;
|
timer.AutoReset = false;
|
||||||
timer.Elapsed += Timer_Elapsed;
|
timer.Elapsed += Timer_Elapsed;
|
||||||
timer.Interval = 1000;
|
timer.Interval = 1000;
|
||||||
timer.Start();
|
timer.Start();
|
||||||
|
|
||||||
|
logger.Info("Starting sending pings.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StopConnectivity()
|
public void StopConnectivity()
|
||||||
{
|
{
|
||||||
logger.Unsubscribe(this);
|
logger.Unsubscribe(this);
|
||||||
cancellationTokenSource.Cancel();
|
cancellationTokenSource.Cancel();
|
||||||
task.Wait();
|
task?.Wait();
|
||||||
|
|
||||||
|
logger.Info("Stopped sending log items.");
|
||||||
|
|
||||||
timer.Stop();
|
timer.Stop();
|
||||||
timer.Elapsed -= Timer_Elapsed;
|
timer.Elapsed -= Timer_Elapsed;
|
||||||
|
|
||||||
|
logger.Info("Stopped sending pings.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendLog()
|
private void SendLog()
|
||||||
|
@ -278,8 +286,6 @@ namespace SafeExamBrowser.Server
|
||||||
var contentType = "application/json;charset=UTF-8";
|
var contentType = "application/json;charset=UTF-8";
|
||||||
var token = ("SEBConnectionToken", connectionToken);
|
var token = ("SEBConnectionToken", connectionToken);
|
||||||
|
|
||||||
logger.Info("Starting to send log items...");
|
|
||||||
|
|
||||||
while (!cancellationTokenSource.IsCancellationRequested)
|
while (!cancellationTokenSource.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -293,7 +299,6 @@ namespace SafeExamBrowser.Server
|
||||||
["text"] = message.Message
|
["text"] = message.Message
|
||||||
};
|
};
|
||||||
var content = json.ToString();
|
var content = json.ToString();
|
||||||
// TODO: Why can't we send multiple log messages in one request?
|
|
||||||
var success = TryExecute(HttpMethod.Post, api.LogEndpoint, out var response, content, contentType, authorization, token);
|
var success = TryExecute(HttpMethod.Post, api.LogEndpoint, out var response, content, contentType, authorization, token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,8 +307,6 @@ namespace SafeExamBrowser.Server
|
||||||
logger.Error("Failed to send log!", e);
|
logger.Error("Failed to send log!", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("Stopped sending log items.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Timer_Elapsed(object sender, ElapsedEventArgs args)
|
private void Timer_Elapsed(object sender, ElapsedEventArgs args)
|
||||||
|
|
Loading…
Add table
Reference in a new issue