Skip to content

Commit

Permalink
[DEV-52] Plugins reloaded: Metrics and Diagnostics support (#42)
Browse files Browse the repository at this point in the history
Added: new Plugin base class for a simpler implementation with  diagnostics and metrics support
Added: new SubsystemsPlugin base class for a simpler implementation with diagnostics and metrics support
Added: PluginDiagnosticsDataCollector to collect all data diags from the plugins
Added: automatic license checking if a licence public key is provided.
Fixed: Licence test
Changed: IPlugableComponent removing CollectTelemetry method and adding other properties like Name and Version
Removed: Serilog dependency
  • Loading branch information
RagingKore authored May 16, 2024
1 parent 5e4d327 commit eca0063
Show file tree
Hide file tree
Showing 42 changed files with 1,214 additions and 680 deletions.
File renamed without changes.
5 changes: 2 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ jobs:
- name: Scan for Vulnerabilities
shell: bash
run: |
cd src
dotnet restore
dotnet list package --vulnerable --include-transitive | tee vulnerabilities.txt
! cat vulnerabilities.txt | grep -q "has the following vulnerable packages"
Expand Down Expand Up @@ -53,11 +52,11 @@ jobs:
- name: Compile
shell: bash
run: |
dotnet build --configuration ${{ matrix.configuration }} --framework=${{ matrix.framework }} src/EventStore.Plugins${{ matrix.test }}
dotnet build --configuration ${{ matrix.configuration }} --framework=${{ matrix.framework }} test/EventStore.Plugins${{ matrix.test }}
- name: Run Tests
shell: bash
run: |
dotnet test --configuration ${{ matrix.configuration }} --framework=${{ matrix.framework }} --blame \
--logger:"GitHubActions;report-warnings=false" \
--logger:"console;verbosity=normal" \
src/EventStore.Plugins${{ matrix.test }}
test/EventStore.Plugins${{ matrix.test }}
4 changes: 2 additions & 2 deletions src/EventStore.Plugins.sln → EventStore.Plugins.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34309.116
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventStore.Plugins", "EventStore.Plugins\EventStore.Plugins.csproj", "{504B01C5-281F-4CEA-A12F-D5333AB901EB}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventStore.Plugins", "src\EventStore.Plugins\EventStore.Plugins.csproj", "{504B01C5-281F-4CEA-A12F-D5333AB901EB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventStore.Plugins.Tests", "EventStore.Plugins.Tests\EventStore.Plugins.Tests.csproj", "{8D893FD3-3D17-4EEB-9F5A-A404237B6E78}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventStore.Plugins.Tests", "test\EventStore.Plugins.Tests\EventStore.Plugins.Tests.csproj", "{8D893FD3-3D17-4EEB-9F5A-A404237B6E78}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down

This file was deleted.

This file was deleted.

25 changes: 0 additions & 25 deletions src/EventStore.Plugins.Tests/EventStore.Plugins.Tests.csproj

This file was deleted.

117 changes: 57 additions & 60 deletions src/EventStore.Plugins/Authentication/AuthenticationRequest.cs
Original file line number Diff line number Diff line change
@@ -1,72 +1,69 @@
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using System.Security.Claims;

namespace EventStore.Plugins.Authentication {
public abstract class AuthenticationRequest {
/// <summary>
/// The Identifier for the source that this request came from
/// </summary>
public readonly string Id;
namespace EventStore.Plugins.Authentication;

/// <summary>
/// The name of the principal for the request
/// </summary>
public readonly string Name;
public abstract class AuthenticationRequest {
/// <summary>
/// Whether a valid client certificate was supplied with the request
/// </summary>
public readonly bool HasValidClientCertificate;

/// <summary>
/// The supplied password for the request
/// </summary>
public readonly string SuppliedPassword;
/// <summary>
/// The Identifier for the source that this request came from
/// </summary>
public readonly string Id;

/// <summary>
/// Whether or not a valid client certificate was supplied with the request
/// </summary>
public readonly bool HasValidClientCertificate;
/// <summary>
/// The name of the principal for the request
/// </summary>
public readonly string Name;

/// <summary>
/// All supplied authentication tokens for the request
/// </summary>
public readonly IReadOnlyDictionary<string, string> Tokens;
/// <summary>
/// The supplied password for the request
/// </summary>
public readonly string SuppliedPassword;

protected AuthenticationRequest(string id, IReadOnlyDictionary<string, string> tokens) {
ArgumentNullException.ThrowIfNull(id);
ArgumentNullException.ThrowIfNull(tokens);
/// <summary>
/// All supplied authentication tokens for the request
/// </summary>
public readonly IReadOnlyDictionary<string, string> Tokens;

Id = id;
Tokens = tokens;
Name = GetToken("uid");
SuppliedPassword = GetToken("pwd");
HasValidClientCertificate = GetToken("client-certificate") != null;
}
protected AuthenticationRequest(string? id, IReadOnlyDictionary<string, string>? tokens) {
ArgumentNullException.ThrowIfNull(id);
ArgumentNullException.ThrowIfNull(tokens);

/// <summary>
/// Gets the token corresponding to <param name="key" />.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string GetToken(string key) => Tokens.TryGetValue(key, out var token) ? token : null;
Id = id;
Tokens = tokens;
Name = GetToken("uid") ?? "";
SuppliedPassword = GetToken("pwd") ?? "";
HasValidClientCertificate = GetToken("client-certificate") != null;
}

/// <summary>
/// The request is unauthorized
/// </summary>
public abstract void Unauthorized();
/// <summary>
/// Gets the token corresponding to <param name="key" />.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string? GetToken(string key) => Tokens.GetValueOrDefault(key);

/// <summary>
/// The request was successfully authenticated
/// </summary>
/// <param name="principal">The <see cref="ClaimsPrincipal" /> of the authenticated request</param>
public abstract void Authenticated(ClaimsPrincipal principal);
/// <summary>
/// The request is unauthorized
/// </summary>
public abstract void Unauthorized();

/// <summary>
/// An error occurred during authentication
/// </summary>
public abstract void Error();
/// <summary>
/// The request was successfully authenticated
/// </summary>
/// <param name="principal">The <see cref="ClaimsPrincipal" /> of the authenticated request</param>
public abstract void Authenticated(ClaimsPrincipal principal);

/// <summary>
/// The authentication provider is not yet ready to service the request
/// </summary>
public abstract void NotReady();
}
}
/// <summary>
/// An error occurred during authentication
/// </summary>
public abstract void Error();

/// <summary>
/// The authentication provider is not yet ready to service the request
/// </summary>
public abstract void NotReady();
}
48 changes: 20 additions & 28 deletions src/EventStore.Plugins/Authentication/HttpAuthenticationRequest.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
using System.Collections.Generic;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

namespace EventStore.Plugins.Authentication;
Expand All @@ -12,58 +9,53 @@ public enum HttpAuthenticationRequestStatus {
Error,
NotReady,
Unauthenticated,
Authenticated,
Authenticated
}

public class HttpAuthenticationRequest : AuthenticationRequest {
private readonly TaskCompletionSource<(HttpAuthenticationRequestStatus, ClaimsPrincipal)> _tcs;
private readonly CancellationTokenRegistration _cancellationRegister;
readonly CancellationTokenRegistration _cancellationRegister;
readonly TaskCompletionSource<(HttpAuthenticationRequestStatus, ClaimsPrincipal?)> _tcs;

public HttpAuthenticationRequest(HttpContext context, string authToken) : this(context,
new Dictionary<string, string> {
["jwt"] = authToken
}) {
}
}) { }

public HttpAuthenticationRequest(HttpContext context, string name, string suppliedPassword) :
this(context, new Dictionary<string, string> {
["uid"] = name,
["pwd"] = suppliedPassword
}) {
}
}) { }

