1
0
mirror of https://github.com/bitwarden/server.git synced 2025-02-21 02:41:21 +01:00

Complete first pass

This commit is contained in:
Thomas Rittson 2024-11-18 19:58:37 +10:00
parent c400210189
commit 2948896b52
No known key found for this signature in database
GPG Key ID: CDDDA03861C35E27
4 changed files with 77 additions and 1 deletions

View File

@ -1,11 +1,18 @@
using Bit.Api.Models.Response; using Bit.Api.Models.Response;
using Bit.Api.Tools.Models.Response; using Bit.Api.Tools.Models.Response;
using Bit.Api.Vault.Models.Response; using Bit.Api.Vault.Models.Response;
using Bit.Core;
using Bit.Core.AdminConsole.OrganizationFeatures.Shared.Authorization;
using Bit.Core.Context; using Bit.Core.Context;
using Bit.Core.Entities; using Bit.Core.Entities;
using Bit.Core.Exceptions;
using Bit.Core.Repositories;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core.Settings; using Bit.Core.Settings;
using Bit.Core.Tools.Authorization;
using Bit.Core.Vault.Models.Data; using Bit.Core.Vault.Models.Data;
using Bit.Core.Vault.Queries;
using Bit.Core.Vault.Repositories;
using Bit.Core.Vault.Services; using Bit.Core.Vault.Services;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -21,24 +28,44 @@ public class OrganizationExportController : Controller
private readonly ICollectionService _collectionService; private readonly ICollectionService _collectionService;
private readonly ICipherService _cipherService; private readonly ICipherService _cipherService;
private readonly GlobalSettings _globalSettings; private readonly GlobalSettings _globalSettings;
private readonly IFeatureService _featureService;
private readonly IAuthorizationService _authorizationService;
private readonly IOrganizationCiphersQuery _organizationCiphersQuery;
private readonly ICipherRepository _cipherRepository;
private readonly ICollectionRepository _collectionRepository;
public OrganizationExportController( public OrganizationExportController(
ICurrentContext currentContext, ICurrentContext currentContext,
ICipherService cipherService, ICipherService cipherService,
ICollectionService collectionService, ICollectionService collectionService,
IUserService userService, IUserService userService,
GlobalSettings globalSettings) GlobalSettings globalSettings,
IFeatureService featureService,
IAuthorizationService authorizationService,
IOrganizationCiphersQuery organizationCiphersQuery,
ICipherRepository cipherRepository,
ICollectionRepository collectionRepository)
{ {
_currentContext = currentContext; _currentContext = currentContext;
_cipherService = cipherService; _cipherService = cipherService;
_collectionService = collectionService; _collectionService = collectionService;
_userService = userService; _userService = userService;
_globalSettings = globalSettings; _globalSettings = globalSettings;
_featureService = featureService;
_authorizationService = authorizationService;
_organizationCiphersQuery = organizationCiphersQuery;
_cipherRepository = cipherRepository;
_collectionRepository = collectionRepository;
} }
[HttpGet("export")] [HttpGet("export")]
public async Task<IActionResult> Export(Guid organizationId) public async Task<IActionResult> Export(Guid organizationId)
{ {
if (_featureService.IsEnabled(FeatureFlagKeys.PM11360RemoveProviderExportPermission))
{
return await Export_vNext(organizationId);
}
var userId = _userService.GetProperUserId(User).Value; var userId = _userService.GetProperUserId(User).Value;
IEnumerable<Collection> orgCollections = await _collectionService.GetOrganizationCollectionsAsync(organizationId); IEnumerable<Collection> orgCollections = await _collectionService.GetOrganizationCollectionsAsync(organizationId);
@ -65,6 +92,37 @@ public class OrganizationExportController : Controller
return Ok(organizationExportListResponseModel); return Ok(organizationExportListResponseModel);
} }
private async Task<IActionResult> Export_vNext(Guid organizationId)
{
var canExportAll = await _authorizationService.AuthorizeAsync(User, new OrganizationScope(organizationId),
VaultExportOperations.ExportWholeVault);
if (canExportAll.Succeeded)
{
var allOrganizationCiphers = await _organizationCiphersQuery.GetAllOrganizationCiphers(organizationId);
var allCollections = await _collectionRepository.GetManyByOrganizationIdAsync(organizationId);
return Ok(new OrganizationExportResponseModel(allOrganizationCiphers, allCollections, _globalSettings));
}
var canExportManaged = await _authorizationService.AuthorizeAsync(User, new OrganizationScope(organizationId),
VaultExportOperations.ExportManagedCollections);
if (canExportManaged.Succeeded)
{
var userId = _userService.GetProperUserId(User)!.Value;
var allCollections = await _collectionRepository.GetManyByUserIdAsync(userId);
var managedCollections = allCollections.Where(c => c.OrganizationId == organizationId && c.Manage).ToList();
var managedCollectionIds = managedCollections.Select(c => c.Id).ToHashSet();
var allOrganizationCiphers = await _organizationCiphersQuery.GetAllOrganizationCiphers(organizationId);
var managedCiphers = allOrganizationCiphers.Where(c => c.CollectionIds.Intersect(managedCollectionIds).Any());
return Ok(new OrganizationExportResponseModel(managedCiphers, managedCollections, _globalSettings));
}
// Unauthorized
throw new NotFoundException();
}
private ListResponseModel<CollectionResponseModel> GetOrganizationCollectionsResponse(IEnumerable<Collection> orgCollections) private ListResponseModel<CollectionResponseModel> GetOrganizationCollectionsResponse(IEnumerable<Collection> orgCollections)
{ {
var collections = orgCollections.Select(c => new CollectionResponseModel(c)); var collections = orgCollections.Select(c => new CollectionResponseModel(c));

View File

@ -1,6 +1,9 @@
using Bit.Api.Models.Response; using Bit.Api.Models.Response;
using Bit.Api.Vault.Models.Response; using Bit.Api.Vault.Models.Response;
using Bit.Core.Entities;
using Bit.Core.Models.Api; using Bit.Core.Models.Api;
using Bit.Core.Settings;
using Bit.Core.Vault.Models.Data;
namespace Bit.Api.Tools.Models.Response; namespace Bit.Api.Tools.Models.Response;
@ -10,6 +13,13 @@ public class OrganizationExportResponseModel : ResponseModel
{ {
} }
public OrganizationExportResponseModel(IEnumerable<CipherOrganizationDetailsWithCollections> ciphers,
IEnumerable<Collection> collections, GlobalSettings globalSettings) : this()
{
Ciphers = ciphers.Select(c => new CipherMiniDetailsResponseModel(c, globalSettings));
Collections = collections.Select(c => new CollectionResponseModel(c));
}
public IEnumerable<CollectionResponseModel> Collections { get; set; } public IEnumerable<CollectionResponseModel> Collections { get; set; }
public IEnumerable<CipherMiniDetailsResponseModel> Ciphers { get; set; } public IEnumerable<CipherMiniDetailsResponseModel> Ciphers { get; set; }

View File

@ -166,5 +166,12 @@ public class CipherMiniDetailsResponseModel : CipherMiniResponseModel
CollectionIds = cipher.CollectionIds ?? new List<Guid>(); CollectionIds = cipher.CollectionIds ?? new List<Guid>();
} }
public CipherMiniDetailsResponseModel(CipherOrganizationDetailsWithCollections cipher,
GlobalSettings globalSettings, string obj = "cipherMiniDetails")
: base(cipher, globalSettings, cipher.OrganizationUseTotp, obj)
{
CollectionIds = cipher.CollectionIds ?? new List<Guid>();
}
public IEnumerable<Guid> CollectionIds { get; set; } public IEnumerable<Guid> CollectionIds { get; set; }
} }

View File

@ -154,6 +154,7 @@ public static class FeatureFlagKeys
public const string NewDeviceVerificationPermanentDismiss = "new-device-permanent-dismiss"; public const string NewDeviceVerificationPermanentDismiss = "new-device-permanent-dismiss";
public const string SecurityTasks = "security-tasks"; public const string SecurityTasks = "security-tasks";
public const string PM14401_ScaleMSPOnClientOrganizationUpdate = "PM-14401-scale-msp-on-client-organization-update"; public const string PM14401_ScaleMSPOnClientOrganizationUpdate = "PM-14401-scale-msp-on-client-organization-update";
public const string PM11360RemoveProviderExportPermission = "pm-11360-remove-provider-export-permission";
public static List<string> GetAllKeys() public static List<string> GetAllKeys()
{ {