-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Org page now shows "Leave org" button only to members * Org page now shows Settings tab only to members or site admins * Members list on org page hides email/username column if you're not an org admin (or site admin) * Members list on org page only shows org admins if a non-member is viewing it * Projects list on org page only shows public projects, or projects you yourself are a member of * This rule applies to both members and non-members equally * Org admins can still see all projects (and site admins too) * Org admins can click on any org member to see all his details * Works like admin dashboard, but can only view org members --------- Co-authored-by: Tim Haasdyk <[email protected]> Co-authored-by: Kevin Hahn <[email protected]>
- Loading branch information
1 parent
c39a189
commit a928b89
Showing
28 changed files
with
734 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
namespace LexBoxApi.GraphQL.CustomTypes; | ||
|
||
public class OrgMemberDto | ||
{ | ||
public required Guid Id { get; set; } | ||
public DateTimeOffset CreatedDate { get; set; } | ||
public DateTimeOffset UpdatedDate { get; set; } | ||
public DateTimeOffset LastActive { get; set; } | ||
public required string Name { get; set; } | ||
public required string? Email { get; set; } | ||
public required string? Username { get; set; } | ||
public required string LocalizationCode { get; set; } | ||
public required bool EmailVerified { get; set; } | ||
public required bool IsAdmin { get; set; } | ||
public required bool Locked { get; set; } | ||
public required bool CanCreateProjects { get; set; } | ||
public required OrgMemberDtoCreatedBy? CreatedBy { get; set; } | ||
} | ||
|
||
public class OrgMemberDtoCreatedBy | ||
{ | ||
public required Guid Id { get; set; } | ||
public required string Name { get; set; } | ||
} |
75 changes: 75 additions & 0 deletions
75
backend/LexBoxApi/GraphQL/CustomTypes/RefreshJwtOrgMembershipMiddleware.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
using HotChocolate.Resolvers; | ||
using LexBoxApi.Auth; | ||
using LexCore.Auth; | ||
using LexCore.Entities; | ||
|
||
namespace LexBoxApi.GraphQL.CustomTypes; | ||
|
||
public class RefreshJwtOrgMembershipMiddleware(FieldDelegate next) | ||
{ | ||
public async Task InvokeAsync(IMiddlewareContext context) | ||
{ | ||
await next(context); | ||
if (UserAlreadyRefreshed(context)) | ||
{ | ||
return; | ||
} | ||
|
||
var user = context.Service<LoggedInContext>().MaybeUser; | ||
if (user is null || user.Role == UserRole.admin) return; | ||
|
||
var orgId = context.Parent<Organization>().Id; | ||
if (orgId == default) | ||
{ | ||
if (context.Result is not Guid orgGuid) return; | ||
if (orgGuid == default) return; | ||
orgId = orgGuid; | ||
} // we know we have a valid org-ID | ||
|
||
var currUserMembershipJwt = user.Orgs.FirstOrDefault(orgs => orgs.OrgId == orgId); | ||
|
||
if (currUserMembershipJwt is null) | ||
{ | ||
// The user was probably added to the org and it's not in the token yet | ||
await RefreshUser(context, user.Id); | ||
return; | ||
} | ||
|
||
if (context.Result is not IEnumerable<OrgMember> orgMembers) return; | ||
|
||
var sampleOrgUser = orgMembers.FirstOrDefault(); | ||
if (sampleOrgUser is not null && sampleOrgUser.UserId == default && (sampleOrgUser.User == null || sampleOrgUser.User.Id == default)) | ||
{ | ||
// User IDs don't seem to have been loaded from the DB, so we can't do anything | ||
return; | ||
} | ||
|
||
var currUserMembershipDb = orgMembers.FirstOrDefault(orgUser => user.Id == orgUser.UserId || user.Id == orgUser.User?.Id); | ||
if (currUserMembershipDb is null) | ||
{ | ||
// The user was probably removed from the org and it's still in the token | ||
await RefreshUser(context, user.Id); | ||
} | ||
else if (currUserMembershipDb.Role == default) | ||
{ | ||
return; // Either the role wasn't loaded by the query (so we can't do anything) or the role is actually Unknown which means it definitely has never been changed | ||
} | ||
else if (currUserMembershipDb.Role != currUserMembershipJwt.Role) | ||
{ | ||
// The user's role was changed | ||
await RefreshUser(context, user.Id); | ||
} | ||
} | ||
|
||
private static async Task RefreshUser(IMiddlewareContext context, Guid userId) | ||
{ | ||
var lexAuthService = context.Service<LexAuthService>(); | ||
context.ContextData[GraphQlSetupKernel.RefreshedJwtMembershipsKey] = true; | ||
await lexAuthService.RefreshUser(userId, LexAuthConstants.OrgsClaimType); | ||
} | ||
|
||
private static bool UserAlreadyRefreshed(IMiddlewareContext context) | ||
{ | ||
return context.ContextData.ContainsKey(GraphQlSetupKernel.RefreshedJwtMembershipsKey); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.