public static HttpAuthenticationRequest CreateWithValidCertificate(HttpContext context, string name, X509Certificate2 clientCertificate) =>
new(context, new Dictionary<string, string> {
["uid"] = name,
["client-certificate"] = clientCertificate.ExportCertificatePem(),
});

private HttpAuthenticationRequest(HttpContext context, IReadOnlyDictionary<string, string> tokens) : base(
HttpAuthenticationRequest(HttpContext context, IReadOnlyDictionary<string, string> tokens) : base(
context.TraceIdentifier, tokens) {
_tcs = new(TaskCreationOptions.RunContinuationsAsynchronously);
_cancellationRegister = context.RequestAborted.Register(Cancel);
}

private void Cancel() {
public static HttpAuthenticationRequest CreateWithValidCertificate(HttpContext context, string name, X509Certificate2 clientCertificate) => new(context,
new Dictionary<string, string> {
["uid"] = name,
["client-certificate"] = clientCertificate.ExportCertificatePem()
});

void Cancel() {
_tcs.TrySetCanceled();
_cancellationRegister.Dispose();
}

public override void Unauthorized() {
public override void Unauthorized() =>
_tcs.TrySetResult((HttpAuthenticationRequestStatus.Unauthenticated, default));
}

public override void Authenticated(ClaimsPrincipal principal) {
public override void Authenticated(ClaimsPrincipal principal) =>
_tcs.TrySetResult((HttpAuthenticationRequestStatus.Authenticated, principal));
}

public override void Error() {
public override void Error() =>
_tcs.TrySetResult((HttpAuthenticationRequestStatus.Error, default));
}

public override void NotReady() {
public override void NotReady() =>
_tcs.TrySetResult((HttpAuthenticationRequestStatus.NotReady, default));
}

public Task<(HttpAuthenticationRequestStatus, ClaimsPrincipal)> AuthenticateAsync() => _tcs.Task;
}
public Task<(HttpAuthenticationRequestStatus, ClaimsPrincipal?)> AuthenticateAsync() =>
_tcs.Task;
}
23 changes: 11 additions & 12 deletions src/EventStore.Plugins/Authentication/IAuthenticationPlugin.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
namespace EventStore.Plugins.Authentication {
public interface IAuthenticationPlugin {
string Name { get; }
string Version { get; }
namespace EventStore.Plugins.Authentication;

string CommandLineName { get; }
public interface IAuthenticationPlugin {
string Name { get; }
string Version { get; }
string CommandLineName { get; }

/// <summary>
/// Creates an authentication provider factory for the authentication plugin
/// </summary>
/// <param name="authenticationConfigPath">The path to the configuration file for the authentication plugin</param>
IAuthenticationProviderFactory GetAuthenticationProviderFactory(string authenticationConfigPath);
}
}
/// <summary>
/// Creates an authentication provider factory for the authentication plugin
/// </summary>
/// <param name="authenticationConfigPath">The path to the configuration file for the authentication plugin</param>
IAuthenticationProviderFactory GetAuthenticationProviderFactory(string authenticationConfigPath);
}
Loading

0 comments on commit eca0063

Please sign in to comment.