feat(batch1): implement jwt wipe and nonce-required internal logic
This commit is contained in:
@@ -269,7 +269,7 @@ public static partial class AuthHandler
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static void WipeSlice(Span<byte> buf)
|
public static void WipeSlice(Span<byte> buf)
|
||||||
{
|
{
|
||||||
buf.Fill((byte)'x');
|
JwtProcessor.WipeSlice(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -31,6 +31,15 @@ public static class JwtProcessor
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const string JwtPrefix = "eyJ";
|
public const string JwtPrefix = "eyJ";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wipes a byte slice by filling with <c>'x'</c>.
|
||||||
|
/// Mirrors Go <c>wipeSlice</c>.
|
||||||
|
/// </summary>
|
||||||
|
public static void WipeSlice(Span<byte> buf)
|
||||||
|
{
|
||||||
|
buf.Fill((byte)'x');
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Validates that the given IP host address is allowed by the user claims source CIDRs.
|
/// Validates that the given IP host address is allowed by the user claims source CIDRs.
|
||||||
/// Returns true if the host is within any of the allowed CIDRs, or if no CIDRs are specified.
|
/// Returns true if the host is within any of the allowed CIDRs, or if no CIDRs are specified.
|
||||||
|
|||||||
@@ -61,10 +61,29 @@ public sealed partial class NatsServer
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if this server requires clients to send a nonce for auth.
|
/// Returns true if this server requires clients to send a nonce for auth.
|
||||||
/// Stub — full implementation in session 11.
|
/// Mirrors Go <c>Server.NonceRequired()</c>.
|
||||||
/// Mirrors Go <c>Server.nonceRequired()</c>.
|
/// Mirrors Go <c>Server.nonceRequired()</c>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool NonceRequired() => false;
|
private bool NonceRequired()
|
||||||
|
{
|
||||||
|
_mu.EnterReadLock();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return NonceRequiredInternal();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_mu.ExitReadLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if this server requires clients to send a nonce for auth.
|
||||||
|
/// Lock should be held by caller for strict Go parity.
|
||||||
|
/// Mirrors Go <c>Server.nonceRequired()</c>.
|
||||||
|
/// </summary>
|
||||||
|
internal bool NonceRequiredInternal()
|
||||||
|
=> GetOpts().AlwaysEnableNonce || (_nkeys?.Count > 0) || _trustedKeys != null || _proxiesKeyPairs.Count > 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Fills <paramref name="nonce"/> with random bytes.
|
/// Fills <paramref name="nonce"/> with random bytes.
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class JwtProcessorTests
|
|||||||
public void WipeSlice_FillsWithX()
|
public void WipeSlice_FillsWithX()
|
||||||
{
|
{
|
||||||
var buf = new byte[] { 0x01, 0x02, 0x03 };
|
var buf = new byte[] { 0x01, 0x02, 0x03 };
|
||||||
AuthHandler.WipeSlice(buf);
|
JwtProcessor.WipeSlice(buf);
|
||||||
buf.ShouldAllBe(b => b == (byte)'x');
|
buf.ShouldAllBe(b => b == (byte)'x');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ public class JwtProcessorTests
|
|||||||
public void WipeSlice_EmptyBuffer_NoOp()
|
public void WipeSlice_EmptyBuffer_NoOp()
|
||||||
{
|
{
|
||||||
var buf = Array.Empty<byte>();
|
var buf = Array.Empty<byte>();
|
||||||
AuthHandler.WipeSlice(buf);
|
JwtProcessor.WipeSlice(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
// Copyright 2012-2026 The NATS Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
using System.Reflection;
|
||||||
|
using Shouldly;
|
||||||
|
using ZB.MOM.NatsNet.Server.Auth;
|
||||||
|
|
||||||
|
namespace ZB.MOM.NatsNet.Server.Tests.Server;
|
||||||
|
|
||||||
|
public sealed class NonceRequiredTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void NonceRequiredInternal_NoConditions_ReturnsFalse()
|
||||||
|
{
|
||||||
|
var server = CreateServer();
|
||||||
|
server.NonceRequiredInternal().ShouldBeFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void NonceRequiredInternal_AlwaysEnableNonceOptionSet_ReturnsTrue()
|
||||||
|
{
|
||||||
|
var server = CreateServer();
|
||||||
|
var opts = server.GetOpts();
|
||||||
|
opts.AlwaysEnableNonce = true;
|
||||||
|
server.SetOpts(opts);
|
||||||
|
|
||||||
|
server.NonceRequiredInternal().ShouldBeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void NonceRequiredInternal_NkeysConfigured_ReturnsTrue()
|
||||||
|
{
|
||||||
|
var server = CreateServer();
|
||||||
|
SetPrivateField(server, "_nkeys", new Dictionary<string, NkeyUser>
|
||||||
|
{
|
||||||
|
["UAEXAMPLE"] = new() { Nkey = "UAEXAMPLE" },
|
||||||
|
});
|
||||||
|
|
||||||
|
server.NonceRequiredInternal().ShouldBeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void NonceRequiredInternal_TrustedKeysPresent_ReturnsTrue()
|
||||||
|
{
|
||||||
|
var server = CreateServer();
|
||||||
|
SetPrivateField(server, "_trustedKeys", new List<string> { "OPKEY" });
|
||||||
|
|
||||||
|
server.NonceRequiredInternal().ShouldBeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void NonceRequiredInternal_ProxiesKeyPairsPresent_ReturnsTrue()
|
||||||
|
{
|
||||||
|
var server = CreateServer();
|
||||||
|
var proxiesField = typeof(NatsServer).GetField("_proxiesKeyPairs", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
proxiesField.ShouldNotBeNull();
|
||||||
|
var proxies = proxiesField!.GetValue(server).ShouldBeOfType<List<object>>();
|
||||||
|
proxies.Add(new object());
|
||||||
|
|
||||||
|
server.NonceRequiredInternal().ShouldBeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NatsServer CreateServer()
|
||||||
|
{
|
||||||
|
var (server, error) = NatsServer.NewServer(new ServerOptions());
|
||||||
|
error.ShouldBeNull();
|
||||||
|
server.ShouldNotBeNull();
|
||||||
|
return server!;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetPrivateField<T>(NatsServer server, string fieldName, T value)
|
||||||
|
{
|
||||||
|
var field = typeof(NatsServer).GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
|
field.ShouldNotBeNull();
|
||||||
|
field!.SetValue(server, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
porting.db
BIN
porting.db
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
# NATS .NET Porting Status Report
|
# NATS .NET Porting Status Report
|
||||||
|
|
||||||
Generated: 2026-02-28 11:05:07 UTC
|
Generated: 2026-02-28 11:30:24 UTC
|
||||||
|
|
||||||
## Modules (12 total)
|
## Modules (12 total)
|
||||||
|
|
||||||
@@ -12,10 +12,10 @@ Generated: 2026-02-28 11:05:07 UTC
|
|||||||
|
|
||||||
| Status | Count |
|
| Status | Count |
|
||||||
|--------|-------|
|
|--------|-------|
|
||||||
| deferred | 2375 |
|
| deferred | 2373 |
|
||||||
| n_a | 24 |
|
| n_a | 24 |
|
||||||
| stub | 1 |
|
| stub | 1 |
|
||||||
| verified | 1273 |
|
| verified | 1275 |
|
||||||
|
|
||||||
## Unit Tests (3257 total)
|
## Unit Tests (3257 total)
|
||||||
|
|
||||||
@@ -34,4 +34,4 @@ Generated: 2026-02-28 11:05:07 UTC
|
|||||||
|
|
||||||
## Overall Progress
|
## Overall Progress
|
||||||
|
|
||||||
**2475/6942 items complete (35.7%)**
|
**2477/6942 items complete (35.7%)**
|
||||||
|
|||||||
37
reports/report_f9b582d.md
Normal file
37
reports/report_f9b582d.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# NATS .NET Porting Status Report
|
||||||
|
|
||||||
|
Generated: 2026-02-28 11:30:24 UTC
|
||||||
|
|
||||||
|
## Modules (12 total)
|
||||||
|
|
||||||
|
| Status | Count |
|
||||||
|
|--------|-------|
|
||||||
|
| verified | 12 |
|
||||||
|
|
||||||
|
## Features (3673 total)
|
||||||
|
|
||||||
|
| Status | Count |
|
||||||
|
|--------|-------|
|
||||||
|
| deferred | 2373 |
|
||||||
|
| n_a | 24 |
|
||||||
|
| stub | 1 |
|
||||||
|
| verified | 1275 |
|
||||||
|
|
||||||
|
## Unit Tests (3257 total)
|
||||||
|
|
||||||
|
| Status | Count |
|
||||||
|
|--------|-------|
|
||||||
|
| deferred | 2091 |
|
||||||
|
| n_a | 187 |
|
||||||
|
| verified | 979 |
|
||||||
|
|
||||||
|
## Library Mappings (36 total)
|
||||||
|
|
||||||
|
| Status | Count |
|
||||||
|
|--------|-------|
|
||||||
|
| mapped | 36 |
|
||||||
|
|
||||||
|
|
||||||
|
## Overall Progress
|
||||||
|
|
||||||
|
**2477/6942 items complete (35.7%)**
|
||||||
Reference in New Issue
Block a user