Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,8 @@ stylecop.documentation.xmlHeader = false
dotnet_diagnostic.SA1101.severity = none # Prefix local calls with this
dotnet_diagnostic.SA1309.severity = none # Field names must not begin with underscore

[**/Models/*.cs]
dotnet_diagnostic.CS8618.severity = none # Non-nullable property must contain a non-null value when exiting constructor


# C++ Files
[*.{cpp,h,in}]
curly_bracket_next_line = true
indent_brace_style = Allman
# xunit Analyzers
dotnet_diagnostic.xUnit1051.severity = none # Calls to methods which accept CancellationToken should use TestContext.Current.CancellationToken to allow test cancellation to be more responsive

# Xml project files
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}]
Expand Down
59 changes: 59 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Release

on:
push:
branches:
- main

permissions:
contents: write

jobs:
nuget:
name: dotnet
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- id: tag
name: Determine tag
run: |
version="$(head -n 1 src/Synadia.AuthCallout/version.txt)"
ref_name="v$version"
create=true
if [ "$(git ls-remote origin "refs/tags/$ref_name" | wc -l)" = "1" ]; then
create=false
fi

echo "version=$version" | tee -a "$GITHUB_OUTPUT"
echo "ref-name=$ref_name" | tee -a "$GITHUB_OUTPUT"
echo "create=$create" | tee -a "$GITHUB_OUTPUT"

- if: ${{ fromJSON(steps.tag.outputs.create) }}
name: Setup dotnet
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
8.x
9.x

- if: ${{ fromJSON(steps.tag.outputs.create) }}
name: Pack
# https://learn.microsoft.com/en-us/nuget/create-packages/symbol-packages-snupkg
# https://devblogs.microsoft.com/dotnet/producing-packages-with-source-link/
run: dotnet pack -c Release -o dist -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg -p:ContinuousIntegrationBuild=true

- if: ${{ fromJSON(steps.tag.outputs.create) }}
name: Push
run: |
cd dist
ls -lh
# this should upload snupkgs in the same folder
dotnet nuget push *.nupkg -s https://api.nuget.org/v3/index.json -k "${{ secrets.NUGET_API_KEY }}" --skip-duplicate

- if: ${{ fromJSON(steps.tag.outputs.create) }}
name: Tag
run: |
git tag "${{ steps.tag.outputs.ref-name }}"
git push origin "${{ steps.tag.outputs.ref-name }}"
14 changes: 14 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ jobs:
- name: Check nats-server
run: nats-server -v

- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.x'

- name: Setup dotnet
uses: actions/setup-dotnet@v4
with:
Expand All @@ -59,3 +64,12 @@ jobs:

- name: Test
run: dotnet test --no-build --logger:"console;verbosity=normal"

- name: Compat Test
env:
X_COMPAT_EXE: bin/Debug/net8.0/compat
run: |
cd tests/compat
dotnet build
go test -v

16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
# Callout .NET

## ⚠️ EARLY DEVELOPERS PREVIEW ⚠️

[![License Apache 2](https://img.shields.io/badge/License-Apache2-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
[![NuGet](https://img.shields.io/nuget/v/Synadia.AuthCallout.svg?cacheSeconds=3600)](https://www.nuget.org/packages/Synadia.AuthCallout)
[![Build](https://github.com/synadia-io/callout.net/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/synadia-io/callout.net/actions/workflows/test.yml?query=branch%3Amain)

### Preview

This is a preview version of the library. The API is subject to change.
The library is not yet ready for production use.

> [!CAUTION]
> ### Important Disclaimer
>
> This repository provides functionality built on top of NATS JWT APIs using .NET.
> However, at this time NATS JWT .NET is _not_ a supported API.
> Use at your own risk.
>
> See also [NATS JWT .NET](https://github.com/nats-io/jwt.net) library for more information.

This library implements a small framework for writing AuthCallout services for NATS.

See also the [Go implementation](https://github.com/synadia-io/callout.go) where this codebase is based on.
8 changes: 8 additions & 0 deletions callout.net.sln
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{
ProjectSection(SolutionItems) = preProject
.github\workflows\format.yml = .github\workflows\format.yml
.github\workflows\test.yml = .github\workflows\test.yml
.github\workflows\release.yml = .github\workflows\release.yml
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "compat", "tests\compat\compat.csproj", "{25EFB419-55B6-4BFB-BF03-F5EB1C0346AF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -47,6 +50,7 @@ Global
{59E78136-1175-4385-BAE5-97D1EDB150D9} = {242B9172-5DAD-4B54-80C4-C34D36CA9302}
{F6DE750B-FC14-4CE5-A12E-E3E3F791E3C2} = {E6241CB5-ECE1-4593-BAE1-7752249A373E}
{A0438527-3F3D-4CC5-B422-C643C5EE7976} = {F223C628-0627-4C07-998D-DD74B74379C2}
{25EFB419-55B6-4BFB-BF03-F5EB1C0346AF} = {E6241CB5-ECE1-4593-BAE1-7752249A373E}
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{859C0248-9DED-4290-9F56-641D572A19A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
Expand All @@ -61,5 +65,9 @@ Global
{F6DE750B-FC14-4CE5-A12E-E3E3F791E3C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F6DE750B-FC14-4CE5-A12E-E3E3F791E3C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F6DE750B-FC14-4CE5-A12E-E3E3F791E3C2}.Release|Any CPU.Build.0 = Release|Any CPU
{25EFB419-55B6-4BFB-BF03-F5EB1C0346AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{25EFB419-55B6-4BFB-BF03-F5EB1C0346AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{25EFB419-55B6-4BFB-BF03-F5EB1C0346AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{25EFB419-55B6-4BFB-BF03-F5EB1C0346AF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
23 changes: 12 additions & 11 deletions examples/Example.AuthService/Example.AuthService.csproj
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- <PublishAot>true</PublishAot>-->
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>true</PublishAot>
<IsPackable>false</IsPackable>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Synadia.AuthCallout\Synadia.AuthCallout.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Synadia.AuthCallout\Synadia.AuthCallout.csproj"/>
</ItemGroup>

</Project>
6 changes: 3 additions & 3 deletions examples/Example.AuthService/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

await using var connection = new NatsConnection(new NatsOpts { AuthOpts = new NatsAuthOpts { CredsFile = creds } });

ValueTask<string> Authorizer(NatsAuthorizationRequest r)
ValueTask<string> Authorizer(NatsAuthorizationRequest r, CancellationToken cancellationToken)
{
NatsUserClaims user = jwt.NewUserClaims(r.UserNKey);

Expand All @@ -34,14 +34,14 @@ ValueTask<string> Authorizer(NatsAuthorizationRequest r)
return ValueTask.FromResult(jwt.EncodeUserClaims(user, akp));
}

ValueTask<string> ResponseSigner(NatsAuthorizationResponseClaims r)
ValueTask<string> ResponseSigner(NatsAuthorizationResponseClaims r, CancellationToken cancellationToken)
{
return ValueTask.FromResult(jwt.EncodeAuthorizationResponseClaims(r, ckp));
}

var opts = new NatsAuthServiceOpts(Authorizer, ResponseSigner)
{
ErrorHandler = e =>
ErrorHandler = (e, ct) =>
{
Console.WriteLine($"ERROR: {e}");
return default;
Expand Down
6 changes: 4 additions & 2 deletions src/Synadia.AuthCallout/INatsAuthService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ public interface INatsAuthService : IAsyncDisposable
/// Starts the NatsAuthService asynchronously by initializing the service and setting up the necessary endpoints
/// for handling authentication requests.
/// </summary>
/// <param name="cancellationToken">A cancellation token to observe while waiting for the operation to complete.</param>
/// <returns>A task that represents the asynchronous start operation.</returns>
ValueTask StartAsync();
ValueTask StartAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Processes an incoming request asynchronously by decoding the JWT, authorizing the request, and optionally encrypting
/// the response before returning it.
/// </summary>
/// <param name="msg">The incoming request message containing the data to process.</param>
/// <param name="cancellationToken">A cancellation token to observe while waiting for the operation to complete.</param>
/// <returns>A task that represents the asynchronous operation, containing the processed response as a byte array.</returns>
ValueTask<byte[]> ProcessRequestAsync(NatsSvcMsg<byte[]> msg);
ValueTask<byte[]> ProcessRequestAsync(NatsSvcMsg<byte[]> msg, CancellationToken cancellationToken = default);
}
Loading