diff --git a/.gitignore b/.gitignore
index f1e3d20..5566f35 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@
*.user
*.userosscache
*.sln.docstates
+*.sln.DotSettings
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
diff --git a/README.md b/README.md
index ca0c90e..a0ef203 100644
--- a/README.md
+++ b/README.md
@@ -2,11 +2,13 @@
Light weight REST service framework for ASP.NET Core
### Branch Status
-[![NuGet](https://img.shields.io/nuget/v/RService.IO.svg)](https://www.nuget.org/packages/RService.IO/) [![NuGet](https://img.shields.io/nuget/v/RService.IO.Abstractions.svg)](https://www.nuget.org/packages/RService.IO.Abstractions/)
+[![NuGet](https://img.shields.io/nuget/v/RService.IO.svg)](https://www.nuget.org/packages/RService.IO/)
+[![NuGet](https://img.shields.io/nuget/v/RService.IO.Abstractions.svg)](https://www.nuget.org/packages/RService.IO.Abstractions/)
+[![NuGet](https://img.shields.io/nuget/v/RService.IO.Authorization.svg)](https://www.nuget.org/packages/RService.IO.Authorization/)
#### Master
[![Build status](https://ci.appveyor.com/api/projects/status/t65h3ok91ljwm30t/branch/master?svg=true)](https://ci.appveyor.com/project/Stoom/rservice-io/branch/master)
-[![Coverage Status](https://coveralls.io/repos/github/Stoom/RService.IO/badge.svg?branch=master)](https://coveralls.io/github/Stoom/RService.IO?branch=master)
+[![Coverage Status](https://coveralls.io/repos/github/Stoom/RService.IO/badge.svg?branch=master)](https://coveralls.io/github/Stoom/RService.IO?branch=master)
[![Codecov branch](https://img.shields.io/codecov/c/github/Stoom/RService.IO/master.svg)](https://codecov.io/gh/Stoom/RService.IO/branch/master)
#### Develop
[![Build status](https://ci.appveyor.com/api/projects/status/t65h3ok91ljwm30t/branch/develop?svg=true)](https://ci.appveyor.com/project/Stoom/rservice-io/branch/develop)
diff --git a/RService.IO.sln b/RService.IO.sln
index 845eb91..da3f652 100644
--- a/RService.IO.sln
+++ b/RService.IO.sln
@@ -1,59 +1,73 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25420.1
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B748CB97-7861-4FC7-828D-11C44E540630}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{64F366F9-AA78-455D-B3C7-94B9F14814AA}"
- ProjectSection(SolutionItems) = preProject
- appveyor.yml = appveyor.yml
- global.json = global.json
- LICENSE = LICENSE
- NuGet.config = NuGet.config
- README.md = README.md
- EndProjectSection
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{1F1CF499-A7DD-4BEE-B9B5-E5A87E0ADDA4}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "RService.IO.Tests", "test\RService.IO.Tests\RService.IO.Tests.xproj", "{29E250BF-7D21-4B2D-81DD-F527C0CC3286}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "RService.IO", "src\RService.IO\RService.IO.xproj", "{80003DA0-A02B-487A-8E22-973B5A4BF0CD}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Rservice.IO.Tests.Integration", "test\Rservice.IO.Tests.Integration\Rservice.IO.Tests.Integration.xproj", "{CE9393A2-ED69-4748-913B-3C11143957F5}"
-EndProject
-Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "RService.IO.Abstractions", "src\RService.IO.Abstractions\RService.IO.Abstractions.xproj", "{4474DEEE-06F5-4706-97A2-A437E258F485}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {29E250BF-7D21-4B2D-81DD-F527C0CC3286}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {29E250BF-7D21-4B2D-81DD-F527C0CC3286}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {29E250BF-7D21-4B2D-81DD-F527C0CC3286}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {29E250BF-7D21-4B2D-81DD-F527C0CC3286}.Release|Any CPU.Build.0 = Release|Any CPU
- {80003DA0-A02B-487A-8E22-973B5A4BF0CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {80003DA0-A02B-487A-8E22-973B5A4BF0CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {80003DA0-A02B-487A-8E22-973B5A4BF0CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {80003DA0-A02B-487A-8E22-973B5A4BF0CD}.Release|Any CPU.Build.0 = Release|Any CPU
- {CE9393A2-ED69-4748-913B-3C11143957F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {CE9393A2-ED69-4748-913B-3C11143957F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {CE9393A2-ED69-4748-913B-3C11143957F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {CE9393A2-ED69-4748-913B-3C11143957F5}.Release|Any CPU.Build.0 = Release|Any CPU
- {4474DEEE-06F5-4706-97A2-A437E258F485}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {4474DEEE-06F5-4706-97A2-A437E258F485}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {4474DEEE-06F5-4706-97A2-A437E258F485}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {4474DEEE-06F5-4706-97A2-A437E258F485}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {29E250BF-7D21-4B2D-81DD-F527C0CC3286} = {1F1CF499-A7DD-4BEE-B9B5-E5A87E0ADDA4}
- {80003DA0-A02B-487A-8E22-973B5A4BF0CD} = {B748CB97-7861-4FC7-828D-11C44E540630}
- {CE9393A2-ED69-4748-913B-3C11143957F5} = {1F1CF499-A7DD-4BEE-B9B5-E5A87E0ADDA4}
- {4474DEEE-06F5-4706-97A2-A437E258F485} = {B748CB97-7861-4FC7-828D-11C44E540630}
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B748CB97-7861-4FC7-828D-11C44E540630}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{64F366F9-AA78-455D-B3C7-94B9F14814AA}"
+ ProjectSection(SolutionItems) = preProject
+ appveyor.yml = appveyor.yml
+ global.json = global.json
+ LICENSE = LICENSE
+ NuGet.config = NuGet.config
+ README.md = README.md
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{1F1CF499-A7DD-4BEE-B9B5-E5A87E0ADDA4}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "RService.IO.Tests", "test\RService.IO.Tests\RService.IO.Tests.xproj", "{29E250BF-7D21-4B2D-81DD-F527C0CC3286}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "RService.IO", "src\RService.IO\RService.IO.xproj", "{80003DA0-A02B-487A-8E22-973B5A4BF0CD}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Rservice.IO.Tests.Integration", "test\Rservice.IO.Tests.Integration\Rservice.IO.Tests.Integration.xproj", "{CE9393A2-ED69-4748-913B-3C11143957F5}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "RService.IO.Abstractions", "src\RService.IO.Abstractions\RService.IO.Abstractions.xproj", "{4474DEEE-06F5-4706-97A2-A437E258F485}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "RService.IO.Authorization", "src\RService.IO.Authorization\RService.IO.Authorization.xproj", "{4FA0A7F5-B8AC-4BE0-BD20-7E2CDB16AE8B}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "RService.IO.Authorization.Tests", "test\RService.IO.Authorization.Tests\RService.IO.Authorization.Tests.xproj", "{44B66719-E3DC-4F39-A67D-196BCB9A0FA7}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {29E250BF-7D21-4B2D-81DD-F527C0CC3286}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {29E250BF-7D21-4B2D-81DD-F527C0CC3286}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {29E250BF-7D21-4B2D-81DD-F527C0CC3286}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {29E250BF-7D21-4B2D-81DD-F527C0CC3286}.Release|Any CPU.Build.0 = Release|Any CPU
+ {80003DA0-A02B-487A-8E22-973B5A4BF0CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {80003DA0-A02B-487A-8E22-973B5A4BF0CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {80003DA0-A02B-487A-8E22-973B5A4BF0CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {80003DA0-A02B-487A-8E22-973B5A4BF0CD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CE9393A2-ED69-4748-913B-3C11143957F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CE9393A2-ED69-4748-913B-3C11143957F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CE9393A2-ED69-4748-913B-3C11143957F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CE9393A2-ED69-4748-913B-3C11143957F5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4474DEEE-06F5-4706-97A2-A437E258F485}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4474DEEE-06F5-4706-97A2-A437E258F485}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4474DEEE-06F5-4706-97A2-A437E258F485}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4474DEEE-06F5-4706-97A2-A437E258F485}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4FA0A7F5-B8AC-4BE0-BD20-7E2CDB16AE8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4FA0A7F5-B8AC-4BE0-BD20-7E2CDB16AE8B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4FA0A7F5-B8AC-4BE0-BD20-7E2CDB16AE8B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4FA0A7F5-B8AC-4BE0-BD20-7E2CDB16AE8B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {44B66719-E3DC-4F39-A67D-196BCB9A0FA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {44B66719-E3DC-4F39-A67D-196BCB9A0FA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {44B66719-E3DC-4F39-A67D-196BCB9A0FA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {44B66719-E3DC-4F39-A67D-196BCB9A0FA7}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {29E250BF-7D21-4B2D-81DD-F527C0CC3286} = {1F1CF499-A7DD-4BEE-B9B5-E5A87E0ADDA4}
+ {80003DA0-A02B-487A-8E22-973B5A4BF0CD} = {B748CB97-7861-4FC7-828D-11C44E540630}
+ {CE9393A2-ED69-4748-913B-3C11143957F5} = {1F1CF499-A7DD-4BEE-B9B5-E5A87E0ADDA4}
+ {4474DEEE-06F5-4706-97A2-A437E258F485} = {B748CB97-7861-4FC7-828D-11C44E540630}
+ {4FA0A7F5-B8AC-4BE0-BD20-7E2CDB16AE8B} = {B748CB97-7861-4FC7-828D-11C44E540630}
+ {44B66719-E3DC-4F39-A67D-196BCB9A0FA7} = {1F1CF499-A7DD-4BEE-B9B5-E5A87E0ADDA4}
+ EndGlobalSection
+EndGlobal
diff --git a/appveyor.yml b/appveyor.yml
index 526b190..e548647 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,6 +1,5 @@
version: '0.1.1-{build}'
configuration:
-- Debug
- Release
platform: Any CPU
environment:
@@ -19,18 +18,29 @@ before_build:
build_script:
- dotnet build "src\RService.IO" -c %CONFIGURATION% --version-suffix %LABEL%
- dotnet build "src\RService.IO.Abstractions" -c %CONFIGURATION% --version-suffix %LABEL%
+- dotnet build "src\RService.IO.Authorization" -c %CONFIGURATION% --version-suffix %LABEL%
test_script:
- ps: '& ${env:homedrive}${env:homepath}\.nuget\packages\OpenCover\4.6.519\tools\OpenCover.Console.exe "-target:C:\Program Files\dotnet\dotnet.exe" -targetargs:"test .\test\RService.IO.Tests" -register:user -filter:"+[RService.IO*]* -[RService.IO.Tests*]*" -output:coverage.xml -oldStyle'
+ - ps: '& ${env:homedrive}${env:homepath}\.nuget\packages\OpenCover\4.6.519\tools\OpenCover.Console.exe "-target:C:\Program Files\dotnet\dotnet.exe" -targetargs:"test .\test\RService.IO.Authorization.Tests" -register:user -filter:"+[RService.IO*]* -[RService.IO.Authorization.Tests*]*" -mergeoutput -output:coverage.xml -oldStyle'
- ps: '& ${env:homedrive}${env:homepath}\.nuget\packages\OpenCover\4.6.519\tools\OpenCover.Console.exe "-target:C:\Program Files\dotnet\dotnet.exe" -targetargs:"test .\test\RService.IO.Tests.Integration" -register:user -filter:"+[RService.IO*]* -[RService.IO.Tests*]*" -mergeoutput -output:coverage.xml -oldStyle'
- ps: '& ${env:homedrive}${env:homepath}\.nuget\packages\coveralls.io\1.3.4\tools\coveralls.net.exe --opencover coverage.xml'
- ps: pip install codecov; codecov -f coverage.xml -X gcov
after_test:
-#- dotnet pack "src\LibNETStandard10" -c %CONFIGURATION% --no-build --version-suffix %LABEL% -o artifacts
-#- dotnet publish "src\ConsoleApplication" -c %CONFIGURATION% --no-build --version-suffix %LABEL% -o artifacts\ConsoleApplication
- ps: dotnet pack "src\RService.IO" -c ${env:CONFIGUREATION} --no-build --version-suffix ${env:LABEL} -o artifacts
- ps: dotnet pack "src\RService.IO.Abstractions" -c ${env:CONFIGUREATION} --no-build --version-suffix ${env:LABEL} -o artifacts
+ - ps: dotnet pack "src\RService.IO.Authorization" -c ${env:CONFIGUREATION} --no-build --version-suffix ${env:LABEL} -o artifacts
artifacts:
- path: '**/RService.IO.*.nupkg'
name: NuGet Package
+deploy:
+ - provider: NuGet
+ api_key:
+ secure: TafSc421VlrLm7iCk6Xm2/ss0aZT8EXfcU2DEarrIeoWxg+NxXH8apUKAV+oT8Kp
+ skip_symbols: false
+ artifact: /.*\.nupkg/
+ on:
+ branch: master
+ configuration: Release
+ appveyor_repo_tag: true
#cache:
#- '%USERPROFILE%\.nuget\packages'
\ No newline at end of file
diff --git a/src/RService.IO.Abstractions/Delegate.cs b/src/RService.IO.Abstractions/Delegate.cs
index fce4321..5db5da6 100644
--- a/src/RService.IO.Abstractions/Delegate.cs
+++ b/src/RService.IO.Abstractions/Delegate.cs
@@ -12,10 +12,10 @@ public static class Delegate
/// The service's response.
public delegate object Activator(object target, params object[] args);
///
- /// Creates a DTO based on JSON.
+ /// Creates a DTO based on a request body.
///
- /// JSON to create DTO from.
+ /// The request body to create DTO from.
/// The DTO.
- public delegate object DtoCtor(string json);
+ public delegate object DtoCtor(string body);
}
}
\ No newline at end of file
diff --git a/src/RService.IO/DelegateFactory.cs b/src/RService.IO.Abstractions/DelegateFactory.cs
similarity index 88%
rename from src/RService.IO/DelegateFactory.cs
rename to src/RService.IO.Abstractions/DelegateFactory.cs
index 0f22fb2..2a14f9b 100644
--- a/src/RService.IO/DelegateFactory.cs
+++ b/src/RService.IO.Abstractions/DelegateFactory.cs
@@ -3,11 +3,10 @@
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
-using Delegate = RService.IO.Abstractions.Delegate;
-namespace RService.IO
+namespace RService.IO.Abstractions
{
- public sealed class DelegateFactory
+ public static class DelegateFactory
{
///
/// Generates a dynamic method call.
@@ -60,18 +59,17 @@ public static Delegate.Activator GenerateMethodCall(MethodInfo method)
/// Generates a dynamic DTO.
///
/// The of the DTO to create.
+ /// The of the generic deserializer.
/// A delegate.
/// The results from this function should be cached.
- public static Delegate.DtoCtor GenerateDtoCtor(Type dtoType)
+ public static Delegate.DtoCtor GenerateDtoCtor(Type dtoType, MethodInfo deserializerMethod)
{
// Methods
- var deserializeMethod = typeof(NetJSON.NetJSON)
- .GetMethod("Deserialize", new[] { typeof(string) })
- .MakeGenericMethod(dtoType);
+ var deserializeMethod = deserializerMethod.MakeGenericMethod(dtoType);
var dtoCtor = dtoType.GetConstructors().First();
// Properties and fields
- var jsonParam = Expression.Parameter(typeof(string), "Json Body");
+ var bodyParam = Expression.Parameter(typeof(string), "Body");
var reqDtoVar = Expression.Variable(dtoType, "Request Dto");
// Return
@@ -86,7 +84,7 @@ public static Delegate.DtoCtor GenerateDtoCtor(Type dtoType)
var callExpressions = new List
{
// Deserialize or ctor
- Expression.Assign(reqDtoVar, Expression.Call(deserializeMethod, jsonParam)),
+ Expression.Assign(reqDtoVar, Expression.Call(deserializeMethod, bodyParam)),
Expression.IfThen(
Expression.Equal(reqDtoVar, nullConst),
Expression.Assign(reqDtoVar, Expression.New(dtoCtor))
@@ -100,7 +98,7 @@ public static Delegate.DtoCtor GenerateDtoCtor(Type dtoType)
var lambda = Expression.Lambda(
Expression.Convert(call, typeof(object)),
- jsonParam);
+ bodyParam);
return lambda.Compile();
}
diff --git a/src/RService.IO.Abstractions/Properties/AssemblyInfo.cs b/src/RService.IO.Abstractions/Properties/AssemblyInfo.cs
index 3226436..b6f5c40 100644
--- a/src/RService.IO.Abstractions/Properties/AssemblyInfo.cs
+++ b/src/RService.IO.Abstractions/Properties/AssemblyInfo.cs
@@ -1,5 +1,4 @@
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
diff --git a/src/RService.IO.Abstractions/IAuthProvider.cs b/src/RService.IO.Abstractions/Providers/IAuthProvider.cs
similarity index 95%
rename from src/RService.IO.Abstractions/IAuthProvider.cs
rename to src/RService.IO.Abstractions/Providers/IAuthProvider.cs
index b17b499..6c69a25 100644
--- a/src/RService.IO.Abstractions/IAuthProvider.cs
+++ b/src/RService.IO.Abstractions/Providers/IAuthProvider.cs
@@ -2,7 +2,7 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
-namespace RService.IO.Abstractions
+namespace RService.IO.Abstractions.Providers
{
///
/// Determines if a service endpoint is authenticated and authorized to be executed.
diff --git a/src/RService.IO.Abstractions/ISerializationProvider.cs b/src/RService.IO.Abstractions/Providers/ISerializationProvider.cs
similarity index 93%
rename from src/RService.IO.Abstractions/ISerializationProvider.cs
rename to src/RService.IO.Abstractions/Providers/ISerializationProvider.cs
index 41f1d6a..e9aa926 100644
--- a/src/RService.IO.Abstractions/ISerializationProvider.cs
+++ b/src/RService.IO.Abstractions/Providers/ISerializationProvider.cs
@@ -1,7 +1,7 @@
using System;
using Microsoft.AspNetCore.Http;
-namespace RService.IO.Abstractions
+namespace RService.IO.Abstractions.Providers
{
///
/// Describes how to hydrate (deserialize), and dehydrate (serialize)
diff --git a/src/RService.IO.Abstractions/IServiceProvider.cs b/src/RService.IO.Abstractions/Providers/IServiceProvider.cs
similarity index 89%
rename from src/RService.IO.Abstractions/IServiceProvider.cs
rename to src/RService.IO.Abstractions/Providers/IServiceProvider.cs
index 2efb527..c15300c 100644
--- a/src/RService.IO.Abstractions/IServiceProvider.cs
+++ b/src/RService.IO.Abstractions/Providers/IServiceProvider.cs
@@ -1,7 +1,7 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
-namespace RService.IO.Abstractions
+namespace RService.IO.Abstractions.Providers
{
///
/// Supports reading request and calling user service endpoints.
diff --git a/src/RService.IO.Abstractions/project.json b/src/RService.IO.Abstractions/project.json
index d233710..6e5fa07 100644
--- a/src/RService.IO.Abstractions/project.json
+++ b/src/RService.IO.Abstractions/project.json
@@ -1,6 +1,6 @@
{
"title": "RService.IO.Abstractions",
- "version": "0.3.0",
+ "version": "0.4.0",
"packOptions": {
"summary": "The abstractions required for implementing a RService.IO service and routes.",
@@ -24,8 +24,9 @@
},
"dependencies": {
- "Microsoft.AspNetCore.Http.Abstractions": "1.0.0",
- "Microsoft.AspNetCore.Routing.Abstractions": "1.0.0"
+ "Microsoft.AspNetCore.Http.Abstractions": "1.1.0",
+ "Microsoft.AspNetCore.Routing.Abstractions": "1.1.0",
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "1.1.0"
},
"frameworks": {
diff --git a/src/RService.IO.Authorization/DependencyInjection/ServiceCollectionExtensions.cs b/src/RService.IO.Authorization/DependencyInjection/ServiceCollectionExtensions.cs
new file mode 100644
index 0000000..09bb758
--- /dev/null
+++ b/src/RService.IO.Authorization/DependencyInjection/ServiceCollectionExtensions.cs
@@ -0,0 +1,20 @@
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using RService.IO.Abstractions.Providers;
+using RService.IO.Authorization.Providers;
+
+namespace RService.IO.Authorization.DependencyInjection
+{
+ public static class ServiceCollectionExtensions
+ {
+ public static IServiceCollection AddRServiceIoAuthorization(
+ this IServiceCollection services)
+ {
+ services.AddOptions();
+
+ services.TryAddTransient();
+
+ return services;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/RService.IO.Authorization/Properties/AssemblyInfo.cs b/src/RService.IO.Authorization/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a4f791d
--- /dev/null
+++ b/src/RService.IO.Authorization/Properties/AssemblyInfo.cs
@@ -0,0 +1,25 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("RService.IO.Authorization")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("RService.IO.Authorization")]
+[assembly: AssemblyCopyright("Copyright © 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// 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)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("4FA0A7F5-B8AC-4BE0-BD20-7E2CDB16AE8B")]
\ No newline at end of file
diff --git a/src/RService.IO/Providers/AuthProvider.cs b/src/RService.IO.Authorization/Providers/AuthProvider.cs
similarity index 97%
rename from src/RService.IO/Providers/AuthProvider.cs
rename to src/RService.IO.Authorization/Providers/AuthProvider.cs
index 53183ed..ebb09c3 100644
--- a/src/RService.IO/Providers/AuthProvider.cs
+++ b/src/RService.IO.Authorization/Providers/AuthProvider.cs
@@ -1,108 +1,109 @@
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Security.Claims;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Authorization;
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Internal;
-using RService.IO.Abstractions;
-
-namespace RService.IO.Providers
-{
- ///
- /// Default implementation of .
- ///
- public class AuthProvider : IAuthProvider
- {
- private readonly IAuthorizationPolicyProvider _policyProvider;
- private readonly ConcurrentDictionary> _cachedAuthAttributes;
-
- ///
- /// Constructs the default auth provider.
- ///
- ///
- /// The to check authorization to specified methods and classes.
- ///
- public AuthProvider(IAuthorizationPolicyProvider provider)
- {
- if (provider == null)
- throw new ArgumentNullException(nameof(provider));
-
- _policyProvider = provider;
- _cachedAuthAttributes = new ConcurrentDictionary>();
- }
-
- ///
- public Task IsAuthorizedAsync(HttpContext ctx, ServiceMetadata metadata)
- {
- if (ctx == null)
- throw new ArgumentNullException(nameof(ctx));
- if (metadata == null)
- throw new ArgumentNullException(nameof(metadata));
-
- IEnumerable
public class RServiceProvider : IServiceProvider
{
diff --git a/src/RService.IO/RServiceMiddleware.cs b/src/RService.IO/RServiceMiddleware.cs
index 05e65e3..fd59684 100644
--- a/src/RService.IO/RServiceMiddleware.cs
+++ b/src/RService.IO/RServiceMiddleware.cs
@@ -7,7 +7,7 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using RService.IO.Abstractions;
-using IServiceProvider = RService.IO.Abstractions.IServiceProvider;
+using IServiceProvider = RService.IO.Abstractions.Providers.IServiceProvider;
namespace RService.IO
{
@@ -19,19 +19,18 @@ public class RServiceMiddleware
private readonly IServiceProvider _serviceProvider;
private readonly RServiceOptions _options;
- public RServiceMiddleware(RequestDelegate next, ILoggerFactory logFactory, RService service, IServiceProvider serviceProvider, IOptions options)
+ public RServiceMiddleware(RequestDelegate next, ILoggerFactory logFactory, RService service,
+ IServiceProvider serviceProvider, IOptions options)
{
_next = next;
_logger = logFactory.CreateLogger();
_service = service;
_serviceProvider = serviceProvider;
- _options = options?.Value;
+ _options = options.Value;
}
public async Task Invoke(HttpContext context)
{
- var exceptionFilter = context.RequestServices.GetService();
-
var routeData = (context.GetRouteData()?.Routers.Count >= 3)
? (context.GetRouteData()?.Routers[1] as Route)
: null;
@@ -77,7 +76,7 @@ public async Task Invoke(HttpContext context)
await context.Response.WriteAsync(exc.Message);
}
- exceptionFilter?.OnException(context, exc);
+ context.RequestServices.GetService()?.OnException(context, exc);
}
}
}
diff --git a/src/RService.IO/Router/RServiceRouterMiddleware.cs b/src/RService.IO/Router/RServiceRouterMiddleware.cs
index 34462a8..418a7d6 100644
--- a/src/RService.IO/Router/RServiceRouterMiddleware.cs
+++ b/src/RService.IO/Router/RServiceRouterMiddleware.cs
@@ -2,7 +2,7 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Logging;
-using RService.IO.Abstractions;
+using RoutingFeature = RService.IO.Abstractions.RoutingFeature;
namespace RService.IO.Router
{
diff --git a/src/RService.IO/project.json b/src/RService.IO/project.json
index 472ab47..59e01b1 100644
--- a/src/RService.IO/project.json
+++ b/src/RService.IO/project.json
@@ -1,6 +1,6 @@
{
"title": "RService.IO",
- "version": "0.3.0",
+ "version": "0.4.0",
"packOptions": {
"summary": "A web service framework for dotnet core loosely based on ServiceStack v3",
"releaseNotes": "Initial alpha release",
@@ -25,17 +25,16 @@
}
},
"dependencies": {
- "Microsoft.AspNetCore.Authorization": "1.0.0",
- "Microsoft.AspNetCore.Hosting.Abstractions": "1.0.0",
- "Microsoft.AspNetCore.Http": "1.0.0",
- "Microsoft.AspNetCore.Http.Abstractions": "1.0.0",
- "Microsoft.AspNetCore.Routing": "1.0.0",
- "Microsoft.Extensions.DependencyInjection": "1.0.0",
- "Microsoft.Extensions.SecurityHelper.Sources": "1.0.0-rtm-21431",
+ "Microsoft.AspNetCore.Hosting.Abstractions": "1.1.0",
+ "Microsoft.AspNetCore.Http": "1.1.0",
+ "Microsoft.AspNetCore.Http.Abstractions": "1.1.0",
+ "Microsoft.AspNetCore.Routing": "1.1.0",
+ "Microsoft.Extensions.DependencyInjection": "1.1.0",
"NetJSON": "1.2.1.4",
- "RService.IO.Abstractions": "0.3.*",
+ "RService.IO.Abstractions": "0.4.*",
+ "RService.IO.Authorization": "0.4.*",
"System.ComponentModel.Primitives": "4.1.0",
- "System.Reflection.Emit.Lightweight": "4.0.1"
+ "System.Reflection.Emit.Lightweight": "4.3.0"
},
"frameworks": {
"netstandard1.6": {
diff --git a/test/RService.IO.Tests/Providers/AuthProviderTests.cs b/test/RService.IO.Authorization.Tests/AuthProviderTests.cs
similarity index 96%
rename from test/RService.IO.Tests/Providers/AuthProviderTests.cs
rename to test/RService.IO.Authorization.Tests/AuthProviderTests.cs
index c4338ce..a4f4401 100644
--- a/test/RService.IO.Tests/Providers/AuthProviderTests.cs
+++ b/test/RService.IO.Authorization.Tests/AuthProviderTests.cs
@@ -1,550 +1,551 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Security.Claims;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Http.Authentication;
-using Microsoft.Extensions.DependencyInjection;
-using Moq;
-using FluentAssertions;
-using Microsoft.AspNetCore.Authorization;
-using RService.IO.Abstractions;
-using RService.IO.Providers;
-using Xunit;
-
-namespace RService.IO.Tests.Providers
-{
- public class AuthProviderTests
- {
- private readonly HttpContext _anonymousContext;
- private readonly HttpContext _authorizedContext;
- private readonly IAuthProvider _anonymousAuthProvider;
- private readonly IAuthProvider _authorizedAuthProvider;
-
- public AuthProviderTests()
- {
- _anonymousContext = GetContext(s => s.AddTransient(), true);
- _authorizedContext = GetContext(s => s.AddTransient());
- _anonymousAuthProvider = GetAuthProvider(_anonymousContext);
- _authorizedAuthProvider = GetAuthProvider(_authorizedContext);
- }
-
- [Fact]
- public void InvalidUser()
- {
- var context = GetContext(service => service.AddAuthorization());
- context.User.Identities.Any(x => x.IsAuthenticated).Should().BeTrue();
- }
-
- [Fact]
- public void Ctor__ThrowsExceptionIfNullProvider()
- {
- // ReSharper disable once ObjectCreationAsStatement
- Action act = () => new AuthProvider(null);
-
- act.ShouldThrow().And.Message.Should().Contain("provider");
- }
-
- [Fact]
- public void IsAuthorizedAsync_Filter__ThrowsExceptionIfNullContext()
- {
- Func act = async () => await _authorizedAuthProvider.IsAuthorizedAsync(null, (IEnumerable)null);
-
- act.ShouldThrow().And.Message.Should().Contain("ctx");
- }
-
- [Fact]
- public void IsAuthorizedAsync_Filter__ThrowsExceptionIfNullFilters()
- {
- Func act = async () => await _anonymousAuthProvider.IsAuthorizedAsync(_anonymousContext, (IEnumerable)null);
-
- act.ShouldThrow().And.Message.Should().Contain("authorizationFilter");
- }
-
- [Fact]
- public void IsAuthorizedAsync_Metadata__ThrowsExceptionIfNullContext()
- {
- Func act = async () => await _anonymousAuthProvider.IsAuthorizedAsync(null, (ServiceMetadata)null);
-
- act.ShouldThrow().And.Message.Should().Contain("ctx");
- }
-
- [Fact]
- public void IsAuthorizedAsync_Metadata__ThrowsExceptionIfNullMetadata()
- {
- Func act = async () => await _anonymousAuthProvider.IsAuthorizedAsync(_anonymousContext, (ServiceMetadata)null);
-
- act.ShouldThrow().And.Message.Should().Contain("metadata");
- }
-
- [Fact]
- public async void IsAuthorizedAsync__AnonymousReturnsTrueForAnonymous()
- {
- var attributes = new[] { new AllowAnonymousAttribute() };
-
- var results = await _anonymousAuthProvider.IsAuthorizedAsync(_anonymousContext, attributes);
- results.Should().BeTrue();
- }
-
- [Fact]
- public async void IsAuthorizedAsync__AnonymousReturnsFalseForAuthorized()
- {
- var attributes = new[] { new AuthorizeAttribute() };
-
- var results = await _anonymousAuthProvider.IsAuthorizedAsync(_anonymousContext, attributes);
- results.Should().BeFalse();
- }
-
- [Fact]
- public async void IsAuthorizedAsync__AuthorizedRoleReturnsTrue()
- {
- var attributes = new[] { new AuthorizeAttribute { Roles = "Administrator" } };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, attributes);
- results.Should().BeTrue();
- }
-
- [Fact]
- public async void IsAuthorizedAsync__UnauthorizedRoleReturnsFalse()
- {
- var authProvider = GetAuthProvider(_authorizedContext);
- var attributes = new[] { new AuthorizeAttribute { Roles = "Poweruser" } };
-
- var results = await authProvider.IsAuthorizedAsync(_authorizedContext, attributes);
- results.Should().BeFalse();
- }
-
- [Fact]
- public async void IsAuthorizedAsync__AuthoriedWithNoAttributes()
- {
- var attributes = new object[] { };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, attributes);
- results.Should().BeTrue();
- }
-
- [Fact]
- public async void IsAuthorizedAsync__AuthorizedWithSpecifiedScheme()
- {
- var attributes = new[]
- {
- new AuthorizeAttribute
- {
- Roles = "Administrator",
- ActiveAuthenticationSchemes = "Basic"
- }
- };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, attributes);
- results.Should().BeTrue();
- }
-
- [Fact]
- public async void IsAuthorizedAsync__NotAuthorizedWithSpecifiedMissingScheme()
- {
- var attributes = new[]
- {
- new AuthorizeAttribute
- {
- Roles = "Administrator",
- ActiveAuthenticationSchemes = "FizzBuzzScheme"
- }
- };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, attributes);
- results.Should().BeFalse();
- }
-
- [Fact]
- public async void IsAuthorizedAsync__ProvideDefaultIdentityIfClaimsFails()
- {
- var attributes = new[]
- {
- new AuthorizeAttribute
- {
- Roles = "Administrator",
- ActiveAuthenticationSchemes = "Basic"
- }
- };
-
- _anonymousContext.User.Should().BeNull();
- await _anonymousAuthProvider.IsAuthorizedAsync(_anonymousContext, attributes);
- _anonymousContext.User.Should().NotBeNull();
- }
-
- [Fact]
- public async void IsAuthorizedAsync__AuthorizedWhenSpecifingMultipleRolesInSingleAttr()
- {
- var attributes = new[] { new AuthorizeAttribute { Roles = "Administrator, PowerUser" } };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, attributes);
- results.Should().BeTrue();
- }
-
- [Fact]
- public async void IsAuthorizedAsync__AuthorizedRequireAllAttrToBeAuthorized()
- {
- var attributes = new[]
- {
- new AuthorizeAttribute { Roles = "Administrator" },
- new AuthorizeAttribute { Roles = "PowerUser" }
- };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, attributes);
- results.Should().BeFalse();
- }
-
- [Fact]
- public async void IsAuthorizedAsync_Metadata__HandlesSingleSuccessfulMethod()
- {
- var metadata = new ServiceMetadata
- {
- Ident = Guid.NewGuid().ToString(),
- Service = typeof(ServiceMetadata).GetTypeInfo(),
- Method = typeof(MethodAuth).GetPublicMethods().Single(x => x.Name == "Single")
- };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
- results.Should().BeTrue();
- }
-
- [Fact]
- public async void IsAuthorizedAsync_Metadata__HandlesSingleFailedMethod()
- {
- var metadata = new ServiceMetadata
- {
- Ident = Guid.NewGuid().ToString(),
- Service = typeof(ServiceMetadata).GetTypeInfo(),
- Method = typeof(MethodAuth).GetPublicMethods().Single(x => x.Name == "SingleFail")
- };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
- results.Should().BeFalse();
- }
-
- [Fact]
- public async void IsAuthorizedAsync_Metadata__HandlesMultipleSuccessfulMethod()
- {
- var metadata = new ServiceMetadata
- {
- Ident = Guid.NewGuid().ToString(),
- Service = typeof(ServiceMetadata).GetTypeInfo(),
- Method = typeof(MethodAuth).GetPublicMethods().Single(x => x.Name == "Multiple")
- };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
- results.Should().BeTrue();
- }
-
- [Fact]
- public async void IsAuthorizedAsync_Metadata__HandlesMultipleFailedMethod()
- {
- var metadata = new ServiceMetadata
- {
- Ident = Guid.NewGuid().ToString(),
- Service = typeof(ServiceMetadata).GetTypeInfo(),
- Method = typeof(MethodAuth).GetPublicMethods().Single(x => x.Name == "MultipleFail")
- };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
- results.Should().BeFalse();
- }
-
- [Fact]
- public async void IsAuthorizedAsync_Metadata__HandlesSingleSuccessfulClass()
- {
- var metadata = new ServiceMetadata
- {
- Ident = Guid.NewGuid().ToString(),
- Service = typeof(SingleClassAuth).GetTypeInfo(),
- Method = typeof(SingleClassAuth).GetPublicMethods().Single(x => x.Name == "Any")
- };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
- results.Should().BeTrue();
- }
-
- [Fact]
- public async void IsAuthorizedAsync_Metadata__HandlesSingleFailedClass()
- {
- var metadata = new ServiceMetadata
- {
- Ident = Guid.NewGuid().ToString(),
- Service = typeof(SingleFailClassAuth).GetTypeInfo(),
- Method = typeof(SingleFailClassAuth).GetPublicMethods().Single(x => x.Name == "Any")
- };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
- results.Should().BeFalse();
- }
-
- [Fact]
- public async void IsAuthorizedAsync_Metadata__HandlesMultipleSuccessfulClass()
- {
- var metadata = new ServiceMetadata
- {
- Ident = Guid.NewGuid().ToString(),
- Service = typeof(MultipleClassAuth).GetTypeInfo(),
- Method = typeof(MultipleClassAuth).GetPublicMethods().Single(x => x.Name == "Any")
- };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
- results.Should().BeTrue();
- }
-
- [Fact]
- public async void IsAuthorizedAsync_Metadata__HandlesMultipleFailedClass()
- {
- var metadata = new ServiceMetadata
- {
- Ident = Guid.NewGuid().ToString(),
- Service = typeof(MultipleFailClassAuth).GetTypeInfo(),
- Method = typeof(MultipleFailClassAuth).GetPublicMethods().Single(x => x.Name == "Any")
- };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
- results.Should().BeFalse();
- }
-
- [Fact]
- public async void IsAuthorizedAsync_Metadata__HandlesSuccessfulHybrid()
- {
- var metadata = new ServiceMetadata
- {
- Ident = Guid.NewGuid().ToString(),
- Service = typeof(HybridAuth).GetTypeInfo(),
- Method = typeof(HybridAuth).GetPublicMethods().Single(x => x.Name == "Any")
- };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
- results.Should().BeTrue();
- }
-
- [Fact]
- public async void IsAuthorizedAsync_Metadata__HandlesMethodFailedHybrid()
- {
- var metadata = new ServiceMetadata
- {
- Ident = Guid.NewGuid().ToString(),
- Service = typeof(HybridAuth).GetTypeInfo(),
- Method = typeof(HybridAuth).GetPublicMethods().Single(x => x.Name == "AnyFail")
- };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
- results.Should().BeFalse();
- }
-
- [Fact]
- public async void IsAuthorizedAsync_Metadata__HandlesClassFailedHybrid()
- {
- var metadata = new ServiceMetadata
- {
- Ident = Guid.NewGuid().ToString(),
- Service = typeof(HybridFailAuth).GetTypeInfo(),
- Method = typeof(HybridFailAuth).GetPublicMethods().Single(x => x.Name == "Fail")
- };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
- results.Should().BeFalse();
- }
-
- [Fact]
- public async void IsAuthorizedAsync_Metadata__HandlesAnonymousMethodSuccessfulHybrid()
- {
- var metadata = new ServiceMetadata
- {
- Ident = Guid.NewGuid().ToString(),
- Service = typeof(HybridFailAuth).GetTypeInfo(),
- Method = typeof(HybridFailAuth).GetPublicMethods().Single(x => x.Name == "Anonymous")
- };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
- results.Should().BeTrue();
- }
-
- [Fact]
- public async void IsAuthorizedAsync_Metadata__HandlesAnonymousClassSuccessfulHybrid()
- {
- var metadata = new ServiceMetadata
- {
- Ident = Guid.NewGuid().ToString(),
- Service = typeof(HybridAnonymousFailAuth).GetTypeInfo(),
- Method = typeof(HybridAnonymousFailAuth).GetPublicMethods().Single(x => x.Name == "Anonymous")
- };
-
- var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
- results.Should().BeTrue();
- }
-
- private static HttpContext GetContext(Action registerServices, bool anonymous = false)
- {
- var basicPrincipal = new ClaimsPrincipal(
- new ClaimsIdentity(new[]
- {
- new Claim("Permission", "CanViewPage"),
- new Claim(ClaimTypes.Role, "Administrator"),
- new Claim(ClaimTypes.Role, "User"),
- new Claim(ClaimTypes.NameIdentifier, "John"),
- },
- "Basic"
- ));
-
- var validUser = basicPrincipal;
-
- var bearerIdentity = new ClaimsIdentity(new[]
- {
- new Claim("Permission", "CupBearer"),
- new Claim(ClaimTypes.Role, "Token"),
- new Claim(ClaimTypes.NameIdentifier, "Jon Bear")
- },
- "Bearer"
- );
- var bearerPrincipal = new ClaimsPrincipal(bearerIdentity);
-
- validUser.AddIdentity(bearerIdentity);
-
- var serviceCollection = new ServiceCollection();
- if (registerServices != null)
- {
- serviceCollection.AddOptions();
- serviceCollection.AddLogging();
- serviceCollection.AddAuthorization();
-
- registerServices.Invoke(serviceCollection);
- }
-
- var serviceProvider = serviceCollection.BuildServiceProvider();
-
- var context = new Mock();
- var auth = new Mock();
- context.Setup(x => x.Authentication).Returns(auth.Object);
- context.SetupProperty(x => x.User);
- if (!anonymous)
- context.Object.User = validUser;
- context.SetupGet(x => x.RequestServices).Returns(serviceProvider);
- auth.Setup(x => x.AuthenticateAsync("Bearer")).ReturnsAsync(bearerPrincipal);
- auth.Setup(x => x.AuthenticateAsync("Basic")).ReturnsAsync(basicPrincipal);
- auth.Setup(x => x.AuthenticateAsync("Fails")).ReturnsAsync(null);
-
- return context.Object;
- }
-
- private static IAuthProvider GetAuthProvider(HttpContext ctx)
- {
- return ctx.RequestServices.GetRequiredService();
- }
-
- #region Test Classes
- // ReSharper disable UnusedMember.Local
- private class MethodAuth
- {
- [Authorize(Roles = "Administrator")]
- public object Single()
- {
- return null;
- }
- [Authorize(Roles = "FakeRole")]
- public object SingleFail()
- {
- return null;
- }
-
- [Authorize(Roles = "Administrator")]
- [Authorize(Roles = "User")]
- public object Multiple()
- {
- return null;
- }
- [Authorize(Roles = "Administrator")]
- [Authorize(Roles = "FakeRole")]
- public object MultipleFail()
- {
- return null;
- }
- }
-
- [Authorize(Roles = "Administrator")]
- private class SingleClassAuth
- {
- public object Any()
- {
- return null;
- }
- }
-
- [Authorize(Roles = "FakeRole")]
- private class SingleFailClassAuth
- {
- public object Any()
- {
- return null;
- }
- }
-
- [Authorize(Roles = "Administrator")]
- [Authorize(Roles = "User")]
- private class MultipleClassAuth
- {
- public object Any()
- {
- return null;
- }
- }
-
- [Authorize(Roles = "Administrator")]
- [Authorize(Roles = "FakeRole")]
- private class MultipleFailClassAuth
- {
- public object Any()
- {
- return null;
- }
- }
-
- [Authorize(Roles = "Administrator")]
- private class HybridAuth
- {
- [Authorize(Roles = "User")]
- public object Any()
- {
- return null;
- }
-
- [Authorize(Roles = "FakeRole")]
- public object AnyFail()
- {
- return null;
- }
- }
-
- [Authorize(Roles = "FakeRole")]
- private class HybridFailAuth
- {
- [AllowAnonymous]
- public object Anonymous()
- {
- return null;
- }
-
- [Authorize(Roles = "Administrator")]
- public object Fail()
- {
- return null;
- }
- }
-
- [AllowAnonymous]
- private class HybridAnonymousFailAuth
- {
- [Authorize(Roles = "FakeRole")]
- public object Anonymous()
- {
- return null;
- }
- }
- // ReSharper restore UnusedMember.Local
- #endregion
- }
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http.Authentication;
+using Microsoft.Extensions.DependencyInjection;
+using Moq;
+using RService.IO.Abstractions;
+using RService.IO.Abstractions.Providers;
+using RService.IO.Authorization.Providers;
+using Xunit;
+
+namespace RService.IO.Authorization.Tests
+{
+ public class AuthProviderTests
+ {
+ private readonly HttpContext _anonymousContext;
+ private readonly HttpContext _authorizedContext;
+ private readonly IAuthProvider _anonymousAuthProvider;
+ private readonly IAuthProvider _authorizedAuthProvider;
+
+ public AuthProviderTests()
+ {
+ _anonymousContext = GetContext(s => s.AddTransient(), true);
+ _authorizedContext = GetContext(s => s.AddTransient());
+ _anonymousAuthProvider = GetAuthProvider(_anonymousContext);
+ _authorizedAuthProvider = GetAuthProvider(_authorizedContext);
+ }
+
+ [Fact]
+ public void InvalidUser()
+ {
+ var context = GetContext(service => service.AddAuthorization());
+ context.User.Identities.Any(x => x.IsAuthenticated).Should().BeTrue();
+ }
+
+ [Fact]
+ public void Ctor__ThrowsExceptionIfNullProvider()
+ {
+ // ReSharper disable once ObjectCreationAsStatement
+ Action act = () => new AuthProvider(null);
+
+ act.ShouldThrow().And.Message.Should().Contain("provider");
+ }
+
+ [Fact]
+ public void IsAuthorizedAsync_Filter__ThrowsExceptionIfNullContext()
+ {
+ Func act = async () => await _authorizedAuthProvider.IsAuthorizedAsync(null, (IEnumerable)null);
+
+ act.ShouldThrow().And.Message.Should().Contain("ctx");
+ }
+
+ [Fact]
+ public void IsAuthorizedAsync_Filter__ThrowsExceptionIfNullFilters()
+ {
+ Func act = async () => await _anonymousAuthProvider.IsAuthorizedAsync(_anonymousContext, (IEnumerable)null);
+
+ act.ShouldThrow().And.Message.Should().Contain("authorizationFilter");
+ }
+
+ [Fact]
+ public void IsAuthorizedAsync_Metadata__ThrowsExceptionIfNullContext()
+ {
+ Func act = async () => await _anonymousAuthProvider.IsAuthorizedAsync(null, (ServiceMetadata)null);
+
+ act.ShouldThrow().And.Message.Should().Contain("ctx");
+ }
+
+ [Fact]
+ public void IsAuthorizedAsync_Metadata__ThrowsExceptionIfNullMetadata()
+ {
+ Func act = async () => await _anonymousAuthProvider.IsAuthorizedAsync(_anonymousContext, (ServiceMetadata)null);
+
+ act.ShouldThrow().And.Message.Should().Contain("metadata");
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync__AnonymousReturnsTrueForAnonymous()
+ {
+ var attributes = new[] { new AllowAnonymousAttribute() };
+
+ var results = await _anonymousAuthProvider.IsAuthorizedAsync(_anonymousContext, attributes);
+ results.Should().BeTrue();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync__AnonymousReturnsFalseForAuthorized()
+ {
+ var attributes = new[] { new AuthorizeAttribute() };
+
+ var results = await _anonymousAuthProvider.IsAuthorizedAsync(_anonymousContext, attributes);
+ results.Should().BeFalse();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync__AuthorizedRoleReturnsTrue()
+ {
+ var attributes = new[] { new AuthorizeAttribute { Roles = "Administrator" } };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, attributes);
+ results.Should().BeTrue();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync__UnauthorizedRoleReturnsFalse()
+ {
+ var authProvider = GetAuthProvider(_authorizedContext);
+ var attributes = new[] { new AuthorizeAttribute { Roles = "Poweruser" } };
+
+ var results = await authProvider.IsAuthorizedAsync(_authorizedContext, attributes);
+ results.Should().BeFalse();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync__AuthoriedWithNoAttributes()
+ {
+ var attributes = new object[] { };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, attributes);
+ results.Should().BeTrue();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync__AuthorizedWithSpecifiedScheme()
+ {
+ var attributes = new[]
+ {
+ new AuthorizeAttribute
+ {
+ Roles = "Administrator",
+ ActiveAuthenticationSchemes = "Basic"
+ }
+ };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, attributes);
+ results.Should().BeTrue();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync__NotAuthorizedWithSpecifiedMissingScheme()
+ {
+ var attributes = new[]
+ {
+ new AuthorizeAttribute
+ {
+ Roles = "Administrator",
+ ActiveAuthenticationSchemes = "FizzBuzzScheme"
+ }
+ };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, attributes);
+ results.Should().BeFalse();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync__ProvideDefaultIdentityIfClaimsFails()
+ {
+ var attributes = new[]
+ {
+ new AuthorizeAttribute
+ {
+ Roles = "Administrator",
+ ActiveAuthenticationSchemes = "Basic"
+ }
+ };
+
+ _anonymousContext.User.Should().BeNull();
+ await _anonymousAuthProvider.IsAuthorizedAsync(_anonymousContext, attributes);
+ _anonymousContext.User.Should().NotBeNull();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync__AuthorizedWhenSpecifingMultipleRolesInSingleAttr()
+ {
+ var attributes = new[] { new AuthorizeAttribute { Roles = "Administrator, PowerUser" } };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, attributes);
+ results.Should().BeTrue();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync__AuthorizedRequireAllAttrToBeAuthorized()
+ {
+ var attributes = new[]
+ {
+ new AuthorizeAttribute { Roles = "Administrator" },
+ new AuthorizeAttribute { Roles = "PowerUser" }
+ };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, attributes);
+ results.Should().BeFalse();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync_Metadata__HandlesSingleSuccessfulMethod()
+ {
+ var metadata = new ServiceMetadata
+ {
+ Ident = Guid.NewGuid().ToString(),
+ Service = typeof(ServiceMetadata).GetTypeInfo(),
+ Method = typeof(MethodAuth).GetPublicMethods().Single(x => x.Name == "Single")
+ };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
+ results.Should().BeTrue();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync_Metadata__HandlesSingleFailedMethod()
+ {
+ var metadata = new ServiceMetadata
+ {
+ Ident = Guid.NewGuid().ToString(),
+ Service = typeof(ServiceMetadata).GetTypeInfo(),
+ Method = typeof(MethodAuth).GetPublicMethods().Single(x => x.Name == "SingleFail")
+ };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
+ results.Should().BeFalse();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync_Metadata__HandlesMultipleSuccessfulMethod()
+ {
+ var metadata = new ServiceMetadata
+ {
+ Ident = Guid.NewGuid().ToString(),
+ Service = typeof(ServiceMetadata).GetTypeInfo(),
+ Method = typeof(MethodAuth).GetPublicMethods().Single(x => x.Name == "Multiple")
+ };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
+ results.Should().BeTrue();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync_Metadata__HandlesMultipleFailedMethod()
+ {
+ var metadata = new ServiceMetadata
+ {
+ Ident = Guid.NewGuid().ToString(),
+ Service = typeof(ServiceMetadata).GetTypeInfo(),
+ Method = typeof(MethodAuth).GetPublicMethods().Single(x => x.Name == "MultipleFail")
+ };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
+ results.Should().BeFalse();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync_Metadata__HandlesSingleSuccessfulClass()
+ {
+ var metadata = new ServiceMetadata
+ {
+ Ident = Guid.NewGuid().ToString(),
+ Service = typeof(SingleClassAuth).GetTypeInfo(),
+ Method = typeof(SingleClassAuth).GetPublicMethods().Single(x => x.Name == "Any")
+ };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
+ results.Should().BeTrue();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync_Metadata__HandlesSingleFailedClass()
+ {
+ var metadata = new ServiceMetadata
+ {
+ Ident = Guid.NewGuid().ToString(),
+ Service = typeof(SingleFailClassAuth).GetTypeInfo(),
+ Method = typeof(SingleFailClassAuth).GetPublicMethods().Single(x => x.Name == "Any")
+ };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
+ results.Should().BeFalse();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync_Metadata__HandlesMultipleSuccessfulClass()
+ {
+ var metadata = new ServiceMetadata
+ {
+ Ident = Guid.NewGuid().ToString(),
+ Service = typeof(MultipleClassAuth).GetTypeInfo(),
+ Method = typeof(MultipleClassAuth).GetPublicMethods().Single(x => x.Name == "Any")
+ };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
+ results.Should().BeTrue();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync_Metadata__HandlesMultipleFailedClass()
+ {
+ var metadata = new ServiceMetadata
+ {
+ Ident = Guid.NewGuid().ToString(),
+ Service = typeof(MultipleFailClassAuth).GetTypeInfo(),
+ Method = typeof(MultipleFailClassAuth).GetPublicMethods().Single(x => x.Name == "Any")
+ };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
+ results.Should().BeFalse();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync_Metadata__HandlesSuccessfulHybrid()
+ {
+ var metadata = new ServiceMetadata
+ {
+ Ident = Guid.NewGuid().ToString(),
+ Service = typeof(HybridAuth).GetTypeInfo(),
+ Method = typeof(HybridAuth).GetPublicMethods().Single(x => x.Name == "Any")
+ };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
+ results.Should().BeTrue();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync_Metadata__HandlesMethodFailedHybrid()
+ {
+ var metadata = new ServiceMetadata
+ {
+ Ident = Guid.NewGuid().ToString(),
+ Service = typeof(HybridAuth).GetTypeInfo(),
+ Method = typeof(HybridAuth).GetPublicMethods().Single(x => x.Name == "AnyFail")
+ };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
+ results.Should().BeFalse();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync_Metadata__HandlesClassFailedHybrid()
+ {
+ var metadata = new ServiceMetadata
+ {
+ Ident = Guid.NewGuid().ToString(),
+ Service = typeof(HybridFailAuth).GetTypeInfo(),
+ Method = typeof(HybridFailAuth).GetPublicMethods().Single(x => x.Name == "Fail")
+ };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
+ results.Should().BeFalse();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync_Metadata__HandlesAnonymousMethodSuccessfulHybrid()
+ {
+ var metadata = new ServiceMetadata
+ {
+ Ident = Guid.NewGuid().ToString(),
+ Service = typeof(HybridFailAuth).GetTypeInfo(),
+ Method = typeof(HybridFailAuth).GetPublicMethods().Single(x => x.Name == "Anonymous")
+ };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
+ results.Should().BeTrue();
+ }
+
+ [Fact]
+ public async void IsAuthorizedAsync_Metadata__HandlesAnonymousClassSuccessfulHybrid()
+ {
+ var metadata = new ServiceMetadata
+ {
+ Ident = Guid.NewGuid().ToString(),
+ Service = typeof(HybridAnonymousFailAuth).GetTypeInfo(),
+ Method = typeof(HybridAnonymousFailAuth).GetPublicMethods().Single(x => x.Name == "Anonymous")
+ };
+
+ var results = await _authorizedAuthProvider.IsAuthorizedAsync(_authorizedContext, metadata);
+ results.Should().BeTrue();
+ }
+
+ private static HttpContext GetContext(Action registerServices, bool anonymous = false)
+ {
+ var basicPrincipal = new ClaimsPrincipal(
+ new ClaimsIdentity(new[]
+ {
+ new Claim("Permission", "CanViewPage"),
+ new Claim(ClaimTypes.Role, "Administrator"),
+ new Claim(ClaimTypes.Role, "User"),
+ new Claim(ClaimTypes.NameIdentifier, "John"),
+ },
+ "Basic"
+ ));
+
+ var validUser = basicPrincipal;
+
+ var bearerIdentity = new ClaimsIdentity(new[]
+ {
+ new Claim("Permission", "CupBearer"),
+ new Claim(ClaimTypes.Role, "Token"),
+ new Claim(ClaimTypes.NameIdentifier, "Jon Bear")
+ },
+ "Bearer"
+ );
+ var bearerPrincipal = new ClaimsPrincipal(bearerIdentity);
+
+ validUser.AddIdentity(bearerIdentity);
+
+ var serviceCollection = new ServiceCollection();
+ if (registerServices != null)
+ {
+ serviceCollection.AddOptions();
+ serviceCollection.AddLogging();
+ serviceCollection.AddAuthorization();
+
+ registerServices.Invoke(serviceCollection);
+ }
+
+ var serviceProvider = serviceCollection.BuildServiceProvider();
+
+ var context = new Mock();
+ var auth = new Mock();
+ context.Setup(x => x.Authentication).Returns(auth.Object);
+ context.SetupProperty(x => x.User);
+ if (!anonymous)
+ context.Object.User = validUser;
+ context.SetupGet(x => x.RequestServices).Returns(serviceProvider);
+ auth.Setup(x => x.AuthenticateAsync("Bearer")).ReturnsAsync(bearerPrincipal);
+ auth.Setup(x => x.AuthenticateAsync("Basic")).ReturnsAsync(basicPrincipal);
+ auth.Setup(x => x.AuthenticateAsync("Fails")).ReturnsAsync(null);
+
+ return context.Object;
+ }
+
+ private static IAuthProvider GetAuthProvider(HttpContext ctx)
+ {
+ return ctx.RequestServices.GetRequiredService();
+ }
+
+ #region Test Classes
+ // ReSharper disable UnusedMember.Local
+ private class MethodAuth
+ {
+ [Authorize(Roles = "Administrator")]
+ public object Single()
+ {
+ return null;
+ }
+ [Authorize(Roles = "FakeRole")]
+ public object SingleFail()
+ {
+ return null;
+ }
+
+ [Authorize(Roles = "Administrator")]
+ [Authorize(Roles = "User")]
+ public object Multiple()
+ {
+ return null;
+ }
+ [Authorize(Roles = "Administrator")]
+ [Authorize(Roles = "FakeRole")]
+ public object MultipleFail()
+ {
+ return null;
+ }
+ }
+
+ [Authorize(Roles = "Administrator")]
+ private class SingleClassAuth
+ {
+ public object Any()
+ {
+ return null;
+ }
+ }
+
+ [Authorize(Roles = "FakeRole")]
+ private class SingleFailClassAuth
+ {
+ public object Any()
+ {
+ return null;
+ }
+ }
+
+ [Authorize(Roles = "Administrator")]
+ [Authorize(Roles = "User")]
+ private class MultipleClassAuth
+ {
+ public object Any()
+ {
+ return null;
+ }
+ }
+
+ [Authorize(Roles = "Administrator")]
+ [Authorize(Roles = "FakeRole")]
+ private class MultipleFailClassAuth
+ {
+ public object Any()
+ {
+ return null;
+ }
+ }
+
+ [Authorize(Roles = "Administrator")]
+ private class HybridAuth
+ {
+ [Authorize(Roles = "User")]
+ public object Any()
+ {
+ return null;
+ }
+
+ [Authorize(Roles = "FakeRole")]
+ public object AnyFail()
+ {
+ return null;
+ }
+ }
+
+ [Authorize(Roles = "FakeRole")]
+ private class HybridFailAuth
+ {
+ [AllowAnonymous]
+ public object Anonymous()
+ {
+ return null;
+ }
+
+ [Authorize(Roles = "Administrator")]
+ public object Fail()
+ {
+ return null;
+ }
+ }
+
+ [AllowAnonymous]
+ private class HybridAnonymousFailAuth
+ {
+ [Authorize(Roles = "FakeRole")]
+ public object Anonymous()
+ {
+ return null;
+ }
+ }
+ // ReSharper restore UnusedMember.Local
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/test/RService.IO.Authorization.Tests/Properties/AssemblyInfo.cs b/test/RService.IO.Authorization.Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..f29ae72
--- /dev/null
+++ b/test/RService.IO.Authorization.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,25 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("RService.IO.Authorization.Tests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("RService.IO.Authorization.Tests")]
+[assembly: AssemblyCopyright("Copyright © 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// 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)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("44B66719-E3DC-4F39-A67D-196BCB9A0FA7")]
\ No newline at end of file
diff --git a/test/RService.IO.Authorization.Tests/RService.IO.Authorization.Tests.xproj b/test/RService.IO.Authorization.Tests/RService.IO.Authorization.Tests.xproj
new file mode 100644
index 0000000..a7115f7
--- /dev/null
+++ b/test/RService.IO.Authorization.Tests/RService.IO.Authorization.Tests.xproj
@@ -0,0 +1,22 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+
+ {44B66719-E3DC-4F39-A67D-196BCB9A0FA7}
+ {8BB2217D-0F2D-49D1-97BC-3654ED321F3B}
+ RService.IO.Authorization.Tests
+ .\obj
+ .\bin\
+ v4.5.1
+
+
+
+ 2.0
+
+
+
diff --git a/test/RService.IO.Authorization.Tests/RServiceIoCollectionExtensionTests.cs b/test/RService.IO.Authorization.Tests/RServiceIoCollectionExtensionTests.cs
new file mode 100644
index 0000000..4e448fe
--- /dev/null
+++ b/test/RService.IO.Authorization.Tests/RServiceIoCollectionExtensionTests.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using FluentAssertions;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+using Moq;
+using RService.IO.Abstractions;
+using RService.IO.Abstractions.Providers;
+using RService.IO.Authorization.DependencyInjection;
+using RService.IO.Authorization.Providers;
+using Xunit;
+
+namespace RService.IO.Authorization.Tests
+{
+ public class RServiceIoCollectionExtensionTests
+ {
+ [Fact]
+ public void AddRServiceIoAuthorization__AddsRServiceProviderForIAuthProvider()
+ {
+ var services = new ServiceCollection();
+
+ services.AddAuthorization()
+ .AddRServiceIoAuthorization();
+
+ var app = BuildApplicationBuilder(services);
+ var provider = app.ApplicationServices.GetService();
+
+ provider.Should().NotBeNull().And.BeOfType();
+ }
+
+ [Fact]
+ public void AddRServiceIoAuthorization__UserImplementationForIAuthProviderTakesPrecedence()
+ {
+ var services = new ServiceCollection();
+
+ services.AddTransient()
+ .AddAuthorization()
+ .AddRServiceIoAuthorization();
+
+ var app = BuildApplicationBuilder(services);
+ var provider = app.ApplicationServices.GetService();
+
+ provider.Should().NotBeNull().And.BeOfType();
+ }
+
+ private static IApplicationBuilder BuildApplicationBuilder(IServiceCollection services)
+ {
+ var builder = new Mock();
+ builder.SetupAllProperties();
+ builder.Object.ApplicationServices = services.BuildServiceProvider();
+
+ return builder.Object;
+ }
+
+ // ReSharper disable ClassNeverInstantiated.Local
+ private class AuthorizationProvider : IAuthProvider
+ {
+ public Task IsAuthorizedAsync(HttpContext ctx, ServiceMetadata metadata)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task IsAuthorizedAsync(HttpContext ctx, IEnumerable authorizationFilters)
+ {
+ throw new NotImplementedException();
+ }
+ }
+ // ReSharper restore ClassNeverInstantiated.Local
+ }
+}
\ No newline at end of file
diff --git a/test/RService.IO.Authorization.Tests/project.json b/test/RService.IO.Authorization.Tests/project.json
new file mode 100644
index 0000000..03da633
--- /dev/null
+++ b/test/RService.IO.Authorization.Tests/project.json
@@ -0,0 +1,35 @@
+{
+ "version": "1.0.0",
+
+ "testRunner": "xunit",
+
+ "dependencies": {
+ "coveralls.io": "1.3.4",
+ "dotnet-test-xunit": "2.2.0-*",
+ "OpenCover": "4.6.519",
+ "RService.IO": "0.4.*",
+ "RService.IO.Authorization": "0.4.*",
+ "Microsoft.Extensions.Logging": "1.1.0-*",
+ "Microsoft.Extensions.Logging.Testing": "1.1.0-*",
+ "xunit": "2.2.0-*"
+ },
+
+ "frameworks": {
+ "netcoreapp1.0": {
+ "imports": [
+ "dotnet5.6",
+ "portable-net45+win8"
+ ],
+
+ "dependencies": {
+ "Microsoft.NETCore.App": {
+ "version": "1.1.0-*",
+ "type": "platform"
+ },
+ "moq.netcore": "4.4.0-*",
+ "System.Diagnostics.TraceSource": "4.0.0-*",
+ "FluentAssertions": "4.13.0"
+ }
+ }
+ }
+}
diff --git a/test/RService.IO.Tests/Abstractions/RoutingHttpContextExtensionsTests.cs b/test/RService.IO.Tests/Abstractions/RoutingHttpContextExtensionsTests.cs
index 422fb50..ac71bd7 100644
--- a/test/RService.IO.Tests/Abstractions/RoutingHttpContextExtensionsTests.cs
+++ b/test/RService.IO.Tests/Abstractions/RoutingHttpContextExtensionsTests.cs
@@ -7,6 +7,7 @@
using RService.IO.Abstractions;
using Xunit;
using RoutingHttpContextExtensions = RService.IO.Abstractions.RoutingHttpContextExtensions;
+using RoutingFeature = RService.IO.Abstractions.RoutingFeature;
namespace RService.IO.Tests.Abstractions
{
diff --git a/test/RService.IO.Tests/ApiExceptionTests.cs b/test/RService.IO.Tests/ApiExceptionTests.cs
index be2ea53..2c4a611 100644
--- a/test/RService.IO.Tests/ApiExceptionTests.cs
+++ b/test/RService.IO.Tests/ApiExceptionTests.cs
@@ -1,6 +1,5 @@
using System;
using System.Net;
-using System.Security.Cryptography.X509Certificates;
using FluentAssertions;
using RService.IO.Abstractions;
using Xunit;
diff --git a/test/RService.IO.Tests/DependencyIngection/ServiceCollectionExtensionTests.cs b/test/RService.IO.Tests/DependencyIngection/ServiceCollectionExtensionTests.cs
index 8538b7a..e08c6d1 100644
--- a/test/RService.IO.Tests/DependencyIngection/ServiceCollectionExtensionTests.cs
+++ b/test/RService.IO.Tests/DependencyIngection/ServiceCollectionExtensionTests.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.Reflection;
using FluentAssertions;
using Microsoft.AspNetCore.Builder;
@@ -11,10 +10,11 @@
using RService.IO.Abstractions;
using RService.IO.DependencyIngection;
using RService.IO.Providers;
-using IServiceProvider = RService.IO.Abstractions.IServiceProvider;
+using IServiceProvider = RService.IO.Abstractions.Providers.IServiceProvider;
using Xunit;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
+using RService.IO.Abstractions.Providers;
namespace RService.IO.Tests.DependencyIngection
{
@@ -220,35 +220,6 @@ public void AddRServiceIo__DoesNotRegistersExceptionFilterWithIoCIfNull()
globalExceptionFilter.Should().BeNull();
}
- [Fact]
- public void AddRServiceIoAuthorization__AddsRServiceProviderForIAuthProvider()
- {
- var services = new ServiceCollection();
-
- services.AddAuthorization()
- .AddRServiceIoAuthorization();
-
- var app = BuildApplicationBuilder(services);
- var provider = app.ApplicationServices.GetService();
-
- provider.Should().NotBeNull().And.BeOfType();
- }
-
- [Fact]
- public void AddRServiceIoAuthorization__UserImplementationForIAuthProviderTakesPrecedence()
- {
- var services = new ServiceCollection();
-
- services.AddTransient()
- .AddAuthorization()
- .AddRServiceIoAuthorization();
-
- var app = BuildApplicationBuilder(services);
- var provider = app.ApplicationServices.GetService();
-
- provider.Should().NotBeNull().And.BeOfType();
- }
-
private static IApplicationBuilder BuildApplicationBuilder(IServiceCollection services)
{
var builder = new Mock();
@@ -280,19 +251,6 @@ public string DehydrateResponse(object resDto)
throw new NotImplementedException();
}
}
-
- private class AuthorizationProvider : IAuthProvider
- {
- public Task IsAuthorizedAsync(HttpContext ctx, ServiceMetadata metadata)
- {
- throw new NotImplementedException();
- }
-
- public Task IsAuthorizedAsync(HttpContext ctx, IEnumerable authorizationFilters)
- {
- throw new NotImplementedException();
- }
- }
// ReSharper restore ClassNeverInstantiated.Local
}
}
\ No newline at end of file
diff --git a/test/RService.IO.Tests/Providers/NetJsonProviderTests.cs b/test/RService.IO.Tests/Providers/NetJsonProviderTests.cs
index c30d7d4..08018f3 100644
--- a/test/RService.IO.Tests/Providers/NetJsonProviderTests.cs
+++ b/test/RService.IO.Tests/Providers/NetJsonProviderTests.cs
@@ -8,10 +8,11 @@
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Primitives;
using Moq;
-using RService.IO.Abstractions;
using RService.IO.Providers;
using Xunit;
using FluentAssertions;
+using RService.IO.Abstractions.Providers;
+using RoutingFeature = RService.IO.Abstractions.RoutingFeature;
namespace RService.IO.Tests.Providers
{
diff --git a/test/RService.IO.Tests/Providers/RServiceProviderTests.cs b/test/RService.IO.Tests/Providers/RServiceProviderTests.cs
index 01766d7..3a46d47 100644
--- a/test/RService.IO.Tests/Providers/RServiceProviderTests.cs
+++ b/test/RService.IO.Tests/Providers/RServiceProviderTests.cs
@@ -11,8 +11,10 @@
using Microsoft.Extensions.Options;
using Moq;
using RService.IO.Abstractions;
+using RService.IO.Abstractions.Providers;
using RService.IO.Providers;
using Xunit;
+using RoutingFeature = RService.IO.Abstractions.RoutingFeature;
namespace RService.IO.Tests.Providers
{
diff --git a/test/RService.IO.Tests/RServiceMiddlewareTests.cs b/test/RService.IO.Tests/RServiceMiddlewareTests.cs
index cc0f130..dce8f33 100644
--- a/test/RService.IO.Tests/RServiceMiddlewareTests.cs
+++ b/test/RService.IO.Tests/RServiceMiddlewareTests.cs
@@ -14,8 +14,9 @@
using RService.IO.Abstractions;
using Xunit;
using Delegate = RService.IO.Abstractions.Delegate;
-using IServiceProvider = RService.IO.Abstractions.IServiceProvider;
+using IServiceProvider = RService.IO.Abstractions.Providers.IServiceProvider;
using IRoutingFeature = Microsoft.AspNetCore.Routing.IRoutingFeature;
+using RoutingFeature = RService.IO.Abstractions.RoutingFeature;
namespace RService.IO.Tests
{
@@ -139,7 +140,7 @@ public async void Invoke__LogsWhenFeatureNotAdded()
}
[Fact]
- public async void Invoke_CallsProviderIfActivatorFound()
+ public async void Invoke__CallsProviderIfActivatorFound()
{
var routePath = "/Foobar".Substring(1);
Delegate.Activator routeActivator = (target, args) => null;
diff --git a/test/RService.IO.Tests/project.json b/test/RService.IO.Tests/project.json
index 2a75c15..7adc79c 100644
--- a/test/RService.IO.Tests/project.json
+++ b/test/RService.IO.Tests/project.json
@@ -6,13 +6,13 @@
"dependencies": {
"coveralls.io": "1.3.4",
"dotnet-test-xunit": "2.2.0-*",
- "Microsoft.AspNetCore.Http": "1.0.0-*",
- "Microsoft.Extensions.DependencyInjection": "1.0.0-*",
- "Microsoft.Extensions.Logging": "1.0.0-*",
- "Microsoft.Extensions.Logging.Testing": "1.0.0-*",
+ "Microsoft.AspNetCore.Http": "1.1.0-*",
+ "Microsoft.Extensions.DependencyInjection": "1.1.0-*",
+ "Microsoft.Extensions.Logging": "1.1.0-*",
+ "Microsoft.Extensions.Logging.Testing": "1.1.0-*",
"OpenCover": "4.6.519",
- "RService.IO": "0.3.*",
- "RService.IO.Abstractions": "0.3.*",
+ "RService.IO": "0.4.*",
+ "RService.IO.Abstractions": "0.4.*",
"xunit": "2.2.0-*"
},
@@ -25,7 +25,7 @@
"dependencies": {
"Microsoft.NETCore.App": {
- "version": "1.0.0-*",
+ "version": "1.1.0-*",
"type": "platform"
},
"moq.netcore": "4.4.0-*",
diff --git a/test/Rservice.IO.Tests.Integration/MiddlewareTests.cs b/test/Rservice.IO.Tests.Integration/MiddlewareTests.cs
index da3b82b..b6b3f18 100644
--- a/test/Rservice.IO.Tests.Integration/MiddlewareTests.cs
+++ b/test/Rservice.IO.Tests.Integration/MiddlewareTests.cs
@@ -13,7 +13,8 @@
using Microsoft.Extensions.Logging;
using Moq;
using RService.IO;
-using RService.IO.Abstractions;
+using RService.IO.Abstractions.Providers;
+using RService.IO.Authorization.DependencyInjection;
using RService.IO.Tests;
using Xunit;
using RService.IO.DependencyIngection;
diff --git a/test/Rservice.IO.Tests.Integration/project.json b/test/Rservice.IO.Tests.Integration/project.json
index 984c816..6f1448b 100644
--- a/test/Rservice.IO.Tests.Integration/project.json
+++ b/test/Rservice.IO.Tests.Integration/project.json
@@ -6,9 +6,10 @@
"dependencies": {
"xunit": "2.2.0-*",
"dotnet-test-xunit": "2.2.0-*",
- "RService.IO": "0.3.*",
+ "RService.IO": "0.4.*",
+ "RService.IO.Authorization": "0.4.*",
"RService.IO.Tests": "1.0.0-*",
- "Microsoft.AspNetCore.TestHost": "1.0.0",
+ "Microsoft.AspNetCore.TestHost": "1.1.0",
"FluentAssertions": "4.13.0"
},
@@ -21,7 +22,7 @@
"dependencies": {
"Microsoft.NETCore.App": {
- "version": "1.0.0-*",
+ "version": "1.1.0-*",
"type": "platform"
}
}