Skip to content

Commit ea5ce98

Browse files
Added Auth extension method to check for authorization in the pipeline.
1 parent 0b5bbce commit ea5ce98

11 files changed

+434
-29
lines changed

Directory.Build.targets

+26-26
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,38 @@
11
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2-
<!--
2+
<!--
33
Push the target package to nuget
44
-->
5-
<Target Name="PushPackage" AfterTargets="Pack"
6-
Condition="'$(PushAfterPack)'=='true' AND '$(IsPackable)'=='true'">
7-
<Exec Command="dotnet nuget push $(SolutionDir)output/$(TargetName).$(PackageVersion).nupkg $(PackageSourceParam) $(PackageApiKeyParam)"></Exec>
8-
</Target>
5+
<Target Name="PushPackage" AfterTargets="Pack"
6+
Condition="'$(PushAfterPack)'=='true' AND '$(IsPackable)'=='true'">
7+
<Exec Command="dotnet nuget push $(SolutionDir)output/$(TargetName).$(PackageVersion).nupkg $(PackageSourceParam) $(PackageApiKeyParam)"></Exec>
8+
</Target>
99

10-
<!--
10+
<!--
1111
Set the package version and source before Pack
1212
https://github.com/NuGet/NuGet.Client/blob/4.3.0.4202/src/NuGet.Core/NuGet.Build.Tasks.Pack.Library/Pack.targets
1313
Must run before target "GenerateNuspec" ("Pack") for the version to be applied as expected
1414
-->
15-
<Target Name="SetPackageVersion" BeforeTargets="GenerateNuspec"
16-
Condition="'$(IsPackable)'=='true'">
17-
<PropertyGroup>
18-
<VersionPrefix>$(MajorVersion).$(MinorVersion).$(PatchVersion)</VersionPrefix>
19-
<PackageVersion Condition="'$(VersionSuffix)'==''">$(VersionPrefix)</PackageVersion>
20-
<PackageVersion Condition="'$(VersionSuffix)'!=''">$(VersionPrefix)-$(VersionSuffix)</PackageVersion>
21-
</PropertyGroup>
22-
</Target>
15+
<Target Name="SetPackageVersion" BeforeTargets="GenerateNuspec"
16+
Condition="'$(IsPackable)'=='true'">
17+
<PropertyGroup>
18+
<VersionPrefix>$(MajorVersion).$(MinorVersion).$(PatchVersion)</VersionPrefix>
19+
<PackageVersion Condition="'$(VersionSuffix)'==''">$(VersionPrefix)</PackageVersion>
20+
<PackageVersion Condition="'$(VersionSuffix)'!=''">$(VersionPrefix)-$(VersionSuffix)</PackageVersion>
21+
</PropertyGroup>
22+
</Target>
2323

24-
<Target Name="SetPackageSource" BeforeTargets="GenerateNuspec"
25-
Condition="'$(PushAfterPack)'=='true'">
26-
<PropertyGroup>
27-
<PackageSourceParam Condition="'$(PackageSource)'!=''">--source $(PackageSource)</PackageSourceParam>
28-
</PropertyGroup>
29-
</Target>
24+
<Target Name="SetPackageSource" BeforeTargets="GenerateNuspec"
25+
Condition="'$(PushAfterPack)'=='true'">
26+
<PropertyGroup>
27+
<PackageSourceParam Condition="'$(PackageSource)'!=''">--source $(PackageSource)</PackageSourceParam>
28+
</PropertyGroup>
29+
</Target>
3030

31-
<Target Name="SetPackageApiKey" BeforeTargets="GenerateNuspec"
32-
Condition="'$(PushAfterPack)'=='true'">
33-
<PropertyGroup>
34-
<PackageApiKeyParam Condition="'$(PackageApiKey)'!=''">--api-key $(PackageApiKey)</PackageApiKeyParam>
35-
</PropertyGroup>
36-
</Target>
31+
<Target Name="SetPackageApiKey" BeforeTargets="GenerateNuspec"
32+
Condition="'$(PushAfterPack)'=='true'">
33+
<PropertyGroup>
34+
<PackageApiKeyParam Condition="'$(PackageApiKey)'!=''">--api-key $(PackageApiKey)</PackageApiKeyParam>
35+
</PropertyGroup>
36+
</Target>
3737

3838
</Project>

Hyperbee.Pipeline.sln

