Skip to content

Commit

Permalink
Clean up sync and put better claims in av token
Browse files Browse the repository at this point in the history
  • Loading branch information
NixFey committed Dec 25, 2024
1 parent d19a814 commit c170a5c
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 11 deletions.
5 changes: 4 additions & 1 deletion FiMAdminApi/Clients/ClientsStartupExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ public static class ClientsStartupExtensions
{
public static void AddClients(this IServiceCollection services)
{
services.AddHttpClient(DataSources.FrcEvents.ToString());
services.AddHttpClient(DataSources.FrcEvents.ToString(), client =>
{
client.Timeout = TimeSpan.FromSeconds(10);
});
services.AddHttpClient(DataSources.BlueAlliance.ToString());
services.AddHttpClient(DataSources.FtcEvents.ToString());
services.AddKeyedScoped<IDataClient, FrcEventsDataClient>(DataSources.FrcEvents);
Expand Down
2 changes: 1 addition & 1 deletion FiMAdminApi/Endpoints/AvTokenEndpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ private static async Task<Results<Ok<CreateAvTokenResponse>, ProblemHttpResult>>
var jwtSecret = configuration["Auth:JwtSecret"] ??
throw new ApplicationException("Unable to get JWT secret from configuration");

List<Claim> claims = [new Claim("eventName", evt.Name), new Claim("eventKey", evt.Key)];
List<Claim> claims = [new Claim("eventId", evt.Id.ToString()), new Claim("eventKey", evt.Key)];
if (evt.Code is not null) claims.Add(new Claim("eventCode", evt.Code));

var maxAllowableExpiry = DateTime.UtcNow.AddDays(7);
Expand Down
11 changes: 8 additions & 3 deletions FiMAdminApi/Endpoints/EventSyncEndpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ private static async Task<Results<Ok<EventSyncResult>, NotFound, BadRequest<stri
}

private static async Task<Ok<EventSyncResult>> SyncCurrentEvents([FromServices] DataContext context,
[FromServices] EventSyncService syncService)
[FromServices] EventSyncService syncService, [FromServices] ILogger logger)
{
var events = context.Events.Include(e => e.Season).Where(e =>
e.SyncSource != null && e.StartTime <= DateTime.UtcNow && e.EndTime >= DateTime.UtcNow).AsAsyncEnumerable();
Expand All @@ -65,9 +65,14 @@ private static async Task<Ok<EventSyncResult>> SyncCurrentEvents([FromServices]
}, async (e, _) =>
{
var individualResult = await syncService.SyncEvent(e);
lock (successLock)
if (!individualResult.Success)
{
if (!individualResult.Success) isSuccess = false;
logger.LogWarning("Sync for event {EventCode} failed: {Message}", e.Code ?? e.Id.ToString(),
individualResult.Message ?? "No message provided");
lock (successLock)
{
isSuccess = false;
}
}
});

Expand Down
21 changes: 16 additions & 5 deletions FiMAdminApi/EventSync/EventSyncService.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using FiMAdminApi.Clients;
using FiMAdminApi.Data;
using FiMAdminApi.Data.Enums;
using FiMAdminApi.Data.Models;
using Microsoft.EntityFrameworkCore;

namespace FiMAdminApi.EventSync;

Expand All @@ -12,10 +10,16 @@ public class EventSyncService(DataContext dbContext, IServiceProvider services,
/// Attempt to run <see cref="EventSyncStep"/>s against an event until the status of the event stabilizes. A given
/// step will be run at most once in a sync.
/// </summary>
/// <remarks>
/// Nothing in this method should throw. Instead, it should return a sync result reporting not successful and a
/// message. This ensures that processes which want to sync many events are not short-circuited if one fails.
/// </remarks>
public async Task<EventSyncResult> SyncEvent(Event evt)
{
if (evt.Season is null) throw new ArgumentException("Event season data is missing");
if (evt.SyncSource is null || evt.Code is null) throw new ArgumentException("Event not set up for syncing");
if (evt.Season is null)
return new EventSyncResult(false, "Event season data is missing");
if (evt.SyncSource is null || evt.Code is null)
return new EventSyncResult(false, "Event not set up for syncing");

var dataSource = services.GetRequiredKeyedService<IDataClient>(evt.SyncSource);

Expand All @@ -33,7 +37,14 @@ public async Task<EventSyncResult> SyncEvent(Event evt)
evt.Code);
alreadyRunSteps.Add(step.GetType());
runAgain = true;
await step.RunStep(evt, dataSource);
try
{
await step.RunStep(evt, dataSource);
}
catch (Exception ex)
{
return new EventSyncResult(false, ex.Message);
}
}
}

Expand Down
13 changes: 12 additions & 1 deletion FiMAdminApi/SupabaseJwtHandler.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Authentication;
Expand Down Expand Up @@ -37,6 +38,16 @@ protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
}

var token = authorizationHeader["Bearer ".Length..].Trim();

// Sanity check the token before we send it off to Supabase
try
{
_ = new JwtSecurityToken(token);
}
catch (Exception)
{
return AuthenticateResult.Fail("JWT was not in a valid format");
}

// Call the API to validate the token
User user;
Expand All @@ -46,7 +57,7 @@ protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
}
catch (Exception ex)
{
Logger.LogWarning(ex, "Exception thrown while validating token");
Logger.LogInformation(ex, "Exception thrown while validating token");
return AuthenticateResult.Fail("Token validation failed.");
}

Expand Down

0 comments on commit c170a5c

Please sign in to comment.