mirror of
https://github.com/bitwarden/server
synced 2025-12-23 03:33:35 +00:00
* Update optionality to use org.FlexibleCollections Also break old feature flag key to ensure it's never enabled * Add logic to set defaults for collection management setting * Update optionality logic to use org property * Add comments * Add helper method for getting individual orgAbility * Fix validate user update permissions interface * Fix tests * dotnet format * Fix more tests * Simplify self-hosted update logic * Fix mapping * Use new getOrganizationAbility method * Refactor invite and save orgUser methods Pass in whole organization object instead of using OrganizationAbility * fix CipherService tests * dotnet format * Remove manager check to simplify this set of changes * Misc cleanup before review * Fix undefined variable * Refactor bulk-access endpoint to avoid early repo call * Restore manager check * Add tests for UpdateOrganizationLicenseCommand * Add nullable regions * Delete unused dependency * dotnet format * Fix test
101 lines
3.5 KiB
C#
101 lines
3.5 KiB
C#
#nullable enable
|
|
using Bit.Core.Context;
|
|
using Bit.Core.Enums;
|
|
using Bit.Core.Services;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
namespace Bit.Api.Vault.AuthorizationHandlers.Collections;
|
|
|
|
/// <summary>
|
|
/// Handles authorization logic for Collection operations.
|
|
/// This uses new logic implemented in the Flexible Collections initiative.
|
|
/// </summary>
|
|
public class CollectionAuthorizationHandler : AuthorizationHandler<CollectionOperationRequirement>
|
|
{
|
|
private readonly ICurrentContext _currentContext;
|
|
private readonly IFeatureService _featureService;
|
|
|
|
public CollectionAuthorizationHandler(
|
|
ICurrentContext currentContext,
|
|
IFeatureService featureService)
|
|
{
|
|
_currentContext = currentContext;
|
|
_featureService = featureService;
|
|
}
|
|
|
|
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context,
|
|
CollectionOperationRequirement requirement)
|
|
{
|
|
// Acting user is not authenticated, fail
|
|
if (!_currentContext.UserId.HasValue)
|
|
{
|
|
context.Fail();
|
|
return;
|
|
}
|
|
|
|
if (requirement.OrganizationId == default)
|
|
{
|
|
context.Fail();
|
|
return;
|
|
}
|
|
|
|
var org = _currentContext.GetOrganization(requirement.OrganizationId);
|
|
|
|
switch (requirement)
|
|
{
|
|
case not null when requirement.Name == nameof(CollectionOperations.ReadAll):
|
|
await CanReadAllAsync(context, requirement, org);
|
|
break;
|
|
|
|
case not null when requirement.Name == nameof(CollectionOperations.ReadAllWithAccess):
|
|
await CanReadAllWithAccessAsync(context, requirement, org);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private async Task CanReadAllAsync(AuthorizationHandlerContext context, CollectionOperationRequirement requirement,
|
|
CurrentContextOrganization? org)
|
|
{
|
|
// Owners, Admins, and users with EditAnyCollection, DeleteAnyCollection,
|
|
// or AccessImportExport permission can always read a collection
|
|
if (org is
|
|
{ Type: OrganizationUserType.Owner or OrganizationUserType.Admin } or
|
|
{ Permissions.EditAnyCollection: true } or
|
|
{ Permissions.DeleteAnyCollection: true } or
|
|
{ Permissions.AccessImportExport: true } or
|
|
{ Permissions.ManageGroups: true })
|
|
{
|
|
context.Succeed(requirement);
|
|
return;
|
|
}
|
|
|
|
// Allow provider users to read collections if they are a provider for the target organization
|
|
if (await _currentContext.ProviderUserForOrgAsync(requirement.OrganizationId))
|
|
{
|
|
context.Succeed(requirement);
|
|
}
|
|
}
|
|
|
|
private async Task CanReadAllWithAccessAsync(AuthorizationHandlerContext context, CollectionOperationRequirement requirement,
|
|
CurrentContextOrganization? org)
|
|
{
|
|
// Owners, Admins, and users with EditAnyCollection or DeleteAnyCollection
|
|
// permission can always read a collection
|
|
if (org is
|
|
{ Type: OrganizationUserType.Owner or OrganizationUserType.Admin } or
|
|
{ Permissions.EditAnyCollection: true } or
|
|
{ Permissions.DeleteAnyCollection: true } or
|
|
{ Permissions.ManageUsers: true })
|
|
{
|
|
context.Succeed(requirement);
|
|
return;
|
|
}
|
|
|
|
// Allow provider users to read collections if they are a provider for the target organization
|
|
if (await _currentContext.ProviderUserForOrgAsync(requirement.OrganizationId))
|
|
{
|
|
context.Succeed(requirement);
|
|
}
|
|
}
|
|
}
|