| | | 1 | | using Elsa.Diagnostics.OpenTelemetry.Contracts; |
| | | 2 | | using Elsa.Diagnostics.OpenTelemetry.Models; |
| | | 3 | | using Elsa.Diagnostics.OpenTelemetry.Permissions; |
| | | 4 | | using FastEndpoints.Security; |
| | | 5 | | using Microsoft.AspNetCore.Authorization; |
| | | 6 | | using Microsoft.AspNetCore.SignalR; |
| | | 7 | | |
| | | 8 | | namespace Elsa.Diagnostics.OpenTelemetry.RealTime; |
| | | 9 | | |
| | | 10 | | [Authorize] |
| | 5 | 11 | | public class OpenTelemetryHub(OpenTelemetrySubscriptionManager subscriptionManager) : Hub<IOpenTelemetryClient> |
| | | 12 | | { |
| | | 13 | | private const string ReadAllPermission = "read:*"; |
| | 1 | 14 | | private static readonly string[] ReadPermissions = [PermissionNames.All, ReadAllPermission, OpenTelemetryPermissions |
| | | 15 | | |
| | | 16 | | public Task SubscribeAsync(OpenTelemetryTraceFilter? filter) |
| | | 17 | | { |
| | 5 | 18 | | EnsureCanReadOpenTelemetry(); |
| | 4 | 19 | | return subscriptionManager.SubscribeAsync(Context.ConnectionId, ValidateFilter(filter), Context.ConnectionAborte |
| | | 20 | | } |
| | | 21 | | |
| | | 22 | | public Task UnsubscribeAsync() |
| | | 23 | | { |
| | 0 | 24 | | return subscriptionManager.UnsubscribeAsync(Context.ConnectionId); |
| | | 25 | | } |
| | | 26 | | |
| | | 27 | | public override async Task OnDisconnectedAsync(Exception? exception) |
| | | 28 | | { |
| | 0 | 29 | | await UnsubscribeAsync().ConfigureAwait(false); |
| | 0 | 30 | | await base.OnDisconnectedAsync(exception).ConfigureAwait(false); |
| | 0 | 31 | | } |
| | | 32 | | |
| | | 33 | | private static OpenTelemetryTraceFilter ValidateFilter(OpenTelemetryTraceFilter? filter) |
| | | 34 | | { |
| | 4 | 35 | | filter ??= new(); |
| | | 36 | | |
| | 4 | 37 | | if (filter.From is { } from && filter.To is { } to && from > to) |
| | 1 | 38 | | throw new HubException("The OpenTelemetry filter 'from' timestamp must be earlier than or equal to 'to'."); |
| | | 39 | | |
| | 3 | 40 | | return filter; |
| | | 41 | | } |
| | | 42 | | |
| | | 43 | | private void EnsureCanReadOpenTelemetry() |
| | | 44 | | { |
| | 5 | 45 | | var user = Context.User; |
| | | 46 | | |
| | 5 | 47 | | if (user?.Identity?.IsAuthenticated != true || !ReadPermissions.Any(user.HasPermission)) |
| | 1 | 48 | | throw new HubException("Access denied."); |
| | 4 | 49 | | } |
| | | 50 | | } |