SEBWIN-727: Implemented support for configuration data URIs.
This commit is contained in:
parent
bbfa720b21
commit
3711555f70
5 changed files with 68 additions and 13 deletions
|
@ -69,6 +69,7 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
|
||||||
var quitUrl = "http://www.byebye.com";
|
var quitUrl = "http://www.byebye.com";
|
||||||
var request = new Mock<IRequest>();
|
var request = new Mock<IRequest>();
|
||||||
|
|
||||||
|
appConfig.ConfigurationFileMimeType = "application/seb";
|
||||||
request.SetupGet(r => r.Url).Returns(quitUrl);
|
request.SetupGet(r => r.Url).Returns(quitUrl);
|
||||||
settings.QuitUrl = quitUrl;
|
settings.QuitUrl = quitUrl;
|
||||||
sut.QuitUrlVisited += (url) => eventFired = true;
|
sut.QuitUrlVisited += (url) => eventFired = true;
|
||||||
|
@ -122,6 +123,7 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
|
||||||
var request = new Mock<IRequest>();
|
var request = new Mock<IRequest>();
|
||||||
var url = "https://www.test.org";
|
var url = "https://www.test.org";
|
||||||
|
|
||||||
|
appConfig.ConfigurationFileMimeType = "application/seb";
|
||||||
filter.Setup(f => f.Process(It.Is<Request>(r => r.Url.Equals(url)))).Returns(FilterResult.Block);
|
filter.Setup(f => f.Process(It.Is<Request>(r => r.Url.Equals(url)))).Returns(FilterResult.Block);
|
||||||
request.SetupGet(r => r.ResourceType).Returns(ResourceType.MainFrame);
|
request.SetupGet(r => r.ResourceType).Returns(ResourceType.MainFrame);
|
||||||
request.SetupGet(r => r.Url).Returns(url);
|
request.SetupGet(r => r.Url).Returns(url);
|
||||||
|
@ -155,6 +157,7 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
|
||||||
var request = new Mock<IRequest>();
|
var request = new Mock<IRequest>();
|
||||||
var url = "https://www.test.org";
|
var url = "https://www.test.org";
|
||||||
|
|
||||||
|
appConfig.ConfigurationFileMimeType = "application/seb";
|
||||||
filter.Setup(f => f.Process(It.Is<Request>(r => r.Url.Equals(url)))).Returns(FilterResult.Block);
|
filter.Setup(f => f.Process(It.Is<Request>(r => r.Url.Equals(url)))).Returns(FilterResult.Block);
|
||||||
request.SetupGet(r => r.ResourceType).Returns(ResourceType.SubFrame);
|
request.SetupGet(r => r.ResourceType).Returns(ResourceType.SubFrame);
|
||||||
request.SetupGet(r => r.Url).Returns(url);
|
request.SetupGet(r => r.Url).Returns(url);
|
||||||
|
@ -182,13 +185,34 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void MustInitiateConfigurationFileDownload()
|
public void MustInitiateDataUriConfigurationFileDownload()
|
||||||
{
|
{
|
||||||
var browser = new Mock<IBrowser>();
|
var browser = new Mock<IBrowser>();
|
||||||
var host = new Mock<IBrowserHost>();
|
var host = new Mock<IBrowserHost>();
|
||||||
var request = new Mock<IRequest>();
|
var request = new Mock<IRequest>();
|
||||||
|
|
||||||
appConfig.ConfigurationFileExtension = ".xyz";
|
appConfig.ConfigurationFileExtension = ".xyz";
|
||||||
|
appConfig.ConfigurationFileMimeType = "application/seb";
|
||||||
|
appConfig.SebUriScheme = "abc";
|
||||||
|
appConfig.SebUriSchemeSecure = "abcd";
|
||||||
|
browser.Setup(b => b.GetHost()).Returns(host.Object);
|
||||||
|
request.SetupGet(r => r.Url).Returns($"{appConfig.SebUriSchemeSecure}://{appConfig.ConfigurationFileMimeType};base64,H4sIAAAAAAAAE41WbXPaRhD...");
|
||||||
|
|
||||||
|
var handled = sut.OnBeforeBrowse(Mock.Of<IWebBrowser>(), browser.Object, Mock.Of<IFrame>(), request.Object, false, false);
|
||||||
|
|
||||||
|
host.Verify(h => h.StartDownload(It.Is<string>(u => u == $"data:{appConfig.ConfigurationFileMimeType};base64,H4sIAAAAAAAAE41WbXPaRhD...")));
|
||||||
|
Assert.IsTrue(handled);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MustInitiateHttpConfigurationFileDownload()
|
||||||
|
{
|
||||||
|
var browser = new Mock<IBrowser>();
|
||||||
|
var host = new Mock<IBrowserHost>();
|
||||||
|
var request = new Mock<IRequest>();
|
||||||
|
|
||||||
|
appConfig.ConfigurationFileExtension = ".xyz";
|
||||||
|
appConfig.ConfigurationFileMimeType = "application/seb";
|
||||||
appConfig.SebUriScheme = "abc";
|
appConfig.SebUriScheme = "abc";
|
||||||
appConfig.SebUriSchemeSecure = "abcd";
|
appConfig.SebUriSchemeSecure = "abcd";
|
||||||
browser.Setup(b => b.GetHost()).Returns(host.Object);
|
browser.Setup(b => b.GetHost()).Returns(host.Object);
|
||||||
|
@ -198,13 +222,23 @@ namespace SafeExamBrowser.Browser.UnitTests.Handlers
|
||||||
|
|
||||||
host.Verify(h => h.StartDownload(It.Is<string>(u => u == $"{Uri.UriSchemeHttp}://host.com/path/file{appConfig.ConfigurationFileExtension}")));
|
host.Verify(h => h.StartDownload(It.Is<string>(u => u == $"{Uri.UriSchemeHttp}://host.com/path/file{appConfig.ConfigurationFileExtension}")));
|
||||||
Assert.IsTrue(handled);
|
Assert.IsTrue(handled);
|
||||||
|
}
|
||||||
|
|
||||||
handled = false;
|
[TestMethod]
|
||||||
host.Reset();
|
public void MustInitiateHttpsConfigurationFileDownload()
|
||||||
request.Reset();
|
{
|
||||||
|
var browser = new Mock<IBrowser>();
|
||||||
|
var host = new Mock<IBrowserHost>();
|
||||||
|
var request = new Mock<IRequest>();
|
||||||
|
|
||||||
|
appConfig.ConfigurationFileExtension = ".xyz";
|
||||||
|
appConfig.ConfigurationFileMimeType = "application/seb";
|
||||||
|
appConfig.SebUriScheme = "abc";
|
||||||
|
appConfig.SebUriSchemeSecure = "abcd";
|
||||||
|
browser.Setup(b => b.GetHost()).Returns(host.Object);
|
||||||
request.SetupGet(r => r.Url).Returns($"{appConfig.SebUriSchemeSecure}://host.com/path/file{appConfig.ConfigurationFileExtension}");
|
request.SetupGet(r => r.Url).Returns($"{appConfig.SebUriSchemeSecure}://host.com/path/file{appConfig.ConfigurationFileExtension}");
|
||||||
|
|
||||||
handled = sut.OnBeforeBrowse(Mock.Of<IWebBrowser>(), browser.Object, Mock.Of<IFrame>(), request.Object, false, false);
|
var handled = sut.OnBeforeBrowse(Mock.Of<IWebBrowser>(), browser.Object, Mock.Of<IFrame>(), request.Object, false, false);
|
||||||
|
|
||||||
host.Verify(h => h.StartDownload(It.Is<string>(u => u == $"{Uri.UriSchemeHttps}://host.com/path/file{appConfig.ConfigurationFileExtension}")));
|
host.Verify(h => h.StartDownload(It.Is<string>(u => u == $"{Uri.UriSchemeHttps}://host.com/path/file{appConfig.ConfigurationFileExtension}")));
|
||||||
Assert.IsTrue(handled);
|
Assert.IsTrue(handled);
|
||||||
|
|
|
@ -121,19 +121,35 @@ namespace SafeExamBrowser.Browser.Handlers
|
||||||
private bool IsConfigurationFile(IRequest request, out string downloadUrl)
|
private bool IsConfigurationFile(IRequest request, out string downloadUrl)
|
||||||
{
|
{
|
||||||
var isValidUri = Uri.TryCreate(request.Url, UriKind.RelativeOrAbsolute, out var uri);
|
var isValidUri = Uri.TryCreate(request.Url, UriKind.RelativeOrAbsolute, out var uri);
|
||||||
var isConfigurationFile = isValidUri && string.Equals(appConfig.ConfigurationFileExtension, Path.GetExtension(uri.AbsolutePath), StringComparison.OrdinalIgnoreCase);
|
var hasFileExtension = string.Equals(appConfig.ConfigurationFileExtension, Path.GetExtension(uri.AbsolutePath), StringComparison.OrdinalIgnoreCase);
|
||||||
|
var isDataUri = request.Url.Contains(appConfig.ConfigurationFileMimeType);
|
||||||
|
var isConfigurationFile = isValidUri && (hasFileExtension || isDataUri);
|
||||||
|
|
||||||
downloadUrl = request.Url;
|
downloadUrl = request.Url;
|
||||||
|
|
||||||
if (isConfigurationFile)
|
if (isConfigurationFile)
|
||||||
{
|
{
|
||||||
if (uri.Scheme == appConfig.SebUriScheme)
|
if (isDataUri)
|
||||||
{
|
{
|
||||||
downloadUrl = new UriBuilder(uri) { Scheme = Uri.UriSchemeHttp }.Uri.AbsoluteUri;
|
if (uri.Scheme == appConfig.SebUriScheme)
|
||||||
|
{
|
||||||
|
downloadUrl = request.Url.Replace($"{appConfig.SebUriScheme}{Uri.SchemeDelimiter}", "data:");
|
||||||
|
}
|
||||||
|
else if (uri.Scheme == appConfig.SebUriSchemeSecure)
|
||||||
|
{
|
||||||
|
downloadUrl = request.Url.Replace($"{appConfig.SebUriSchemeSecure}{Uri.SchemeDelimiter}", "data:");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (uri.Scheme == appConfig.SebUriSchemeSecure)
|
else
|
||||||
{
|
{
|
||||||
downloadUrl = new UriBuilder(uri) { Scheme = Uri.UriSchemeHttps }.Uri.AbsoluteUri;
|
if (uri.Scheme == appConfig.SebUriScheme)
|
||||||
|
{
|
||||||
|
downloadUrl = new UriBuilder(uri) { Scheme = Uri.UriSchemeHttp }.Uri.AbsoluteUri;
|
||||||
|
}
|
||||||
|
else if (uri.Scheme == appConfig.SebUriSchemeSecure)
|
||||||
|
{
|
||||||
|
downloadUrl = new UriBuilder(uri) { Scheme = Uri.UriSchemeHttps }.Uri.AbsoluteUri;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Debug($"Detected configuration file {(windowSettings.UrlPolicy.CanLog() ? $"'{uri}'" : "")}.");
|
logger.Debug($"Detected configuration file {(windowSettings.UrlPolicy.CanLog() ? $"'{uri}'" : "")}.");
|
||||||
|
|
|
@ -624,10 +624,10 @@ namespace SafeExamBrowser.Client
|
||||||
logger.Info($"Received server failure action request with id '{args.RequestId}'.");
|
logger.Info($"Received server failure action request with id '{args.RequestId}'.");
|
||||||
|
|
||||||
var dialog = uiFactory.CreateServerFailureDialog(args.Message, args.ShowFallback);
|
var dialog = uiFactory.CreateServerFailureDialog(args.Message, args.ShowFallback);
|
||||||
var result = dialog.Show(splashScreen);
|
var result = dialog.Show();
|
||||||
|
|
||||||
runtime.SubmitServerFailureActionResult(args.RequestId, result.Abort, result.Fallback, result.Retry);
|
runtime.SubmitServerFailureActionResult(args.RequestId, result.Abort, result.Fallback, result.Retry);
|
||||||
logger.Info($"Server failure action request with id '{args.RequestId}' is complete.");
|
logger.Info($"Server failure action request with id '{args.RequestId}' is complete, the user chose to {(result.Abort ? "abort" : (result.Fallback ? "fallback" : "retry"))}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClientHost_Shutdown()
|
private void ClientHost_Shutdown()
|
||||||
|
|
|
@ -241,6 +241,11 @@ namespace SafeExamBrowser.Runtime.Operations
|
||||||
abort = args.Abort;
|
abort = args.Abort;
|
||||||
fallback = args.Fallback;
|
fallback = args.Fallback;
|
||||||
|
|
||||||
|
if (args.Retry)
|
||||||
|
{
|
||||||
|
logger.Debug("The user chose to retry the current server request.");
|
||||||
|
}
|
||||||
|
|
||||||
return args.Retry;
|
return args.Retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
xmlns:fa="http://schemas.fontawesome.io/icons/"
|
xmlns:fa="http://schemas.fontawesome.io/icons/"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Desktop.Windows"
|
xmlns:local="clr-namespace:SafeExamBrowser.UserInterface.Desktop.Windows"
|
||||||
mc:Ignorable="d" Height="250" Width="450" ResizeMode="NoResize" Topmost="True">
|
mc:Ignorable="d" Height="250" Width="450" ResizeMode="NoResize" Topmost="True" WindowStartupLocation="CenterScreen">
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<ResourceDictionary.MergedDictionaries>
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
|
Loading…
Reference in a new issue