fix: scope organization access by membership
This commit is contained in:
@@ -24,7 +24,7 @@ internal sealed class AccessScopeService(
|
|||||||
|
|
||||||
public static bool CanAccessWorkspace(ClaimsPrincipal user, Guid workspaceId)
|
public static bool CanAccessWorkspace(ClaimsPrincipal user, Guid workspaceId)
|
||||||
{
|
{
|
||||||
return IsManager(user) || user.GetWorkspaceScopeIds().Contains(workspaceId);
|
return user.GetWorkspaceScopeIds().Contains(workspaceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool CanManageWorkspace(ClaimsPrincipal user, Guid workspaceId)
|
public static bool CanManageWorkspace(ClaimsPrincipal user, Guid workspaceId)
|
||||||
@@ -34,24 +34,25 @@ internal sealed class AccessScopeService(
|
|||||||
|
|
||||||
public static bool CanAccessClient(ClaimsPrincipal user, Guid workspaceId, Guid clientId)
|
public static bool CanAccessClient(ClaimsPrincipal user, Guid workspaceId, Guid clientId)
|
||||||
{
|
{
|
||||||
return IsManager(user)
|
return CanAccessWorkspace(user, workspaceId) &&
|
||||||
|| (CanAccessWorkspace(user, workspaceId) && user.GetClientScopeIds().Contains(clientId));
|
(IsManager(user) || user.GetClientScopeIds().Contains(clientId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool CanAccessCampaign(ClaimsPrincipal user, Guid workspaceId, Guid clientId, Guid campaignId)
|
public static bool CanAccessCampaign(ClaimsPrincipal user, Guid workspaceId, Guid clientId, Guid campaignId)
|
||||||
{
|
{
|
||||||
return IsManager(user)
|
return CanAccessClient(user, workspaceId, clientId) &&
|
||||||
|| (CanAccessClient(user, workspaceId, clientId) && user.GetCampaignScopeIds().Contains(campaignId));
|
(IsManager(user) || user.GetCampaignScopeIds().Contains(campaignId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool CanContributeToCampaign(ClaimsPrincipal user, Guid workspaceId, Guid clientId, Guid campaignId)
|
public static bool CanContributeToCampaign(ClaimsPrincipal user, Guid workspaceId, Guid clientId, Guid campaignId)
|
||||||
{
|
{
|
||||||
return IsManager(user) || (IsProvider(user) && CanAccessCampaign(user, workspaceId, clientId, campaignId));
|
return IsManager(user) && CanAccessCampaign(user, workspaceId, clientId, campaignId)
|
||||||
|
|| IsProvider(user) && CanAccessCampaign(user, workspaceId, clientId, campaignId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool CanReviewContent(ClaimsPrincipal user, Guid workspaceId, Guid clientId, Guid campaignId)
|
public static bool CanReviewContent(ClaimsPrincipal user, Guid workspaceId, Guid clientId, Guid campaignId)
|
||||||
{
|
{
|
||||||
return IsManager(user)
|
return IsManager(user) && CanAccessCampaign(user, workspaceId, clientId, campaignId)
|
||||||
|| IsProvider(user) && CanAccessCampaign(user, workspaceId, clientId, campaignId)
|
|| IsProvider(user) && CanAccessCampaign(user, workspaceId, clientId, campaignId)
|
||||||
|| IsClient(user) && CanAccessClient(user, workspaceId, clientId);
|
|| IsClient(user) && CanAccessClient(user, workspaceId, clientId);
|
||||||
}
|
}
|
||||||
@@ -68,7 +69,7 @@ internal sealed class AccessScopeService(
|
|||||||
Guid workspaceId,
|
Guid workspaceId,
|
||||||
CancellationToken ct)
|
CancellationToken ct)
|
||||||
{
|
{
|
||||||
return CanAccessWorkspace(user, workspaceId)
|
return user.GetWorkspaceScopeIds().Contains(workspaceId)
|
||||||
|| await organizationAccessService.HasInheritedWorkspacePermissionAsync(
|
|| await organizationAccessService.HasInheritedWorkspacePermissionAsync(
|
||||||
user,
|
user,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
@@ -81,7 +82,7 @@ internal sealed class AccessScopeService(
|
|||||||
Guid workspaceId,
|
Guid workspaceId,
|
||||||
CancellationToken ct)
|
CancellationToken ct)
|
||||||
{
|
{
|
||||||
return IsManager(user)
|
return CanManageWorkspace(user, workspaceId)
|
||||||
|| await organizationAccessService.HasInheritedWorkspacePermissionAsync(
|
|| await organizationAccessService.HasInheritedWorkspacePermissionAsync(
|
||||||
user,
|
user,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
@@ -94,8 +95,7 @@ internal sealed class AccessScopeService(
|
|||||||
Guid organizationId,
|
Guid organizationId,
|
||||||
CancellationToken ct)
|
CancellationToken ct)
|
||||||
{
|
{
|
||||||
return IsManager(user)
|
return await organizationAccessService.HasOrganizationPermissionAsync(
|
||||||
|| await organizationAccessService.HasOrganizationPermissionAsync(
|
|
||||||
user,
|
user,
|
||||||
organizationId,
|
organizationId,
|
||||||
OrganizationPermissions.CreateWorkspaces,
|
OrganizationPermissions.CreateWorkspaces,
|
||||||
@@ -108,8 +108,7 @@ internal sealed class AccessScopeService(
|
|||||||
Guid clientId,
|
Guid clientId,
|
||||||
CancellationToken ct)
|
CancellationToken ct)
|
||||||
{
|
{
|
||||||
if (IsManager(user) ||
|
if (await organizationAccessService.HasInheritedWorkspacePermissionAsync(
|
||||||
await organizationAccessService.HasInheritedWorkspacePermissionAsync(
|
|
||||||
user,
|
user,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
OrganizationPermissions.AccessOwnedWorkspaces,
|
OrganizationPermissions.AccessOwnedWorkspaces,
|
||||||
@@ -128,8 +127,7 @@ internal sealed class AccessScopeService(
|
|||||||
Guid campaignId,
|
Guid campaignId,
|
||||||
CancellationToken ct)
|
CancellationToken ct)
|
||||||
{
|
{
|
||||||
if (IsManager(user) ||
|
if (await organizationAccessService.HasInheritedWorkspacePermissionAsync(
|
||||||
await organizationAccessService.HasInheritedWorkspacePermissionAsync(
|
|
||||||
user,
|
user,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
OrganizationPermissions.AccessOwnedWorkspaces,
|
OrganizationPermissions.AccessOwnedWorkspaces,
|
||||||
@@ -149,7 +147,7 @@ internal sealed class AccessScopeService(
|
|||||||
Guid campaignId,
|
Guid campaignId,
|
||||||
CancellationToken ct)
|
CancellationToken ct)
|
||||||
{
|
{
|
||||||
return IsManager(user)
|
return IsManager(user) && await CanAccessCampaignAsync(user, workspaceId, clientId, campaignId, ct)
|
||||||
|| await organizationAccessService.HasInheritedWorkspacePermissionAsync(
|
|| await organizationAccessService.HasInheritedWorkspacePermissionAsync(
|
||||||
user,
|
user,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
@@ -165,7 +163,7 @@ internal sealed class AccessScopeService(
|
|||||||
Guid campaignId,
|
Guid campaignId,
|
||||||
CancellationToken ct)
|
CancellationToken ct)
|
||||||
{
|
{
|
||||||
return IsManager(user)
|
return IsManager(user) && await CanAccessCampaignAsync(user, workspaceId, clientId, campaignId, ct)
|
||||||
|| await organizationAccessService.HasInheritedWorkspacePermissionAsync(
|
|| await organizationAccessService.HasInheritedWorkspacePermissionAsync(
|
||||||
user,
|
user,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
|
|||||||
@@ -34,23 +34,20 @@ internal class GetCampaignsHandler(
|
|||||||
{
|
{
|
||||||
IQueryable<Campaign> query = dbContext.Campaigns.AsQueryable();
|
IQueryable<Campaign> query = dbContext.Campaigns.AsQueryable();
|
||||||
|
|
||||||
if (!AccessScopeService.IsManager(User))
|
IReadOnlyCollection<Guid> workspaceScopeIds = await accessScopeService.GetAccessibleWorkspaceIdsAsync(User, ct);
|
||||||
|
IReadOnlyCollection<Guid> clientScopeIds = User.GetClientScopeIds();
|
||||||
|
IReadOnlyCollection<Guid> campaignScopeIds = User.GetCampaignScopeIds();
|
||||||
|
|
||||||
|
query = query.Where(campaign => workspaceScopeIds.Contains(campaign.WorkspaceId));
|
||||||
|
|
||||||
|
if (!AccessScopeService.IsManager(User) && clientScopeIds.Count > 0)
|
||||||
{
|
{
|
||||||
IReadOnlyCollection<Guid> workspaceScopeIds = await accessScopeService.GetAccessibleWorkspaceIdsAsync(User, ct);
|
query = query.Where(campaign => clientScopeIds.Contains(campaign.ClientId));
|
||||||
IReadOnlyCollection<Guid> clientScopeIds = User.GetClientScopeIds();
|
}
|
||||||
IReadOnlyCollection<Guid> campaignScopeIds = User.GetCampaignScopeIds();
|
|
||||||
|
|
||||||
query = query.Where(campaign => workspaceScopeIds.Contains(campaign.WorkspaceId));
|
if (!AccessScopeService.IsManager(User) && campaignScopeIds.Count > 0)
|
||||||
|
{
|
||||||
if (clientScopeIds.Count > 0)
|
query = query.Where(campaign => campaignScopeIds.Contains(campaign.Id));
|
||||||
{
|
|
||||||
query = query.Where(campaign => clientScopeIds.Contains(campaign.ClientId));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (campaignScopeIds.Count > 0)
|
|
||||||
{
|
|
||||||
query = query.Where(campaign => campaignScopeIds.Contains(campaign.Id));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.ClientId.HasValue)
|
if (request.ClientId.HasValue)
|
||||||
|
|||||||
@@ -23,11 +23,8 @@ internal class GetChannelsHandler(
|
|||||||
{
|
{
|
||||||
IQueryable<Channel> query = dbContext.Channels.AsQueryable();
|
IQueryable<Channel> query = dbContext.Channels.AsQueryable();
|
||||||
|
|
||||||
if (!AccessScopeService.IsManager(User))
|
IReadOnlyCollection<Guid> workspaceScopeIds = await accessScopeService.GetAccessibleWorkspaceIdsAsync(User, ct);
|
||||||
{
|
query = query.Where(channel => workspaceScopeIds.Contains(channel.WorkspaceId));
|
||||||
IReadOnlyCollection<Guid> workspaceScopeIds = await accessScopeService.GetAccessibleWorkspaceIdsAsync(User, ct);
|
|
||||||
query = query.Where(channel => workspaceScopeIds.Contains(channel.WorkspaceId));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request.WorkspaceId.HasValue)
|
if (request.WorkspaceId.HasValue)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,18 +33,14 @@ internal class GetClientsHandler(
|
|||||||
{
|
{
|
||||||
IQueryable<Client> query = dbContext.Clients.AsQueryable();
|
IQueryable<Client> query = dbContext.Clients.AsQueryable();
|
||||||
|
|
||||||
if (!AccessScopeService.IsManager(User))
|
IReadOnlyCollection<Guid> workspaceScopeIds = await accessScopeService.GetAccessibleWorkspaceIdsAsync(User, ct);
|
||||||
|
IReadOnlyCollection<Guid> clientScopeIds = User.GetClientScopeIds();
|
||||||
|
|
||||||
|
query = query.Where(client => workspaceScopeIds.Contains(client.WorkspaceId));
|
||||||
|
|
||||||
|
if (!AccessScopeService.IsManager(User) && clientScopeIds.Count > 0)
|
||||||
{
|
{
|
||||||
IReadOnlyCollection<Guid> workspaceScopeIds = await accessScopeService.GetAccessibleWorkspaceIdsAsync(User, ct);
|
query = query.Where(client => clientScopeIds.Contains(client.Id));
|
||||||
IReadOnlyCollection<Guid> clientScopeIds = User.GetClientScopeIds();
|
|
||||||
|
|
||||||
query = query.Where(client => workspaceScopeIds.Contains(client.WorkspaceId));
|
|
||||||
|
|
||||||
if (clientScopeIds.Count > 0)
|
|
||||||
{
|
|
||||||
query = query.Where(client => clientScopeIds.Contains(client.Id));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.WorkspaceId.HasValue)
|
if (request.WorkspaceId.HasValue)
|
||||||
|
|||||||
@@ -37,23 +37,20 @@ internal class GetContentItemsHandler(
|
|||||||
{
|
{
|
||||||
IQueryable<ContentItem> query = dbContext.ContentItems.AsQueryable();
|
IQueryable<ContentItem> query = dbContext.ContentItems.AsQueryable();
|
||||||
|
|
||||||
if (!AccessScopeService.IsManager(User))
|
IReadOnlyCollection<Guid> workspaceScopeIds = await accessScopeService.GetAccessibleWorkspaceIdsAsync(User, ct);
|
||||||
|
IReadOnlyCollection<Guid> clientScopeIds = User.GetClientScopeIds();
|
||||||
|
IReadOnlyCollection<Guid> campaignScopeIds = User.GetCampaignScopeIds();
|
||||||
|
|
||||||
|
query = query.Where(item => workspaceScopeIds.Contains(item.WorkspaceId));
|
||||||
|
|
||||||
|
if (!AccessScopeService.IsManager(User) && clientScopeIds.Count > 0)
|
||||||
{
|
{
|
||||||
IReadOnlyCollection<Guid> workspaceScopeIds = await accessScopeService.GetAccessibleWorkspaceIdsAsync(User, ct);
|
query = query.Where(item => clientScopeIds.Contains(item.ClientId));
|
||||||
IReadOnlyCollection<Guid> clientScopeIds = User.GetClientScopeIds();
|
}
|
||||||
IReadOnlyCollection<Guid> campaignScopeIds = User.GetCampaignScopeIds();
|
|
||||||
|
|
||||||
query = query.Where(item => workspaceScopeIds.Contains(item.WorkspaceId));
|
if (!AccessScopeService.IsManager(User) && campaignScopeIds.Count > 0)
|
||||||
|
{
|
||||||
if (clientScopeIds.Count > 0)
|
query = query.Where(item => campaignScopeIds.Contains(item.CampaignId));
|
||||||
{
|
|
||||||
query = query.Where(item => clientScopeIds.Contains(item.ClientId));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (campaignScopeIds.Count > 0)
|
|
||||||
{
|
|
||||||
query = query.Where(item => campaignScopeIds.Contains(item.CampaignId));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.WorkspaceId.HasValue)
|
if (request.WorkspaceId.HasValue)
|
||||||
|
|||||||
@@ -56,13 +56,10 @@ internal class GetNotificationsHandler(
|
|||||||
IQueryable<NotificationEvent> query = dbContext.NotificationEvents.AsQueryable();
|
IQueryable<NotificationEvent> query = dbContext.NotificationEvents.AsQueryable();
|
||||||
Guid currentUserId = User.GetUserId();
|
Guid currentUserId = User.GetUserId();
|
||||||
|
|
||||||
if (!AccessScopeService.IsManager(User))
|
IReadOnlyCollection<Guid> workspaceScopeIds = await accessScopeService.GetAccessibleWorkspaceIdsAsync(User, ct);
|
||||||
{
|
query = query.Where(notificationEvent =>
|
||||||
IReadOnlyCollection<Guid> workspaceScopeIds = await accessScopeService.GetAccessibleWorkspaceIdsAsync(User, ct);
|
workspaceScopeIds.Contains(notificationEvent.WorkspaceId) ||
|
||||||
query = query.Where(notificationEvent =>
|
notificationEvent.RecipientUserId == currentUserId);
|
||||||
workspaceScopeIds.Contains(notificationEvent.WorkspaceId) ||
|
|
||||||
notificationEvent.RecipientUserId == currentUserId);
|
|
||||||
}
|
|
||||||
|
|
||||||
query = query.Where(notificationEvent =>
|
query = query.Where(notificationEvent =>
|
||||||
notificationEvent.RecipientUserId == null ||
|
notificationEvent.RecipientUserId == null ||
|
||||||
|
|||||||
@@ -2,29 +2,16 @@ using System.Security.Claims;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Socialize.Api.Data;
|
using Socialize.Api.Data;
|
||||||
using Socialize.Api.Infrastructure.Security;
|
using Socialize.Api.Infrastructure.Security;
|
||||||
using Socialize.Api.Modules.Identity.Contracts;
|
|
||||||
|
|
||||||
namespace Socialize.Api.Modules.Organizations.Services;
|
namespace Socialize.Api.Modules.Organizations.Services;
|
||||||
|
|
||||||
internal sealed class OrganizationAccessService(
|
internal sealed class OrganizationAccessService(
|
||||||
AppDbContext dbContext)
|
AppDbContext dbContext)
|
||||||
{
|
{
|
||||||
public static bool IsGlobalManager(ClaimsPrincipal user)
|
|
||||||
{
|
|
||||||
return user.IsInRole(KnownRoles.Administrator) || user.IsInRole(KnownRoles.Manager);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<IReadOnlyCollection<Guid>> GetAccessibleOrganizationIdsAsync(
|
public async Task<IReadOnlyCollection<Guid>> GetAccessibleOrganizationIdsAsync(
|
||||||
ClaimsPrincipal user,
|
ClaimsPrincipal user,
|
||||||
CancellationToken ct)
|
CancellationToken ct)
|
||||||
{
|
{
|
||||||
if (IsGlobalManager(user))
|
|
||||||
{
|
|
||||||
return await dbContext.Organizations
|
|
||||||
.Select(organization => organization.Id)
|
|
||||||
.ToArrayAsync(ct);
|
|
||||||
}
|
|
||||||
|
|
||||||
Guid userId = user.GetUserId();
|
Guid userId = user.GetUserId();
|
||||||
|
|
||||||
Guid[] ownedOrganizationIds = await dbContext.Organizations
|
Guid[] ownedOrganizationIds = await dbContext.Organizations
|
||||||
@@ -47,13 +34,6 @@ internal sealed class OrganizationAccessService(
|
|||||||
ClaimsPrincipal user,
|
ClaimsPrincipal user,
|
||||||
CancellationToken ct)
|
CancellationToken ct)
|
||||||
{
|
{
|
||||||
if (IsGlobalManager(user))
|
|
||||||
{
|
|
||||||
return await dbContext.Workspaces
|
|
||||||
.Select(workspace => workspace.Id)
|
|
||||||
.ToArrayAsync(ct);
|
|
||||||
}
|
|
||||||
|
|
||||||
Guid[] directWorkspaceIds = user.GetWorkspaceScopeIds().ToArray();
|
Guid[] directWorkspaceIds = user.GetWorkspaceScopeIds().ToArray();
|
||||||
Guid[] organizationWorkspaceIds = await GetInheritedWorkspaceIdsAsync(user, OrganizationPermissions.AccessOwnedWorkspaces, ct);
|
Guid[] organizationWorkspaceIds = await GetInheritedWorkspaceIdsAsync(user, OrganizationPermissions.AccessOwnedWorkspaces, ct);
|
||||||
|
|
||||||
@@ -68,11 +48,6 @@ internal sealed class OrganizationAccessService(
|
|||||||
Guid organizationId,
|
Guid organizationId,
|
||||||
CancellationToken ct)
|
CancellationToken ct)
|
||||||
{
|
{
|
||||||
if (IsGlobalManager(user))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Guid userId = user.GetUserId();
|
Guid userId = user.GetUserId();
|
||||||
|
|
||||||
return await dbContext.Organizations.AnyAsync(
|
return await dbContext.Organizations.AnyAsync(
|
||||||
@@ -89,11 +64,6 @@ internal sealed class OrganizationAccessService(
|
|||||||
string permission,
|
string permission,
|
||||||
CancellationToken ct)
|
CancellationToken ct)
|
||||||
{
|
{
|
||||||
if (IsGlobalManager(user))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Guid userId = user.GetUserId();
|
Guid userId = user.GetUserId();
|
||||||
|
|
||||||
bool owner = await dbContext.Organizations.AnyAsync(
|
bool owner = await dbContext.Organizations.AnyAsync(
|
||||||
@@ -117,11 +87,6 @@ internal sealed class OrganizationAccessService(
|
|||||||
Guid organizationId,
|
Guid organizationId,
|
||||||
CancellationToken ct)
|
CancellationToken ct)
|
||||||
{
|
{
|
||||||
if (IsGlobalManager(user))
|
|
||||||
{
|
|
||||||
return OrganizationPermissionRules.GetPermissionsForRole(OrganizationRoles.Owner);
|
|
||||||
}
|
|
||||||
|
|
||||||
Guid userId = user.GetUserId();
|
Guid userId = user.GetUserId();
|
||||||
|
|
||||||
bool owner = await dbContext.Organizations.AnyAsync(
|
bool owner = await dbContext.Organizations.AnyAsync(
|
||||||
@@ -150,11 +115,6 @@ internal sealed class OrganizationAccessService(
|
|||||||
string permission,
|
string permission,
|
||||||
CancellationToken ct)
|
CancellationToken ct)
|
||||||
{
|
{
|
||||||
if (IsGlobalManager(user))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Guid? organizationId = await dbContext.Workspaces
|
Guid? organizationId = await dbContext.Workspaces
|
||||||
.Where(workspace => workspace.Id == workspaceId)
|
.Where(workspace => workspace.Id == workspaceId)
|
||||||
.Select(workspace => (Guid?)workspace.OrganizationId)
|
.Select(workspace => (Guid?)workspace.OrganizationId)
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
using System.Security.Claims;
|
||||||
|
using Socialize.Api.Infrastructure.Security;
|
||||||
|
using Socialize.Api.Modules.Identity.Contracts;
|
||||||
|
|
||||||
|
namespace Socialize.Tests.Security;
|
||||||
|
|
||||||
|
public class AccessScopeServiceTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void Manager_role_does_not_grant_workspace_access_without_workspace_scope()
|
||||||
|
{
|
||||||
|
Guid workspaceId = Guid.NewGuid();
|
||||||
|
ClaimsPrincipal user = CreateUser(KnownRoles.Manager);
|
||||||
|
|
||||||
|
Assert.False(AccessScopeService.CanAccessWorkspace(user, workspaceId));
|
||||||
|
Assert.False(AccessScopeService.CanManageWorkspace(user, workspaceId));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Administrator_role_does_not_grant_workspace_access_without_workspace_scope()
|
||||||
|
{
|
||||||
|
Guid workspaceId = Guid.NewGuid();
|
||||||
|
ClaimsPrincipal user = CreateUser(KnownRoles.Administrator);
|
||||||
|
|
||||||
|
Assert.False(AccessScopeService.CanAccessWorkspace(user, workspaceId));
|
||||||
|
Assert.False(AccessScopeService.CanManageWorkspace(user, workspaceId));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Manager_can_manage_only_workspaces_in_scope()
|
||||||
|
{
|
||||||
|
Guid workspaceId = Guid.NewGuid();
|
||||||
|
ClaimsPrincipal user = CreateUser(KnownRoles.Manager, new Claim(KnownClaims.WorkspaceScope, workspaceId.ToString()));
|
||||||
|
|
||||||
|
Assert.True(AccessScopeService.CanAccessWorkspace(user, workspaceId));
|
||||||
|
Assert.True(AccessScopeService.CanManageWorkspace(user, workspaceId));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ClaimsPrincipal CreateUser(string role, params Claim[] claims)
|
||||||
|
{
|
||||||
|
Claim[] baseClaims =
|
||||||
|
[
|
||||||
|
new(ClaimTypes.NameIdentifier, Guid.NewGuid().ToString()),
|
||||||
|
new(ClaimTypes.Role, role),
|
||||||
|
];
|
||||||
|
|
||||||
|
return new ClaimsPrincipal(new ClaimsIdentity(baseClaims.Concat(claims), "Test"));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user