SEBWIN-314: Completed infrastructure for request filter.
This commit is contained in:
parent
367ebf1329
commit
1dd65e1bda
25 changed files with 669 additions and 167 deletions
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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 Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using SafeExamBrowser.Browser.Filters;
|
||||
using SafeExamBrowser.Settings.Browser;
|
||||
|
||||
namespace SafeExamBrowser.Browser.UnitTests.Filters
|
||||
{
|
||||
[TestClass]
|
||||
public class RequestFilterTests
|
||||
{
|
||||
private RequestFilter sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
sut = new RequestFilter();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustProcessBlockRulesFirst()
|
||||
{
|
||||
var allow = new FilterRuleSettings { Expression = "*", Type = FilterType.Simplified, Result = FilterResult.Allow };
|
||||
var block = new FilterRuleSettings { Expression = "*", Type = FilterType.Simplified, Result = FilterResult.Block };
|
||||
|
||||
sut.Load(allow);
|
||||
sut.Load(block);
|
||||
|
||||
var result = sut.Process("safeexambrowser.org");
|
||||
|
||||
Assert.AreEqual(FilterResult.Block, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustProcessAllowRulesSecond()
|
||||
{
|
||||
var allow = new FilterRuleSettings { Expression = "*", Type = FilterType.Simplified, Result = FilterResult.Allow };
|
||||
var block = new FilterRuleSettings { Expression = "xyz", Type = FilterType.Simplified, Result = FilterResult.Block };
|
||||
|
||||
sut.Load(allow);
|
||||
sut.Load(block);
|
||||
|
||||
var result = sut.Process("safeexambrowser.org");
|
||||
|
||||
Assert.AreEqual(FilterResult.Allow, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustReturnDefault()
|
||||
{
|
||||
var allow = new FilterRuleSettings { Expression = "xyz", Type = FilterType.Simplified, Result = FilterResult.Allow };
|
||||
var block = new FilterRuleSettings { Expression = "xyz", Type = FilterType.Simplified, Result = FilterResult.Block };
|
||||
|
||||
sut.Default = (FilterResult) (-1);
|
||||
sut.Load(allow);
|
||||
sut.Load(block);
|
||||
|
||||
var result = sut.Process("safeexambrowser.org");
|
||||
|
||||
Assert.AreEqual((FilterResult) (-1), result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustReturnDefaultWithoutRules()
|
||||
{
|
||||
sut.Default = FilterResult.Allow;
|
||||
var result = sut.Process("safeexambrowser.org");
|
||||
Assert.AreEqual(FilterResult.Allow, result);
|
||||
|
||||
sut.Default = FilterResult.Block;
|
||||
result = sut.Process("safeexambrowser.org");
|
||||
Assert.AreEqual(FilterResult.Block, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(NotImplementedException))]
|
||||
public void MustNotAllowUnsupportedResult()
|
||||
{
|
||||
sut.Load(new FilterRuleSettings { Result = (FilterResult) (-1) });
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(NotImplementedException))]
|
||||
public void MustNotAllowUnsupportedFilterType()
|
||||
{
|
||||
sut.Load(new FilterRuleSettings { Type = (FilterType) (-1) });
|
||||
}
|
||||
}
|
||||
}
|
17
SafeExamBrowser.Browser.UnitTests/Properties/AssemblyInfo.cs
Normal file
17
SafeExamBrowser.Browser.UnitTests/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("SafeExamBrowser.Browser.UnitTests")]
|
||||
[assembly: AssemblyDescription("Safe Exam Browser")]
|
||||
[assembly: AssemblyCompany("ETH Zürich")]
|
||||
[assembly: AssemblyProduct("SafeExamBrowser.Browser.UnitTests")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2019 ETH Zürich, Educational Development and Technology (LET)")]
|
||||
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
[assembly: Guid("f54c4c0e-4c72-4f88-a389-7f6de3ccb745")]
|
||||
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyInformationalVersion("1.0.0.0")]
|
|
@ -0,0 +1,100 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props" Condition="Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{F54C4C0E-4C72-4F88-A389-7F6DE3CCB745}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>SafeExamBrowser.Browser.UnitTests</RootNamespace>
|
||||
<AssemblyName>SafeExamBrowser.Browser.UnitTests</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
|
||||
<IsCodedUITest>False</IsCodedUITest>
|
||||
<TestProjectType>UnitTest</TestProjectType>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Filters\RequestFilterTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Browser.Contracts\SafeExamBrowser.Browser.Contracts.csproj">
|
||||
<Project>{5fb5273d-277c-41dd-8593-a25ce1aff2e9}</Project>
|
||||
<Name>SafeExamBrowser.Browser.Contracts</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Browser\SafeExamBrowser.Browser.csproj">
|
||||
<Project>{04e653f1-98e6-4e34-9dd7-7f2bc1a8b767}</Project>
|
||||
<Name>SafeExamBrowser.Browser</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\SafeExamBrowser.Settings\SafeExamBrowser.Settings.csproj">
|
||||
<Project>{30b2d907-5861-4f39-abad-c4abf1b3470e}</Project>
|
||||
<Name>SafeExamBrowser.Settings</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props'))" />
|
||||
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets" Condition="Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets')" />
|
||||
</Project>
|
5
SafeExamBrowser.Browser.UnitTests/packages.config
Normal file
5
SafeExamBrowser.Browser.UnitTests/packages.config
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="MSTest.TestAdapter" version="1.3.2" targetFramework="net472" />
|
||||
<package id="MSTest.TestFramework" version="1.3.2" targetFramework="net472" />
|
||||
</packages>
|
|
@ -14,9 +14,9 @@ using SafeExamBrowser.Browser.Contracts.Events;
|
|||
using SafeExamBrowser.Browser.Events;
|
||||
using SafeExamBrowser.Browser.Handlers;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.Settings.Browser;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Settings.Browser;
|
||||
using SafeExamBrowser.UserInterface.Contracts;
|
||||
using SafeExamBrowser.UserInterface.Contracts.Browser;
|
||||
using SafeExamBrowser.UserInterface.Contracts.MessageBox;
|
||||
|
@ -102,7 +102,7 @@ namespace SafeExamBrowser.Browser
|
|||
var keyboardHandler = new KeyboardHandler();
|
||||
var lifeSpanHandler = new LifeSpanHandler();
|
||||
var requestLogger = logger.CloneFor($"{nameof(RequestHandler)} {Id}");
|
||||
var requestHandler = new RequestHandler(appConfig, settings, logger);
|
||||
var requestHandler = new RequestHandler(appConfig, settings.Filter, logger, text);
|
||||
|
||||
displayHandler.FaviconChanged += DisplayHandler_FaviconChanged;
|
||||
displayHandler.ProgressChanged += DisplayHandler_ProgressChanged;
|
||||
|
@ -117,6 +117,8 @@ namespace SafeExamBrowser.Browser
|
|||
control.AddressChanged += Control_AddressChanged;
|
||||
control.LoadingStateChanged += Control_LoadingStateChanged;
|
||||
control.TitleChanged += Control_TitleChanged;
|
||||
|
||||
requestHandler.Initiailize();
|
||||
control.Initialize();
|
||||
|
||||
logger.Debug("Initialized browser control.");
|
||||
|
|
3
SafeExamBrowser.Browser/Filters/BlockedContent.html
Normal file
3
SafeExamBrowser.Browser/Filters/BlockedContent.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<div style="background-color: lightgray; display: table; font-family: 'Segoe UI'; height: 100%; text-align: center; width: 100%">
|
||||
<p style="display: table-cell; font-weight: bold; vertical-align: middle">%%MESSAGE%%</p>
|
||||
</div>
|
13
SafeExamBrowser.Browser/Filters/BlockedPage.html
Normal file
13
SafeExamBrowser.Browser/Filters/BlockedPage.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html style="height: 100%; width: 100%">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>%%TITLE%%</title>
|
||||
</head>
|
||||
<body style="background-color: lightgray; display: table; font-family: 'Segoe UI'; height: 98%; text-align: center; width: 99%">
|
||||
<div style="display: table-cell; vertical-align: middle">
|
||||
<p style="font-weight: bold">%%MESSAGE%%</p>
|
||||
<button onclick="window.history.back()" style="cursor: pointer">⭠ %%BACK_BUTTON%%</button>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -7,20 +7,74 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using SafeExamBrowser.Browser.Filters.Rules;
|
||||
using SafeExamBrowser.Settings.Browser;
|
||||
|
||||
namespace SafeExamBrowser.Browser.Filters
|
||||
{
|
||||
internal class RequestFilter
|
||||
{
|
||||
internal void Load(FilterRule rule)
|
||||
{
|
||||
private IList<Rule> allowRules;
|
||||
private IList<Rule> blockRules;
|
||||
|
||||
internal FilterResult Default { get; set; }
|
||||
|
||||
internal RequestFilter()
|
||||
{
|
||||
allowRules = new List<Rule>();
|
||||
blockRules = new List<Rule>();
|
||||
Default = FilterResult.Block;
|
||||
}
|
||||
|
||||
internal FilterResult Process(Uri request)
|
||||
internal void Load(FilterRuleSettings settings)
|
||||
{
|
||||
var rule = default(Rule);
|
||||
|
||||
switch (settings.Type)
|
||||
{
|
||||
case FilterType.Regex:
|
||||
rule = new RegexRule(settings.Expression);
|
||||
break;
|
||||
case FilterType.Simplified:
|
||||
rule = new SimpleRule(settings.Expression);
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException($"Filter rule of type '{settings.Type}' is not yet implemented!");
|
||||
}
|
||||
|
||||
switch (settings.Result)
|
||||
{
|
||||
case FilterResult.Allow:
|
||||
allowRules.Add(rule);
|
||||
break;
|
||||
case FilterResult.Block:
|
||||
blockRules.Add(rule);
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException($"Filter result '{settings.Result}' is not yet implemented!");
|
||||
}
|
||||
}
|
||||
|
||||
internal FilterResult Process(string url)
|
||||
{
|
||||
foreach (var rule in blockRules)
|
||||
{
|
||||
if (rule.IsMatch(url))
|
||||
{
|
||||
return FilterResult.Block;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var rule in allowRules)
|
||||
{
|
||||
if (rule.IsMatch(url))
|
||||
{
|
||||
return FilterResult.Allow;
|
||||
}
|
||||
}
|
||||
|
||||
return Default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
31
SafeExamBrowser.Browser/Filters/Rules/RegexRule.cs
Normal file
31
SafeExamBrowser.Browser/Filters/Rules/RegexRule.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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.Text.RegularExpressions;
|
||||
|
||||
namespace SafeExamBrowser.Browser.Filters.Rules
|
||||
{
|
||||
internal class RegexRule : Rule
|
||||
{
|
||||
private string expression;
|
||||
|
||||
public RegexRule(string expression) : base(expression)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Initialize(string expression)
|
||||
{
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
internal override bool IsMatch(string url)
|
||||
{
|
||||
return Regex.IsMatch(url, expression, RegexOptions.IgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
21
SafeExamBrowser.Browser/Filters/Rules/Rule.cs
Normal file
21
SafeExamBrowser.Browser/Filters/Rules/Rule.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
namespace SafeExamBrowser.Browser.Filters.Rules
|
||||
{
|
||||
internal abstract class Rule
|
||||
{
|
||||
internal Rule(string expression)
|
||||
{
|
||||
Initialize(expression);
|
||||
}
|
||||
|
||||
internal abstract bool IsMatch(string url);
|
||||
protected abstract void Initialize(string expression);
|
||||
}
|
||||
}
|
31
SafeExamBrowser.Browser/Filters/Rules/SimpleRule.cs
Normal file
31
SafeExamBrowser.Browser/Filters/Rules/SimpleRule.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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.Text.RegularExpressions;
|
||||
|
||||
namespace SafeExamBrowser.Browser.Filters.Rules
|
||||
{
|
||||
internal class SimpleRule : Rule
|
||||
{
|
||||
private string expression;
|
||||
|
||||
public SimpleRule(string expression) : base(expression)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Initialize(string expression)
|
||||
{
|
||||
this.expression = expression.Replace("*", @".*");
|
||||
}
|
||||
|
||||
internal override bool IsMatch(string url)
|
||||
{
|
||||
return Regex.IsMatch(url, expression, RegexOptions.IgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,46 +7,30 @@
|
|||
*/
|
||||
|
||||
using CefSharp;
|
||||
using SafeExamBrowser.Browser.Filters;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using BrowserSettings = SafeExamBrowser.Settings.Browser.BrowserSettings;
|
||||
using SafeExamBrowser.Settings.Browser;
|
||||
|
||||
namespace SafeExamBrowser.Browser.Handlers
|
||||
{
|
||||
internal class RequestHandler : CefSharp.Handler.RequestHandler
|
||||
{
|
||||
private AppConfig appConfig;
|
||||
private BrowserSettings settings;
|
||||
private RequestFilter filter;
|
||||
private ILogger logger;
|
||||
private ResourceRequestHandler resourceRequestHandler;
|
||||
private ResourceHandler resourceHandler;
|
||||
|
||||
internal RequestHandler(AppConfig appConfig, BrowserSettings settings, ILogger logger)
|
||||
internal RequestHandler(AppConfig appConfig, BrowserFilterSettings settings, ILogger logger, IText text)
|
||||
{
|
||||
this.appConfig = appConfig;
|
||||
this.settings = settings;
|
||||
this.filter = new RequestFilter();
|
||||
this.logger = logger;
|
||||
this.resourceRequestHandler = new ResourceRequestHandler(appConfig, settings, logger);
|
||||
this.resourceHandler = new ResourceHandler(appConfig, settings, logger, text);
|
||||
}
|
||||
|
||||
internal void Initiailize()
|
||||
{
|
||||
if (settings.FilterMainRequests || settings.FilterContentRequests)
|
||||
{
|
||||
foreach (var rule in settings.FilterRules)
|
||||
{
|
||||
filter.Load(rule);
|
||||
}
|
||||
|
||||
logger.Debug("Initialized request filter.");
|
||||
}
|
||||
resourceHandler.Initialize();
|
||||
}
|
||||
|
||||
protected override IResourceRequestHandler GetResourceRequestHandler(IWebBrowser webBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)
|
||||
{
|
||||
return resourceRequestHandler;
|
||||
return resourceHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
174
SafeExamBrowser.Browser/Handlers/ResourceHandler.cs
Normal file
174
SafeExamBrowser.Browser/Handlers/ResourceHandler.cs
Normal file
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* 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 System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using CefSharp;
|
||||
using SafeExamBrowser.Browser.Filters;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.I18n.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using SafeExamBrowser.Settings.Browser;
|
||||
|
||||
namespace SafeExamBrowser.Browser.Handlers
|
||||
{
|
||||
internal class ResourceHandler : CefSharp.Handler.ResourceRequestHandler
|
||||
{
|
||||
private AppConfig appConfig;
|
||||
private BrowserFilterSettings settings;
|
||||
private ILogger logger;
|
||||
private RequestFilter filter;
|
||||
private IResourceHandler contentBlockedHandler;
|
||||
private IResourceHandler pageBlockedHandler;
|
||||
private IText text;
|
||||
|
||||
internal ResourceHandler(AppConfig appConfig, BrowserFilterSettings settings, ILogger logger, IText text)
|
||||
{
|
||||
this.appConfig = appConfig;
|
||||
this.filter = new RequestFilter();
|
||||
this.logger = logger;
|
||||
this.settings = settings;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
internal void Initialize()
|
||||
{
|
||||
if (settings.FilterMainRequests || settings.FilterContentRequests)
|
||||
{
|
||||
InitializeFilter();
|
||||
}
|
||||
}
|
||||
|
||||
protected override IResourceHandler GetResourceHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request)
|
||||
{
|
||||
if (BlockMainRequest(request))
|
||||
{
|
||||
return pageBlockedHandler;
|
||||
}
|
||||
|
||||
if (BlockContentRequest(request))
|
||||
{
|
||||
return contentBlockedHandler;
|
||||
}
|
||||
|
||||
return base.GetResourceHandler(chromiumWebBrowser, browser, frame, request);
|
||||
}
|
||||
|
||||
protected override CefReturnValue OnBeforeResourceLoad(IWebBrowser webBrowser, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback)
|
||||
{
|
||||
// TODO: CEF does not yet support intercepting requests from service workers, thus the user agent must be statically set at browser
|
||||
// startup for now. Once CEF has full support of service workers, the static user agent should be removed and the method below
|
||||
// reactivated. See https://bitbucket.org/chromiumembedded/cef/issues/2622 for the current status of development.
|
||||
// AppendCustomUserAgent(request);
|
||||
|
||||
if (IsMailtoUrl(request.Url))
|
||||
{
|
||||
return CefReturnValue.Cancel;
|
||||
}
|
||||
|
||||
ReplaceCustomScheme(request);
|
||||
|
||||
return base.OnBeforeResourceLoad(webBrowser, browser, frame, request, callback);
|
||||
}
|
||||
|
||||
private void AppendCustomUserAgent(IRequest request)
|
||||
{
|
||||
var headers = new NameValueCollection(request.Headers);
|
||||
var userAgent = request.Headers["User-Agent"];
|
||||
|
||||
headers["User-Agent"] = $"{userAgent} SEB/{appConfig.ProgramInformationalVersion}";
|
||||
request.Headers = headers;
|
||||
}
|
||||
|
||||
private bool BlockContentRequest(IRequest request)
|
||||
{
|
||||
if (settings.FilterContentRequests && request.ResourceType != ResourceType.MainFrame)
|
||||
{
|
||||
var result = filter.Process(request.Url);
|
||||
var block = result == FilterResult.Block;
|
||||
|
||||
if (block)
|
||||
{
|
||||
logger.Info($"Blocked content request for '{request.Url}'.");
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool BlockMainRequest(IRequest request)
|
||||
{
|
||||
if (settings.FilterMainRequests && request.ResourceType == ResourceType.MainFrame)
|
||||
{
|
||||
var result = filter.Process(request.Url);
|
||||
var block = result == FilterResult.Block;
|
||||
|
||||
if (block)
|
||||
{
|
||||
logger.Info($"Blocked main request for '{request.Url}'.");
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void InitializeFilter()
|
||||
{
|
||||
var assembly = Assembly.GetAssembly(typeof(RequestFilter));
|
||||
var contentMessage = text.Get(TextKey.Browser_BlockedContentMessage);
|
||||
var contentStream = assembly.GetManifestResourceStream($"{typeof(RequestFilter).Namespace}.BlockedContent.html");
|
||||
var pageButton = text.Get(TextKey.Browser_BlockedPageButton);
|
||||
var pageMessage = text.Get(TextKey.Browser_BlockedPageMessage);
|
||||
var pageTitle = text.Get(TextKey.Browser_BlockedPageTitle);
|
||||
var pageStream = assembly.GetManifestResourceStream($"{typeof(RequestFilter).Namespace}.BlockedPage.html");
|
||||
var contentHtml = new StreamReader(contentStream).ReadToEnd();
|
||||
var pageHtml = new StreamReader(pageStream).ReadToEnd();
|
||||
|
||||
contentHtml = contentHtml.Replace("%%MESSAGE%%", contentMessage);
|
||||
pageHtml = pageHtml.Replace("%%MESSAGE%%", pageMessage).Replace("%%TITLE%%", pageTitle).Replace("%%BACK_BUTTON%%", pageButton);
|
||||
|
||||
contentBlockedHandler = CefSharp.ResourceHandler.FromString(contentHtml);
|
||||
pageBlockedHandler = CefSharp.ResourceHandler.FromString(pageHtml);
|
||||
|
||||
foreach (var rule in settings.Rules)
|
||||
{
|
||||
filter.Load(rule);
|
||||
}
|
||||
|
||||
logger.Debug($"Initialized request filter with {settings.Rules.Count} rules.");
|
||||
}
|
||||
|
||||
private bool IsMailtoUrl(string url)
|
||||
{
|
||||
return url.StartsWith(Uri.UriSchemeMailto);
|
||||
}
|
||||
|
||||
private void ReplaceCustomScheme(IRequest request)
|
||||
{
|
||||
if (Uri.IsWellFormedUriString(request.Url, UriKind.RelativeOrAbsolute))
|
||||
{
|
||||
var uri = new Uri(request.Url);
|
||||
|
||||
if (uri.Scheme == appConfig.SebUriScheme)
|
||||
{
|
||||
request.Url = new UriBuilder(uri) { Scheme = Uri.UriSchemeHttp }.Uri.AbsoluteUri;
|
||||
}
|
||||
else if (uri.Scheme == appConfig.SebUriSchemeSecure)
|
||||
{
|
||||
request.Url = new UriBuilder(uri) { Scheme = Uri.UriSchemeHttps }.Uri.AbsoluteUri;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,99 +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 System.Collections.Specialized;
|
||||
using CefSharp;
|
||||
using SafeExamBrowser.Configuration.Contracts;
|
||||
using SafeExamBrowser.Logging.Contracts;
|
||||
using BrowserSettings = SafeExamBrowser.Settings.Browser.BrowserSettings;
|
||||
|
||||
namespace SafeExamBrowser.Browser.Handlers
|
||||
{
|
||||
internal class ResourceRequestHandler : CefSharp.Handler.ResourceRequestHandler
|
||||
{
|
||||
private AppConfig appConfig;
|
||||
private BrowserSettings settings;
|
||||
private ILogger logger;
|
||||
|
||||
internal ResourceRequestHandler(AppConfig appConfig, BrowserSettings settings, ILogger logger)
|
||||
{
|
||||
this.appConfig = appConfig;
|
||||
this.settings = settings;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
protected override IResourceHandler GetResourceHandler(IWebBrowser webBrowser, IBrowser browser, IFrame frame, IRequest request)
|
||||
{
|
||||
if (FilterMainRequest(request) || FilterContentRequest(request))
|
||||
{
|
||||
return ResourceHandler.FromString("<html><body>Blocked!</body></html>");
|
||||
}
|
||||
|
||||
return base.GetResourceHandler(webBrowser, browser, frame, request);
|
||||
}
|
||||
|
||||
protected override CefReturnValue OnBeforeResourceLoad(IWebBrowser webBrowser, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback)
|
||||
{
|
||||
// TODO: CEF does not yet support intercepting requests from service workers, thus the user agent must be statically set at browser
|
||||
// startup for now. Once CEF has full support of service workers, the static user agent should be removed and the method below
|
||||
// reactivated. See https://bitbucket.org/chromiumembedded/cef/issues/2622 for the current status of development.
|
||||
// AppendCustomUserAgent(request);
|
||||
|
||||
if (IsMailtoUrl(request.Url))
|
||||
{
|
||||
return CefReturnValue.Cancel;
|
||||
}
|
||||
|
||||
ReplaceCustomScheme(request);
|
||||
|
||||
return base.OnBeforeResourceLoad(webBrowser, browser, frame, request, callback);
|
||||
}
|
||||
|
||||
private void AppendCustomUserAgent(IRequest request)
|
||||
{
|
||||
var headers = new NameValueCollection(request.Headers);
|
||||
var userAgent = request.Headers["User-Agent"];
|
||||
|
||||
headers["User-Agent"] = $"{userAgent} SEB/{appConfig.ProgramInformationalVersion}";
|
||||
request.Headers = headers;
|
||||
}
|
||||
|
||||
private bool FilterContentRequest(IRequest request)
|
||||
{
|
||||
return settings.FilterContentRequests && request.ResourceType != ResourceType.MainFrame;
|
||||
}
|
||||
|
||||
private bool FilterMainRequest(IRequest request)
|
||||
{
|
||||
return settings.FilterMainRequests && request.ResourceType == ResourceType.MainFrame;
|
||||
}
|
||||
|
||||
private bool IsMailtoUrl(string url)
|
||||
{
|
||||
return url.StartsWith(Uri.UriSchemeMailto);
|
||||
}
|
||||
|
||||
private void ReplaceCustomScheme(IRequest request)
|
||||
{
|
||||
if (Uri.IsWellFormedUriString(request.Url, UriKind.RelativeOrAbsolute))
|
||||
{
|
||||
var uri = new Uri(request.Url);
|
||||
|
||||
if (uri.Scheme == appConfig.SebUriScheme)
|
||||
{
|
||||
request.Url = new UriBuilder(uri) { Scheme = Uri.UriSchemeHttp }.Uri.AbsoluteUri;
|
||||
}
|
||||
else if (uri.Scheme == appConfig.SebUriSchemeSecure)
|
||||
{
|
||||
request.Url = new UriBuilder(uri) { Scheme = Uri.UriSchemeHttps }.Uri.AbsoluteUri;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
|
@ -14,6 +15,7 @@ using System.Runtime.InteropServices;
|
|||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: InternalsVisibleTo("SafeExamBrowser.Browser.UnitTests")]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("04e653f1-98e6-4e34-9dd7-7f2bc1a8b767")]
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
|
@ -72,6 +73,9 @@
|
|||
<Compile Include="Events\PopupRequestedEventArgs.cs" />
|
||||
<Compile Include="Events\PopupRequestedEventHandler.cs" />
|
||||
<Compile Include="Filters\RequestFilter.cs" />
|
||||
<Compile Include="Filters\Rules\Rule.cs" />
|
||||
<Compile Include="Filters\Rules\RegexRule.cs" />
|
||||
<Compile Include="Filters\Rules\SimpleRule.cs" />
|
||||
<Compile Include="Handlers\ContextMenuHandler.cs" />
|
||||
<Compile Include="BrowserControl.cs">
|
||||
<SubType>Component</SubType>
|
||||
|
@ -82,7 +86,7 @@
|
|||
<Compile Include="Handlers\KeyboardHandler.cs" />
|
||||
<Compile Include="Handlers\LifeSpanHandler.cs" />
|
||||
<Compile Include="Handlers\RequestHandler.cs" />
|
||||
<Compile Include="Handlers\ResourceRequestHandler.cs" />
|
||||
<Compile Include="Handlers\ResourceHandler.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -124,6 +128,10 @@
|
|||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Filters\BlockedContent.html" />
|
||||
<EmbeddedResource Include="Filters\BlockedPage.html" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>
|
||||
|
|
|
@ -110,7 +110,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
|||
{
|
||||
if (value is bool filter)
|
||||
{
|
||||
settings.Browser.FilterContentRequests = filter;
|
||||
settings.Browser.Filter.FilterContentRequests = filter;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
|||
{
|
||||
if (value is bool filter)
|
||||
{
|
||||
settings.Browser.FilterMainRequests = filter;
|
||||
settings.Browser.Filter.FilterMainRequests = filter;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,13 +126,15 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
|||
{
|
||||
const int ALLOW = 1;
|
||||
|
||||
if (value is IEnumerable<IDictionary<string, object>> ruleDataList)
|
||||
if (value is IList<object> ruleDataList)
|
||||
{
|
||||
foreach (var ruleData in ruleDataList)
|
||||
foreach (var item in ruleDataList)
|
||||
{
|
||||
if (item is IDictionary<string, object> ruleData)
|
||||
{
|
||||
if (ruleData.TryGetValue(Keys.Browser.Filter.RuleIsActive, out var v) && v is bool active && active)
|
||||
{
|
||||
var rule = new FilterRule();
|
||||
var rule = new FilterRuleSettings();
|
||||
|
||||
if (ruleData.TryGetValue(Keys.Browser.Filter.RuleExpression, out v) && v is string expression)
|
||||
{
|
||||
|
@ -149,7 +151,8 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
|
|||
rule.Type = regex ? FilterType.Regex : FilterType.Simplified;
|
||||
}
|
||||
|
||||
settings.Browser.FilterRules.Add(rule);
|
||||
settings.Browser.Filter.Rules.Add(rule);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,10 @@ namespace SafeExamBrowser.I18n.Contracts
|
|||
/// </summary>
|
||||
public enum TextKey
|
||||
{
|
||||
Browser_BlockedContentMessage,
|
||||
Browser_BlockedPageButton,
|
||||
Browser_BlockedPageMessage,
|
||||
Browser_BlockedPageTitle,
|
||||
BrowserWindow_DeveloperConsoleMenuItem,
|
||||
BrowserWindow_ZoomMenuItem,
|
||||
Build,
|
||||
|
|
|
@ -1,5 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Text>
|
||||
<Entry key="Browser_BlockedContentMessage">
|
||||
Content blocked
|
||||
</Entry>
|
||||
<Entry key="Browser_BlockedPageButton">
|
||||
Back to previous page
|
||||
</Entry>
|
||||
<Entry key="Browser_BlockedPageMessage">
|
||||
Access to this page is not allowed according to the application configuration.
|
||||
</Entry>
|
||||
<Entry key="Browser_BlockedPageTitle">
|
||||
Page Blocked
|
||||
</Entry>
|
||||
<Entry key="BrowserWindow_DeveloperConsoleMenuItem">
|
||||
Developer Console
|
||||
</Entry>
|
||||
|
|
40
SafeExamBrowser.Settings/Browser/BrowserFilterSettings.cs
Normal file
40
SafeExamBrowser.Settings/Browser/BrowserFilterSettings.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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 System.Collections.Generic;
|
||||
|
||||
namespace SafeExamBrowser.Settings.Browser
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines all configuration options for the request filter of the browser.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class BrowserFilterSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines whether all content requests for a web page should be filtered according to the defined <see cref="Rules"/>.
|
||||
/// </summary>
|
||||
public bool FilterContentRequests { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines whether the main request for a web page should be filtered according to the defined <see cref="Rules"/>.
|
||||
/// </summary>
|
||||
public bool FilterMainRequests { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines all rules to be used to filter web requests.
|
||||
/// </summary>
|
||||
public IList<FilterRuleSettings> Rules { get; set; }
|
||||
|
||||
public BrowserFilterSettings()
|
||||
{
|
||||
Rules = new List<FilterRuleSettings>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,7 +7,6 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SafeExamBrowser.Settings.Browser
|
||||
{
|
||||
|
@ -48,19 +47,9 @@ namespace SafeExamBrowser.Settings.Browser
|
|||
public string CustomUserAgent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines whether all content requests for a web page should be filtered according to the defined <see cref="FilterRules"/>.
|
||||
/// The settings to be used for the browser request filter.
|
||||
/// </summary>
|
||||
public bool FilterContentRequests { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines whether the main request for a web page should be filtered according to the defined <see cref="FilterRules"/>.
|
||||
/// </summary>
|
||||
public bool FilterMainRequests { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines all rules to be used to filter web requests.
|
||||
/// </summary>
|
||||
public IList<FilterRule> FilterRules { get; set; }
|
||||
public BrowserFilterSettings Filter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The configuration to be used for the main browser window.
|
||||
|
@ -80,7 +69,7 @@ namespace SafeExamBrowser.Settings.Browser
|
|||
public BrowserSettings()
|
||||
{
|
||||
AdditionalWindowSettings = new BrowserWindowSettings();
|
||||
FilterRules = new List<FilterRule>();
|
||||
Filter = new BrowserFilterSettings();
|
||||
MainWindowSettings = new BrowserWindowSettings();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@ using System;
|
|||
namespace SafeExamBrowser.Settings.Browser
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a request filter rule.
|
||||
/// Defines the settings for a request filter rule.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class FilterRule
|
||||
public class FilterRuleSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// The expression according to which requests should be filtered.
|
|
@ -53,10 +53,11 @@
|
|||
<Reference Include="Microsoft.CSharp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Browser\BrowserFilterSettings.cs" />
|
||||
<Compile Include="Browser\BrowserSettings.cs" />
|
||||
<Compile Include="Browser\BrowserWindowSettings.cs" />
|
||||
<Compile Include="Browser\FilterResult.cs" />
|
||||
<Compile Include="Browser\FilterRule.cs" />
|
||||
<Compile Include="Browser\FilterRuleSettings.cs" />
|
||||
<Compile Include="Browser\FilterType.cs" />
|
||||
<Compile Include="ConfigurationMode.cs" />
|
||||
<Compile Include="KioskMode.cs" />
|
||||
|
|
|
@ -104,6 +104,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeExamBrowser.WindowsApi.
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeExamBrowser.Settings", "SafeExamBrowser.Settings\SafeExamBrowser.Settings.csproj", "{30B2D907-5861-4F39-ABAD-C4ABF1B3470E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SafeExamBrowser.Browser.UnitTests", "SafeExamBrowser.Browser.UnitTests\SafeExamBrowser.Browser.UnitTests.csproj", "{F54C4C0E-4C72-4F88-A389-7F6DE3CCB745}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -466,6 +468,14 @@ Global
|
|||
{30B2D907-5861-4F39-ABAD-C4ABF1B3470E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{30B2D907-5861-4F39-ABAD-C4ABF1B3470E}.Release|x86.ActiveCfg = Release|x86
|
||||
{30B2D907-5861-4F39-ABAD-C4ABF1B3470E}.Release|x86.Build.0 = Release|x86
|
||||
{F54C4C0E-4C72-4F88-A389-7F6DE3CCB745}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F54C4C0E-4C72-4F88-A389-7F6DE3CCB745}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F54C4C0E-4C72-4F88-A389-7F6DE3CCB745}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{F54C4C0E-4C72-4F88-A389-7F6DE3CCB745}.Debug|x86.Build.0 = Debug|x86
|
||||
{F54C4C0E-4C72-4F88-A389-7F6DE3CCB745}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F54C4C0E-4C72-4F88-A389-7F6DE3CCB745}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F54C4C0E-4C72-4F88-A389-7F6DE3CCB745}.Release|x86.ActiveCfg = Release|x86
|
||||
{F54C4C0E-4C72-4F88-A389-7F6DE3CCB745}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -7,7 +7,8 @@ before_build:
|
|||
build_script:
|
||||
- msbuild /verbosity:minimal "SafeExamBrowser.sln"
|
||||
test_script:
|
||||
- .\packages\OpenCover.4.7.922\tools\OpenCover.Console.exe -register -target:"vstest.console.exe" -targetargs:"/logger:Appveyor .\SafeExamBrowser.Client.UnitTests\bin\%PLATFORM%\%CONFIGURATION%\SafeExamBrowser.Client.UnitTests.dll" -filter:"+[*]* -[*.UnitTests]* -[*Moq*]*" -mergebyhash -output:"coverage.xml"
|
||||
- .\packages\OpenCover.4.7.922\tools\OpenCover.Console.exe -register -target:"vstest.console.exe" -targetargs:"/logger:Appveyor .\SafeExamBrowser.Browser.UnitTests\bin\%PLATFORM%\%CONFIGURATION%\SafeExamBrowser.Browser.UnitTests.dll" -filter:"+[*]* -[*.UnitTests]* -[*Moq*]*" -mergebyhash -output:"coverage.xml"
|
||||
- .\packages\OpenCover.4.7.922\tools\OpenCover.Console.exe -register -target:"vstest.console.exe" -targetargs:"/logger:Appveyor .\SafeExamBrowser.Client.UnitTests\bin\%PLATFORM%\%CONFIGURATION%\SafeExamBrowser.Client.UnitTests.dll" -filter:"+[*]* -[*.UnitTests]* -[*Moq*]*" -mergebyhash -mergeoutput -output:"coverage.xml"
|
||||
- .\packages\OpenCover.4.7.922\tools\OpenCover.Console.exe -register -target:"vstest.console.exe" -targetargs:"/logger:Appveyor .\SafeExamBrowser.Communication.UnitTests\bin\%PLATFORM%\%CONFIGURATION%\SafeExamBrowser.Communication.UnitTests.dll" -filter:"+[*]* -[*.UnitTests]* -[*Moq*]*" -mergebyhash -mergeoutput -output:"coverage.xml"
|
||||
- .\packages\OpenCover.4.7.922\tools\OpenCover.Console.exe -register -target:"vstest.console.exe" -targetargs:"/logger:Appveyor .\SafeExamBrowser.Configuration.UnitTests\bin\%PLATFORM%\%CONFIGURATION%\SafeExamBrowser.Configuration.UnitTests.dll" -filter:"+[*]* -[*.UnitTests]* -[*Moq*]*" -mergebyhash -mergeoutput -output:"coverage.xml"
|
||||
- .\packages\OpenCover.4.7.922\tools\OpenCover.Console.exe -register -target:"vstest.console.exe" -targetargs:"/logger:Appveyor .\SafeExamBrowser.Core.UnitTests\bin\%PLATFORM%\%CONFIGURATION%\SafeExamBrowser.Core.UnitTests.dll" -filter:"+[*]* -[*.UnitTests]* -[*Moq*]*" -mergebyhash -mergeoutput -output:"coverage.xml"
|
||||
|
|
Loading…
Reference in a new issue