From 656eadd17d8d197bfe6309ea8b45f8a5ae24167f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rui=20Tom=C3=A9?= <108268980+r-tome@users.noreply.github.com> Date: Mon, 7 Nov 2022 12:01:45 +0000 Subject: [PATCH] [EC-584] Removed ListResponseModel from OrganizationExportResponseModel (#2316) * [EC-584] Removed ListResponseModel from OrganizationExportResponseModel properties * [EC-584] Added backwards compatibility for client version 2022.9.0 * [EC-584] Added property 'ClientVersion' to ICurrentContext * [EC-584] Added backwards compatibility for version 2022.10.0 * [EC-584] Change ICurrentContext.ClientVersion from string to Version * [EC-584] Remove check for versions before 2022.9.0 because they do not use this endpoint (cherry picked from commit 8a6f780d55cf0768e1869f1f097452328791983e) --- .../OrganizationExportController.cs | 26 +++++++++++++++---- .../OrganizationExportResponseModel.cs | 16 +++++++++--- src/Core/Context/CurrentContext.cs | 6 +++++ src/Core/Context/ICurrentContext.cs | 1 + 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/Api/Controllers/OrganizationExportController.cs b/src/Api/Controllers/OrganizationExportController.cs index f2a2265f9d..9c075b18f1 100644 --- a/src/Api/Controllers/OrganizationExportController.cs +++ b/src/Api/Controllers/OrganizationExportController.cs @@ -1,4 +1,5 @@ using Bit.Api.Models.Response; +using Bit.Core.Context; using Bit.Core.Entities; using Bit.Core.Services; using Bit.Core.Settings; @@ -12,17 +13,20 @@ namespace Bit.Api.Controllers; [Authorize("Application")] public class OrganizationExportController : Controller { + private readonly ICurrentContext _currentContext; private readonly IUserService _userService; private readonly ICollectionService _collectionService; private readonly ICipherService _cipherService; private readonly GlobalSettings _globalSettings; public OrganizationExportController( + ICurrentContext currentContext, ICipherService cipherService, ICollectionService collectionService, IUserService userService, GlobalSettings globalSettings) { + _currentContext = currentContext; _cipherService = cipherService; _collectionService = collectionService; _userService = userService; @@ -30,20 +34,32 @@ public class OrganizationExportController : Controller } [HttpGet("export")] - public async Task Export(Guid organizationId) + public async Task Export(Guid organizationId) { var userId = _userService.GetProperUserId(User).Value; IEnumerable orgCollections = await _collectionService.GetOrganizationCollections(organizationId); (IEnumerable orgCiphers, Dictionary> collectionCiphersGroupDict) = await _cipherService.GetOrganizationCiphers(userId, organizationId); - var result = new OrganizationExportResponseModel + // Backward compatibility with versions before 2022.11.0 that use ListResponseModel + if (_currentContext.ClientVersion < new Version("2022.11.0")) { - Collections = GetOrganizationCollectionsResponse(orgCollections), - Ciphers = GetOrganizationCiphersResponse(orgCiphers, collectionCiphersGroupDict) + var organizationExportListResponseModel = new OrganizationExportListResponseModel + { + Collections = GetOrganizationCollectionsResponse(orgCollections), + Ciphers = GetOrganizationCiphersResponse(orgCiphers, collectionCiphersGroupDict) + }; + + return Ok(organizationExportListResponseModel); + } + + var organizationExportResponseModel = new OrganizationExportResponseModel + { + Collections = orgCollections.Select(c => new CollectionResponseModel(c)), + Ciphers = orgCiphers.Select(c => new CipherMiniDetailsResponseModel(c, _globalSettings, collectionCiphersGroupDict, c.OrganizationUseTotp)) }; - return result; + return Ok(organizationExportResponseModel); } private ListResponseModel GetOrganizationCollectionsResponse(IEnumerable orgCollections) diff --git a/src/Api/Models/Response/OrganizationExportResponseModel.cs b/src/Api/Models/Response/OrganizationExportResponseModel.cs index a7533c918d..53720b4b3a 100644 --- a/src/Api/Models/Response/OrganizationExportResponseModel.cs +++ b/src/Api/Models/Response/OrganizationExportResponseModel.cs @@ -1,11 +1,21 @@ -namespace Bit.Api.Models.Response; +using Bit.Core.Models.Api; -public class OrganizationExportResponseModel +namespace Bit.Api.Models.Response; + +public class OrganizationExportResponseModel : ResponseModel { - public OrganizationExportResponseModel() + public OrganizationExportResponseModel() : base("organizationExport") { } + public IEnumerable Collections { get; set; } + + public IEnumerable Ciphers { get; set; } +} + +[Obsolete("This version is for backwards compatibility for client version 2022.9.0")] +public class OrganizationExportListResponseModel +{ public ListResponseModel Collections { get; set; } public ListResponseModel Ciphers { get; set; } diff --git a/src/Core/Context/CurrentContext.cs b/src/Core/Context/CurrentContext.cs index d78340d700..8c4d40579b 100644 --- a/src/Core/Context/CurrentContext.cs +++ b/src/Core/Context/CurrentContext.cs @@ -32,6 +32,7 @@ public class CurrentContext : ICurrentContext public virtual bool MaybeBot { get; set; } public virtual int? BotScore { get; set; } public virtual string ClientId { get; set; } + public virtual Version ClientVersion { get; set; } public CurrentContext(IProviderUserRepository providerUserRepository) { @@ -80,6 +81,11 @@ public class CurrentContext : ICurrentContext { MaybeBot = httpContext.Request.Headers["X-Cf-Maybe-Bot"] == "1"; } + + if (httpContext.Request.Headers.ContainsKey("Bitwarden-Client-Version")) + { + ClientVersion = new Version(httpContext.Request.Headers["Bitwarden-Client-Version"]); + } } public async virtual Task BuildAsync(ClaimsPrincipal user, GlobalSettings globalSettings) diff --git a/src/Core/Context/ICurrentContext.cs b/src/Core/Context/ICurrentContext.cs index b53e43dfac..19917fe4ff 100644 --- a/src/Core/Context/ICurrentContext.cs +++ b/src/Core/Context/ICurrentContext.cs @@ -22,6 +22,7 @@ public interface ICurrentContext bool MaybeBot { get; set; } int? BotScore { get; set; } string ClientId { get; set; } + Version ClientVersion { get; set; } Task BuildAsync(HttpContext httpContext, GlobalSettings globalSettings); Task BuildAsync(ClaimsPrincipal user, GlobalSettings globalSettings);