Skip to content

Commit

Permalink
Fix redundant updates from concurrent middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
myieye authored and hahn-kev committed Dec 15, 2023
1 parent 08ace6c commit 7a08cab
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@

namespace LexBoxApi.GraphQL.CustomTypes;

public class RefreshJwtProjectMembershipMiddleware(FieldDelegate next, ILogger<RefreshJwtProjectMembershipMiddleware> logger)
public class RefreshJwtProjectMembershipMiddleware(FieldDelegate next)
{
private const string REFRESHED_USER_KEY = "RefreshedJwtProjectMembership";

public async Task InvokeAsync(IMiddlewareContext context)
{
await next(context);
var httpContext = context.GetGlobalStateOrDefault<HttpContext>("HttpContext");
if (httpContext?.Response.Headers.ContainsKey(LexAuthService.JwtUpdatedHeader) == true)
if (UserAlreadyRefreshed(context))
{
// The JWT was already updated, skip processing
return;
}

Expand All @@ -28,13 +28,12 @@ public async Task InvokeAsync(IMiddlewareContext context)
projectId = projectGuid;
} // we know we have a valid project-ID

var lexAuthService = context.Service<LexAuthService>();
var currUserMembershipJwt = user.Projects.FirstOrDefault(projects => projects.ProjectId == projectId);

if (currUserMembershipJwt is null)
{
// The user was probably added to the project and it's not in the token yet
await lexAuthService.RefreshUser(user.Id, LexAuthConstants.ProjectsClaimType);
await RefreshUser(context, user.Id);
return;
}

Expand All @@ -51,7 +50,7 @@ public async Task InvokeAsync(IMiddlewareContext context)
if (currUserMembershipDb is null)
{
// The user was probably removed from the project and it's still in the token
await lexAuthService.RefreshUser(user.Id, LexAuthConstants.ProjectsClaimType);
await RefreshUser(context, user.Id);
}
else if (currUserMembershipDb.Role == default)
{
Expand All @@ -60,7 +59,19 @@ public async Task InvokeAsync(IMiddlewareContext context)
else if (currUserMembershipDb.Role != currUserMembershipJwt.Role)
{
// The user's role was changed
await lexAuthService.RefreshUser(user.Id, LexAuthConstants.ProjectsClaimType);
await RefreshUser(context, user.Id);
}
}

private static async Task RefreshUser(IMiddlewareContext context, Guid userId)
{
var lexAuthService = context.Service<LexAuthService>();
context.ScopedContextData = context.ScopedContextData.SetItem(REFRESHED_USER_KEY, true);
await lexAuthService.RefreshUser(userId, LexAuthConstants.ProjectsClaimType);
}

private static bool UserAlreadyRefreshed(IMiddlewareContext context)
{
return context.ScopedContextData.ContainsKey(REFRESHED_USER_KEY);
}
}
5 changes: 2 additions & 3 deletions backend/LexBoxApi/GraphQL/LexQueries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@ public class LexQueries

[UseProjection]
[UseSorting]
public async Task<IQueryable<Project>> MyProjects(LoggedInContext loggedInContext, LexBoxDbContext context, LexAuthService lexAuthService)
public IQueryable<Project> MyProjects(LoggedInContext loggedInContext, LexBoxDbContext context)
{
var userId = loggedInContext.User.Id;
var projects = context.Projects.Where(p => p.Users.Select(u => u.UserId).Contains(userId));
return projects;
return context.Projects.Where(p => p.Users.Select(u => u.UserId).Contains(userId));
}

[UseProjection]
Expand Down

0 comments on commit 7a08cab

Please sign in to comment.