mirror of
https://github.com/bitwarden/server.git
synced 2024-11-21 12:05:42 +01:00
[AC-2605] Restrict collection access for some custom users (#4096)
* Make custom users subject to collection settings Affects ManageUsers and ManageGroups
This commit is contained in:
parent
489f6246b1
commit
98b7866c95
@ -217,12 +217,22 @@ public class BulkCollectionAuthorizationHandler : BulkAuthorizationHandler<BulkC
|
|||||||
|
|
||||||
private async Task<bool> CanUpdateUserAccessAsync(ICollection<Collection> resources, CurrentContextOrganization? org)
|
private async Task<bool> CanUpdateUserAccessAsync(ICollection<Collection> resources, CurrentContextOrganization? org)
|
||||||
{
|
{
|
||||||
return await CanUpdateCollectionAsync(resources, org) || org?.Permissions.ManageUsers == true;
|
if (await AllowAdminAccessToAllCollectionItems(org) && org?.Permissions.ManageUsers == true)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await CanUpdateCollectionAsync(resources, org);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool> CanUpdateGroupAccessAsync(ICollection<Collection> resources, CurrentContextOrganization? org)
|
private async Task<bool> CanUpdateGroupAccessAsync(ICollection<Collection> resources, CurrentContextOrganization? org)
|
||||||
{
|
{
|
||||||
return await CanUpdateCollectionAsync(resources, org) || org?.Permissions.ManageGroups == true;
|
if (await AllowAdminAccessToAllCollectionItems(org) && org?.Permissions.ManageGroups == true)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await CanUpdateCollectionAsync(resources, org);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<bool> CanDeleteAsync(ICollection<Collection> resources, CurrentContextOrganization? org)
|
private async Task<bool> CanDeleteAsync(ICollection<Collection> resources, CurrentContextOrganization? org)
|
||||||
@ -313,4 +323,11 @@ public class BulkCollectionAuthorizationHandler : BulkAuthorizationHandler<BulkC
|
|||||||
|
|
||||||
return await _applicationCacheService.GetOrganizationAbilityAsync(organization.Id);
|
return await _applicationCacheService.GetOrganizationAbilityAsync(organization.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<bool> AllowAdminAccessToAllCollectionItems(CurrentContextOrganization? org)
|
||||||
|
{
|
||||||
|
var organizationAbility = await GetOrganizationAbilityAsync(org);
|
||||||
|
return !_featureService.IsEnabled(FeatureFlagKeys.FlexibleCollectionsV1) ||
|
||||||
|
organizationAbility is { AllowAdminAccessToAllCollectionItems: true };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -828,79 +828,167 @@ public class BulkCollectionAuthorizationHandlerTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Theory, BitAutoData, CollectionCustomization]
|
[Theory, BitAutoData, CollectionCustomization]
|
||||||
public async Task CanUpdateUsers_WithManageUsersCustomPermission_Success(
|
public async Task CanUpdateUsers_WithManageUsersCustomPermission_V1Disabled_Success(
|
||||||
SutProvider<BulkCollectionAuthorizationHandler> sutProvider,
|
SutProvider<BulkCollectionAuthorizationHandler> sutProvider, ICollection<Collection> collections,
|
||||||
ICollection<Collection> collections,
|
CurrentContextOrganization organization, Guid actingUserId)
|
||||||
CurrentContextOrganization organization)
|
|
||||||
{
|
{
|
||||||
var actingUserId = Guid.NewGuid();
|
|
||||||
|
|
||||||
organization.Type = OrganizationUserType.Custom;
|
organization.Type = OrganizationUserType.Custom;
|
||||||
organization.Permissions = new Permissions
|
organization.Permissions = new Permissions
|
||||||
{
|
{
|
||||||
ManageUsers = true
|
ManageUsers = true
|
||||||
};
|
};
|
||||||
|
|
||||||
var operationsToTest = new[]
|
sutProvider.GetDependency<ICurrentContext>().UserId.Returns(actingUserId);
|
||||||
{
|
sutProvider.GetDependency<ICurrentContext>().GetOrganization(organization.Id).Returns(organization);
|
||||||
BulkCollectionOperations.ModifyUserAccess,
|
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.FlexibleCollectionsV1)
|
||||||
};
|
.Returns(false);
|
||||||
|
|
||||||
foreach (var op in operationsToTest)
|
var context = new AuthorizationHandlerContext(
|
||||||
{
|
new[] { BulkCollectionOperations.ModifyUserAccess },
|
||||||
sutProvider.GetDependency<ICurrentContext>().UserId.Returns(actingUserId);
|
new ClaimsPrincipal(),
|
||||||
sutProvider.GetDependency<ICurrentContext>().GetOrganization(organization.Id).Returns(organization);
|
collections);
|
||||||
|
|
||||||
var context = new AuthorizationHandlerContext(
|
await sutProvider.Sut.HandleAsync(context);
|
||||||
new[] { op },
|
|
||||||
new ClaimsPrincipal(),
|
|
||||||
collections);
|
|
||||||
|
|
||||||
await sutProvider.Sut.HandleAsync(context);
|
Assert.True(context.HasSucceeded);
|
||||||
|
|
||||||
Assert.True(context.HasSucceeded);
|
|
||||||
|
|
||||||
// Recreate the SUT to reset the mocks/dependencies between tests
|
|
||||||
sutProvider.Recreate();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory, BitAutoData, CollectionCustomization]
|
[Theory, BitAutoData, CollectionCustomization]
|
||||||
public async Task CanUpdateGroups_WithManageGroupsCustomPermission_Success(
|
public async Task CanUpdateUsers_WithManageUsersCustomPermission_AllowAdminAccessIsTrue_Success(
|
||||||
SutProvider<BulkCollectionAuthorizationHandler> sutProvider,
|
SutProvider<BulkCollectionAuthorizationHandler> sutProvider, ICollection<Collection> collections,
|
||||||
ICollection<Collection> collections,
|
CurrentContextOrganization organization, Guid actingUserId)
|
||||||
CurrentContextOrganization organization)
|
|
||||||
{
|
{
|
||||||
var actingUserId = Guid.NewGuid();
|
organization.Type = OrganizationUserType.Custom;
|
||||||
|
organization.Permissions = new Permissions
|
||||||
|
{
|
||||||
|
ManageUsers = true
|
||||||
|
};
|
||||||
|
|
||||||
|
sutProvider.GetDependency<ICurrentContext>().UserId.Returns(actingUserId);
|
||||||
|
sutProvider.GetDependency<ICurrentContext>().GetOrganization(organization.Id).Returns(organization);
|
||||||
|
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.FlexibleCollectionsV1)
|
||||||
|
.Returns(true);
|
||||||
|
sutProvider.GetDependency<IApplicationCacheService>().GetOrganizationAbilityAsync(organization.Id)
|
||||||
|
.Returns(new OrganizationAbility { AllowAdminAccessToAllCollectionItems = true });
|
||||||
|
|
||||||
|
var context = new AuthorizationHandlerContext(
|
||||||
|
new[] { BulkCollectionOperations.ModifyUserAccess },
|
||||||
|
new ClaimsPrincipal(),
|
||||||
|
collections);
|
||||||
|
|
||||||
|
await sutProvider.Sut.HandleAsync(context);
|
||||||
|
|
||||||
|
Assert.True(context.HasSucceeded);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory, BitAutoData, CollectionCustomization]
|
||||||
|
public async Task CanUpdateUsers_WithManageUsersCustomPermission_AllowAdminAccessIsFalse_Failure(
|
||||||
|
SutProvider<BulkCollectionAuthorizationHandler> sutProvider, ICollection<Collection> collections,
|
||||||
|
CurrentContextOrganization organization, Guid actingUserId)
|
||||||
|
{
|
||||||
|
organization.Type = OrganizationUserType.Custom;
|
||||||
|
organization.Permissions = new Permissions
|
||||||
|
{
|
||||||
|
ManageUsers = true
|
||||||
|
};
|
||||||
|
|
||||||
|
sutProvider.GetDependency<ICurrentContext>().UserId.Returns(actingUserId);
|
||||||
|
sutProvider.GetDependency<ICurrentContext>().GetOrganization(organization.Id).Returns(organization);
|
||||||
|
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.FlexibleCollectionsV1)
|
||||||
|
.Returns(true);
|
||||||
|
sutProvider.GetDependency<IApplicationCacheService>().GetOrganizationAbilityAsync(organization.Id)
|
||||||
|
.Returns(new OrganizationAbility { AllowAdminAccessToAllCollectionItems = false });
|
||||||
|
|
||||||
|
var context = new AuthorizationHandlerContext(
|
||||||
|
new[] { BulkCollectionOperations.ModifyUserAccess },
|
||||||
|
new ClaimsPrincipal(),
|
||||||
|
collections);
|
||||||
|
|
||||||
|
await sutProvider.Sut.HandleAsync(context);
|
||||||
|
|
||||||
|
Assert.False(context.HasSucceeded);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory, BitAutoData, CollectionCustomization]
|
||||||
|
public async Task CanUpdateGroups_WithManageGroupsCustomPermission_V1Disabled_Success(
|
||||||
|
SutProvider<BulkCollectionAuthorizationHandler> sutProvider, ICollection<Collection> collections,
|
||||||
|
CurrentContextOrganization organization, Guid actingUserId)
|
||||||
|
{
|
||||||
organization.Type = OrganizationUserType.Custom;
|
organization.Type = OrganizationUserType.Custom;
|
||||||
organization.Permissions = new Permissions
|
organization.Permissions = new Permissions
|
||||||
{
|
{
|
||||||
ManageGroups = true
|
ManageGroups = true
|
||||||
};
|
};
|
||||||
|
|
||||||
var operationsToTest = new[]
|
sutProvider.GetDependency<ICurrentContext>().UserId.Returns(actingUserId);
|
||||||
|
sutProvider.GetDependency<ICurrentContext>().GetOrganization(organization.Id).Returns(organization);
|
||||||
|
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.FlexibleCollectionsV1)
|
||||||
|
.Returns(false);
|
||||||
|
|
||||||
|
var context = new AuthorizationHandlerContext(
|
||||||
|
new[] { BulkCollectionOperations.ModifyGroupAccess },
|
||||||
|
new ClaimsPrincipal(),
|
||||||
|
collections);
|
||||||
|
|
||||||
|
await sutProvider.Sut.HandleAsync(context);
|
||||||
|
|
||||||
|
Assert.True(context.HasSucceeded);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory, BitAutoData, CollectionCustomization]
|
||||||
|
public async Task CanUpdateGroups_WithManageGroupsCustomPermission_AllowAdminAccessIsTrue_Success(
|
||||||
|
SutProvider<BulkCollectionAuthorizationHandler> sutProvider, ICollection<Collection> collections,
|
||||||
|
CurrentContextOrganization organization, Guid actingUserId)
|
||||||
|
{
|
||||||
|
organization.Type = OrganizationUserType.Custom;
|
||||||
|
organization.Permissions = new Permissions
|
||||||
{
|
{
|
||||||
BulkCollectionOperations.ModifyGroupAccess,
|
ManageGroups = true
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var op in operationsToTest)
|
sutProvider.GetDependency<ICurrentContext>().UserId.Returns(actingUserId);
|
||||||
|
sutProvider.GetDependency<ICurrentContext>().GetOrganization(organization.Id).Returns(organization);
|
||||||
|
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.FlexibleCollectionsV1)
|
||||||
|
.Returns(true);
|
||||||
|
sutProvider.GetDependency<IApplicationCacheService>().GetOrganizationAbilityAsync(organization.Id)
|
||||||
|
.Returns(new OrganizationAbility { AllowAdminAccessToAllCollectionItems = true });
|
||||||
|
|
||||||
|
var context = new AuthorizationHandlerContext(
|
||||||
|
new[] { BulkCollectionOperations.ModifyGroupAccess },
|
||||||
|
new ClaimsPrincipal(),
|
||||||
|
collections);
|
||||||
|
|
||||||
|
await sutProvider.Sut.HandleAsync(context);
|
||||||
|
|
||||||
|
Assert.True(context.HasSucceeded);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory, BitAutoData, CollectionCustomization]
|
||||||
|
public async Task CanUpdateGroups_WithManageGroupsCustomPermission_AllowAdminAccessIsFalse_Failure(
|
||||||
|
SutProvider<BulkCollectionAuthorizationHandler> sutProvider, ICollection<Collection> collections,
|
||||||
|
CurrentContextOrganization organization, Guid actingUserId)
|
||||||
|
{
|
||||||
|
organization.Type = OrganizationUserType.Custom;
|
||||||
|
organization.Permissions = new Permissions
|
||||||
{
|
{
|
||||||
sutProvider.GetDependency<ICurrentContext>().UserId.Returns(actingUserId);
|
ManageGroups = true
|
||||||
sutProvider.GetDependency<ICurrentContext>().GetOrganization(organization.Id).Returns(organization);
|
};
|
||||||
|
|
||||||
var context = new AuthorizationHandlerContext(
|
sutProvider.GetDependency<ICurrentContext>().UserId.Returns(actingUserId);
|
||||||
new[] { op },
|
sutProvider.GetDependency<ICurrentContext>().GetOrganization(organization.Id).Returns(organization);
|
||||||
new ClaimsPrincipal(),
|
sutProvider.GetDependency<IFeatureService>().IsEnabled(FeatureFlagKeys.FlexibleCollectionsV1)
|
||||||
collections);
|
.Returns(true);
|
||||||
|
sutProvider.GetDependency<IApplicationCacheService>().GetOrganizationAbilityAsync(organization.Id)
|
||||||
|
.Returns(new OrganizationAbility { AllowAdminAccessToAllCollectionItems = false });
|
||||||
|
|
||||||
await sutProvider.Sut.HandleAsync(context);
|
var context = new AuthorizationHandlerContext(
|
||||||
|
new[] { BulkCollectionOperations.ModifyGroupAccess },
|
||||||
|
new ClaimsPrincipal(),
|
||||||
|
collections);
|
||||||
|
|
||||||
Assert.True(context.HasSucceeded);
|
await sutProvider.Sut.HandleAsync(context);
|
||||||
|
|
||||||
// Recreate the SUT to reset the mocks/dependencies between tests
|
Assert.False(context.HasSucceeded);
|
||||||
sutProvider.Recreate();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory, BitAutoData, CollectionCustomization]
|
[Theory, BitAutoData, CollectionCustomization]
|
||||||
|
Loading…
Reference in New Issue
Block a user