+15-2
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{884A8242-3
4141
docs\todo.md = docs\todo.md
4242
EndProjectSection
4343
EndProject
44-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hyperbee.Pipeline.Caching", "src\Hyperbee.Pipline.Caching\Hyperbee.Pipeline.Caching.csproj", "{833A7497-542F-4B88-A76A-DA520E000F6F}"
44+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hyperbee.Pipeline.Caching", "src\Hyperbee.Pipline.Caching\Hyperbee.Pipeline.Caching.csproj", "{833A7497-542F-4B88-A76A-DA520E000F6F}"
4545
EndProject
46-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hyperbee.Pipeline.Caching.Tests", "test\Hyperbee.PipelineCaching.Tests\Hyperbee.Pipeline.Caching.Tests.csproj", "{B7E5FBB3-AF2A-4E48-8E6A-10887DC6C4C0}"
46+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hyperbee.Pipeline.Caching.Tests", "test\Hyperbee.PipelineCaching.Tests\Hyperbee.Pipeline.Caching.Tests.csproj", "{B7E5FBB3-AF2A-4E48-8E6A-10887DC6C4C0}"
47+
EndProject
48+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hyperbee.Pipeline.Auth", "src\Hyperbee.Pipeline.Auth\Hyperbee.Pipeline.Auth.csproj", "{85FBEEBD-0E57-4B54-83AF-6A501779CBD5}"
49+
EndProject
50+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hyperbee.Pipeline.Auth.Tests", "test\Hyperbee.Pipeline.Auth.Tests\Hyperbee.Pipeline.Auth.Tests.csproj", "{3E5F6864-2BAD-4349-8C7A-D199A715FA3C}"
4751
EndProject
4852
Global
4953
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -67,6 +71,14 @@ Global
6771
{B7E5FBB3-AF2A-4E48-8E6A-10887DC6C4C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
6872
{B7E5FBB3-AF2A-4E48-8E6A-10887DC6C4C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
6973
{B7E5FBB3-AF2A-4E48-8E6A-10887DC6C4C0}.Release|Any CPU.Build.0 = Release|Any CPU
74+
{85FBEEBD-0E57-4B54-83AF-6A501779CBD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
75+
{85FBEEBD-0E57-4B54-83AF-6A501779CBD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
76+
{85FBEEBD-0E57-4B54-83AF-6A501779CBD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
77+
{85FBEEBD-0E57-4B54-83AF-6A501779CBD5}.Release|Any CPU.Build.0 = Release|Any CPU
78+
{3E5F6864-2BAD-4349-8C7A-D199A715FA3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
79+
{3E5F6864-2BAD-4349-8C7A-D199A715FA3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
80+
{3E5F6864-2BAD-4349-8C7A-D199A715FA3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
81+
{3E5F6864-2BAD-4349-8C7A-D199A715FA3C}.Release|Any CPU.Build.0 = Release|Any CPU
7082
EndGlobalSection
7183
GlobalSection(SolutionProperties) = preSolution
7284
HideSolutionNode = FALSE
@@ -77,6 +89,7 @@ Global
7789
{17DA1657-DF82-440F-B1F1-D888BFA9626B} = {F9B24CD9-E06B-4834-84CB-8C29E5F10BE0}
7890
{884A8242-351E-4363-9B34-E8C202CF7787} = {870D9301-BE3D-44EA-BF9C-FCC2E87FE4CD}
7991
{B7E5FBB3-AF2A-4E48-8E6A-10887DC6C4C0} = {F9B24CD9-E06B-4834-84CB-8C29E5F10BE0}
92+
{3E5F6864-2BAD-4349-8C7A-D199A715FA3C} = {F9B24CD9-E06B-4834-84CB-8C29E5F10BE0}
8093
EndGlobalSection
8194
GlobalSection(ExtensibilityGlobals) = postSolution
8295
SolutionGuid = {32874F5B-B467-4F28-A8E2-82C2536FB228}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<IsPackable>true</IsPackable>
7+
8+
<Authors>Stillpoint Software, Inc.</Authors>
9+
<PackageReadmeFile>README.md</PackageReadmeFile>
10+
<PackageTags>pipeline;auth</PackageTags>
11+
<PackageIcon>icon.png</PackageIcon>
12+
<PackageProjectUrl>https://github.com/Stillpoint-Software/Hyperbee.Pipeline/</PackageProjectUrl>
13+
<PackageReleaseNotes>https://github.com/Stillpoint-Software/hyperbee.pipeline/releases/latest</PackageReleaseNotes>
14+
<TargetFrameworks>net8.0</TargetFrameworks>
15+
<PackageLicenseFile>LICENSE</PackageLicenseFile>
16+
<Copyright>Stillpoint Software, Inc.</Copyright>
17+
<Title>Hyperbee Pipline Auth</Title>
18+
<Description>Auth for Hyperbee.Pipelines async pipelines</Description>
19+
<RepositoryUrl>https://github.com/Stillpoint-Software/Hyperbee.Pipeline</RepositoryUrl>
20+
<RepositoryType>git</RepositoryType>
21+
<PackageReleaseNotes>https://github.com/Stillpoint-Software/hyperbee.pipeline/releases/latest</PackageReleaseNotes>
22+
</PropertyGroup>
23+
24+
<ItemGroup>
25+
<FrameworkReference Include="Microsoft.AspNetCore.App" />
26+
<None Include="..\..\assets\icon.png" Pack="true" Visible="false" PackagePath="/" />
27+
<None Include="..\..\LICENSE">
28+
<Pack>True</Pack>
29+
<PackagePath>\</PackagePath>
30+
</None>
31+
<None Include="README.md">
32+
<Pack>True</Pack>
33+
<PackagePath>\</PackagePath>
34+
</None>
35+
<PackageReference Include="Microsoft.AspNetCore.Http.Connections.Common" Version="8.0.4" />
36+
<ProjectReference Include="..\Hyperbee.Pipeline\Hyperbee.Pipeline.csproj" />
37+
<PackageReference Update="Microsoft.SourceLink.GitHub" Version="8.0.0">
38+
<PrivateAssets>all</PrivateAssets>
39+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
40+
</PackageReference>
41+
</ItemGroup>
42+
</Project>

src/Hyperbee.Pipeline.Auth/LICENSE

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
## LICENSE
2+
3+
MIT License
4+
5+
Copyright (c) 2024 Stillpoint Software, Inc.
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in all
15+
copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
SOFTWARE.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using System.Security.Claims;
2+
using Hyperbee.Pipeline.Context;
3+
using Microsoft.Extensions.DependencyInjection;
4+
5+
namespace Hyperbee.Pipeline.Auth;
6+
7+
public static class PipelineAuthExtensions
8+
{
9+
private const string ClaimsPrincipalKey = nameof( ClaimsPrincipalKey );
10+
11+
public static IPipelineBuilder<TInput, TNext> PipeIfClaim<TInput, TOutput, TNext>(
12+
this IPipelineBuilder<TInput, TOutput> builder,
13+
Claim claim,
14+
Func<IPipelineStartBuilder<TOutput, TOutput>, IPipelineBuilder<TOutput, TNext>> childBuilder )
15+
{
16+
return (IPipelineBuilder<TInput, TNext>) builder
17+
.PipeIf( ( context, arg ) =>
18+
{
19+
var claimsPrincipal = context.GetClaimsPrincipal();
20+
21+
return claimsPrincipal.HasClaim( x => x.Type == claim.Type && x.Value == claim.Value );
22+
}
23+
, childBuilder );
24+
25+
}
26+
27+
public static IPipelineBuilder<TInput, TOutput> WithAuth<TInput, TOutput>(
28+
this IPipelineStartBuilder<TInput, TOutput> builder,
29+
Func<IPipelineContext, TOutput, ClaimsPrincipal, bool> validateClaims )
30+
{
31+
return builder
32+
.WithAuth()
33+
.Call( ( context, argument ) =>
34+
{
35+
var claimsPrincipal = context.GetClaimsPrincipal();
36+
37+
if ( !validateClaims( context, argument, claimsPrincipal ) )
38+
context.CancelAfter();
39+
40+
} );
41+
}
42+
43+
public static IPipelineBuilder<TInput, TOutput> WithAuth<TInput, TOutput>(
44+
this IPipelineStartBuilder<TInput, TOutput> builder )
45+
{
46+
return builder.HookAsync( async ( context, argument, next ) =>
47+
{
48+
context.GetClaimsPrincipal();
49+
50+
return await next( context, argument );
51+
52+
} );
53+
}
54+
55+
public static ClaimsPrincipal GetClaimsPrincipal( this IPipelineContext context )
56+
{
57+
if ( context.Items.TryGetValue<ClaimsPrincipal>( ClaimsPrincipalKey, out var claimsPrincipal ) )
58+
return claimsPrincipal;
59+
60+
var claimsPrincipalAccessor = context.ServiceProvider.GetService<IClaimsPrincipalAccessor>();
61+
claimsPrincipal = claimsPrincipalAccessor.ClaimsPrincipal;
62+
63+
context.Items.SetValue( ClaimsPrincipalKey, claimsPrincipal );
64+
return claimsPrincipal;
65+
}
66+
67+
68+
}

src/Hyperbee.Pipeline.Auth/README.md

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Hyperbee.Pipeline.Claims
2+
3+
The `Hyperbee.Pipeline.Auth` library is a set of extentsions to `Hyperbee.Pipeline` that adds support for authorization within the pipeline.
4+
5+
6+
## Examples
7+
8+
```csharp
9+
// Will return the claim if available
10+
var command = PipelineFactory
11+
.Start<string>()
12+
.PipeIfClaim( Claim )
13+
.Build();
14+
15+
```
16+
17+
```csharp
18+
// WithAuth takes a function to validate the claim.
19+
var command = PipelineFactory
20+
.Start<string>()
21+
.WithAuth( ValidateClaim )
22+
.Build();
23+
24+
private async Task<bool> ValidateClaim( IPipelineContext context, string roleValue, ClaimsPrincipal claimsPrincipal )
25+
{
26+
return claimsPrincipal.HasClaim( x => x.Value == roleValue );
27+
}
28+
```
29+
30+
## Dependacy Injection
31+
32+
```csharp
33+
// Add httpContextAccessor if using web api
34+
services.AddHttpContextAccessor();
35+
36+
// Add with the pipelines
37+
services.AddClaimPrincipalAccessor();
38+
```
39+
40+
Or create your own claims principal use for the pipelines:
41+
42+
```csharp
43+
services.AddPipeline( (factoryServices, rootProvider) =>
44+
{
45+
factoryServices.AddClaimPrincipalAccessor( IClaimsPrincipal claimsPrincipal )
46+
} );
47+
```
48+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using System.Security.Claims;
2+
using Microsoft.AspNetCore.Http;
3+
using Microsoft.Extensions.DependencyInjection;
4+
5+
namespace Hyperbee.Pipeline.Auth;
6+
7+
public static class ServiceCollectionExtensions
8+
{
9+
public static IServiceCollection AddClaimPrincipalAccessor<T>(
10+
this IServiceCollection services,
11+
T claimsPrincipalAccessor
12+
) where T : IClaimsPrincipalAccessor
13+
{
14+
return services.AddTransient<IClaimsPrincipalAccessor>( _ => claimsPrincipalAccessor );
15+
16+
}
17+
18+
//For web API
19+
public static IServiceCollection AddClaimPrincipalAccessor(
20+
this IServiceCollection services
21+
)
22+
{
23+
return services.AddTransient<IClaimsPrincipalAccessor, HttpClaimsAccessor>();
24+
}
25+
}
26+
27+
public interface IClaimsPrincipalAccessor
28+
{
29+
public ClaimsPrincipal ClaimsPrincipal { get; }
30+
}
31+
32+
public class HttpClaimsAccessor : IClaimsPrincipalAccessor
33+
{
34+
private readonly IHttpContextAccessor _httpContextAccessor;
35+
public HttpClaimsAccessor( IHttpContextAccessor httpContextAccessor )
36+
{
37+
_httpContextAccessor = httpContextAccessor;
38+
}
39+
40+
public ClaimsPrincipal ClaimsPrincipal
41+
{
42+
get { return _httpContextAccessor.HttpContext.User; }
43+
}
44+
}
45+
46+
47+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
8+
<IsPackable>false</IsPackable>
9+
<IsTestProject>true</IsTestProject>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="coverlet.collector" Version="6.0.2">
14+
<PrivateAssets>all</PrivateAssets>
15+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
16+
</PackageReference>
17+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
18+
<PackageReference Include="MSTest.TestAdapter" Version="3.3.1" />
19+
<PackageReference Include="MSTest.TestFramework" Version="3.3.1" />
20+
<PackageReference Include="NSubstitute" Version="5.1.0" />
21+
</ItemGroup>
22+
23+
<ItemGroup>
24+
<ProjectReference Include="..\..\src\Hyperbee.Pipeline.Auth\Hyperbee.Pipeline.Auth.csproj" />
25+
<ProjectReference Include="..\..\src\Hyperbee.Pipeline\Hyperbee.Pipeline.csproj" />
26+
</ItemGroup>
27+
28+
<ItemGroup>
29+
<Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
30+
</ItemGroup>
31+
32+
</Project>

0 commit comments

Comments
 (0)