1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-02 16:42:50 -05:00

SM-365: Add Export & Import Functionality for SM (#2591)

* SM-365: Add Export endpoint

* SM-365: Add SM Import/Export support

* SM-365: Fix DI and add temp NoAccessCheck

* SM-365: Add access checks to import / export

* SM-365: dotnet format

* SM-365: Fix import bugs

* SM-365: Fix import bug with EF & refactor based on PR comments

* SM-365: Update access permissions in export

* SM-365: Address PR comments

* SM-365: Refactor for readability and PR comments
This commit is contained in:
Colton Hurst
2023-02-14 09:24:31 -05:00
committed by GitHub
parent 109d915d9e
commit 5836c87bb4
12 changed files with 453 additions and 1 deletions

View File

@ -0,0 +1,101 @@
using Bit.Core.SecretsManager.Commands.Porting;
using Bit.Core.SecretsManager.Commands.Porting.Interfaces;
using Bit.Core.SecretsManager.Entities;
using Bit.Core.SecretsManager.Repositories;
namespace Bit.Commercial.Core.SecretsManager.Commands.Porting;
public class ImportCommand : IImportCommand
{
private readonly IProjectRepository _projectRepository;
private readonly ISecretRepository _secretRepository;
public ImportCommand(IProjectRepository projectRepository, ISecretRepository secretRepository)
{
_projectRepository = projectRepository;
_secretRepository = secretRepository;
}
public async Task ImportAsync(Guid organizationId, SMImport import)
{
var importedProjects = new List<Guid>();
var importedSecrets = new List<Guid>();
try
{
import = AssignNewIds(import);
if (import.Projects.Any())
{
importedProjects = (await _projectRepository.ImportAsync(import.Projects.Select(p => new Project
{
Id = p.Id,
OrganizationId = organizationId,
Name = p.Name,
}))).Select(p => p.Id).ToList();
}
if (import.Secrets != null && import.Secrets.Any())
{
importedSecrets = (await _secretRepository.ImportAsync(import.Secrets.Select(s => new Secret
{
Id = s.Id,
OrganizationId = organizationId,
Key = s.Key,
Value = s.Value,
Note = s.Note,
Projects = s.ProjectIds?.Select(id => new Project { Id = id }).ToList(),
}))).Select(s => s.Id).ToList();
}
}
catch (Exception)
{
if (importedProjects.Any())
{
await _projectRepository.DeleteManyByIdAsync(importedProjects);
}
if (importedSecrets.Any())
{
await _secretRepository.HardDeleteManyByIdAsync(importedSecrets);
}
throw new Exception("Error attempting import");
}
}
public SMImport AssignNewIds(SMImport import)
{
var projects = new Dictionary<Guid, SMImport.InnerProject>();
var secrets = new List<SMImport.InnerSecret>();
if (import.Projects != null && import.Projects.Any())
{
projects = import.Projects.ToDictionary(
p => p.Id,
p => new SMImport.InnerProject { Id = Guid.NewGuid(), Name = p.Name }
);
}
if (import.Secrets != null && import.Secrets.Any())
{
foreach (var secret in import.Secrets)
{
secrets.Add(new SMImport.InnerSecret
{
Id = Guid.NewGuid(),
Key = secret.Key,
Value = secret.Value,
Note = secret.Note,
ProjectIds = secret.ProjectIds?.Select(id => projects[id].Id),
});
}
}
return new SMImport
{
Projects = projects.Values,
Secrets = secrets,
};
}
}

View File

@ -1,10 +1,12 @@
using Bit.Commercial.Core.SecretsManager.Commands.AccessPolicies;
using Bit.Commercial.Core.SecretsManager.Commands.AccessTokens;
using Bit.Commercial.Core.SecretsManager.Commands.Porting;
using Bit.Commercial.Core.SecretsManager.Commands.Projects;
using Bit.Commercial.Core.SecretsManager.Commands.Secrets;
using Bit.Commercial.Core.SecretsManager.Commands.ServiceAccounts;
using Bit.Core.SecretsManager.Commands.AccessPolicies.Interfaces;
using Bit.Core.SecretsManager.Commands.AccessTokens.Interfaces;
using Bit.Core.SecretsManager.Commands.Porting.Interfaces;
using Bit.Core.SecretsManager.Commands.Projects.Interfaces;
using Bit.Core.SecretsManager.Commands.Secrets.Interfaces;
using Bit.Core.SecretsManager.Commands.ServiceAccounts.Interfaces;
@ -28,5 +30,6 @@ public static class SecretsManagerCollectionExtensions
services.AddScoped<ICreateAccessPoliciesCommand, CreateAccessPoliciesCommand>();
services.AddScoped<IUpdateAccessPolicyCommand, UpdateAccessPolicyCommand>();
services.AddScoped<IDeleteAccessPolicyCommand, DeleteAccessPolicyCommand>();
services.AddScoped<IImportCommand, ImportCommand>();
}
}