mirror of
https://github.com/bitwarden/server.git
synced 2025-07-02 16:42:50 -05:00
[SM-394] Secrets Manager (#2164)
Long lived feature branch for Secrets Manager Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> Co-authored-by: cd-bitwarden <106776772+cd-bitwarden@users.noreply.github.com> Co-authored-by: CarleyDiaz-Bitwarden <103955722+CarleyDiaz-Bitwarden@users.noreply.github.com> Co-authored-by: Thomas Avery <tavery@bitwarden.com> Co-authored-by: Colton Hurst <colton@coltonhurst.com>
This commit is contained in:
@ -0,0 +1,99 @@
|
||||
using Bit.Infrastructure.EntityFramework.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Configurations;
|
||||
|
||||
public class AccessPolicyEntityTypeConfiguration : IEntityTypeConfiguration<AccessPolicy>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<AccessPolicy> builder)
|
||||
{
|
||||
builder
|
||||
.HasDiscriminator<string>("Discriminator")
|
||||
.HasValue<UserProjectAccessPolicy>("user_project")
|
||||
.HasValue<UserServiceAccountAccessPolicy>("user_service_account")
|
||||
.HasValue<GroupProjectAccessPolicy>("group_project")
|
||||
.HasValue<GroupServiceAccountAccessPolicy>("group_service_account")
|
||||
.HasValue<ServiceAccountProjectAccessPolicy>("service_account_project");
|
||||
|
||||
builder
|
||||
.Property(s => s.Id)
|
||||
.ValueGeneratedNever();
|
||||
|
||||
builder
|
||||
.HasKey(s => s.Id)
|
||||
.IsClustered();
|
||||
|
||||
builder.ToTable(nameof(AccessPolicy));
|
||||
}
|
||||
}
|
||||
|
||||
public class UserProjectAccessPolicyEntityTypeConfiguration : IEntityTypeConfiguration<UserProjectAccessPolicy>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<UserProjectAccessPolicy> builder)
|
||||
{
|
||||
builder
|
||||
.Property(e => e.OrganizationUserId)
|
||||
.HasColumnName(nameof(UserProjectAccessPolicy.OrganizationUserId));
|
||||
|
||||
builder
|
||||
.Property(e => e.GrantedProjectId)
|
||||
.HasColumnName(nameof(UserProjectAccessPolicy.GrantedProjectId));
|
||||
}
|
||||
}
|
||||
|
||||
public class UserServiceAccountAccessPolicyEntityTypeConfiguration : IEntityTypeConfiguration<UserServiceAccountAccessPolicy>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<UserServiceAccountAccessPolicy> builder)
|
||||
{
|
||||
builder
|
||||
.Property(e => e.OrganizationUserId)
|
||||
.HasColumnName(nameof(UserServiceAccountAccessPolicy.OrganizationUserId));
|
||||
|
||||
builder
|
||||
.Property(e => e.GrantedServiceAccountId)
|
||||
.HasColumnName(nameof(UserServiceAccountAccessPolicy.GrantedServiceAccountId));
|
||||
}
|
||||
}
|
||||
|
||||
public class GroupProjectAccessPolicyEntityTypeConfiguration : IEntityTypeConfiguration<GroupProjectAccessPolicy>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<GroupProjectAccessPolicy> builder)
|
||||
{
|
||||
builder
|
||||
.Property(e => e.GroupId)
|
||||
.HasColumnName(nameof(GroupProjectAccessPolicy.GroupId));
|
||||
|
||||
builder
|
||||
.Property(e => e.GrantedProjectId)
|
||||
.HasColumnName(nameof(GroupProjectAccessPolicy.GrantedProjectId));
|
||||
}
|
||||
}
|
||||
|
||||
public class GroupServiceAccountAccessPolicyEntityTypeConfiguration : IEntityTypeConfiguration<GroupServiceAccountAccessPolicy>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<GroupServiceAccountAccessPolicy> builder)
|
||||
{
|
||||
builder
|
||||
.Property(e => e.GroupId)
|
||||
.HasColumnName(nameof(GroupServiceAccountAccessPolicy.GroupId));
|
||||
|
||||
builder
|
||||
.Property(e => e.GrantedServiceAccountId)
|
||||
.HasColumnName(nameof(GroupServiceAccountAccessPolicy.GrantedServiceAccountId));
|
||||
}
|
||||
}
|
||||
|
||||
public class ServiceAccountProjectAccessPolicyEntityTypeConfiguration : IEntityTypeConfiguration<ServiceAccountProjectAccessPolicy>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ServiceAccountProjectAccessPolicy> builder)
|
||||
{
|
||||
builder
|
||||
.Property(e => e.ServiceAccountId)
|
||||
.HasColumnName(nameof(ServiceAccountProjectAccessPolicy.ServiceAccountId));
|
||||
|
||||
builder
|
||||
.Property(e => e.GrantedProjectId)
|
||||
.HasColumnName(nameof(ServiceAccountProjectAccessPolicy.GrantedProjectId));
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
using Bit.Infrastructure.EntityFramework.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Configurations;
|
||||
|
||||
public class ApiKeyEntityTypeConfiguration : IEntityTypeConfiguration<ApiKey>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ApiKey> builder)
|
||||
{
|
||||
builder
|
||||
.Property(s => s.Id)
|
||||
.ValueGeneratedNever();
|
||||
|
||||
builder
|
||||
.HasKey(s => s.Id)
|
||||
.IsClustered();
|
||||
|
||||
builder
|
||||
.HasIndex(s => s.ServiceAccountId)
|
||||
.IsClustered(false);
|
||||
|
||||
builder.ToTable(nameof(ApiKey));
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
using Bit.Infrastructure.EntityFramework.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Configurations;
|
||||
|
||||
public class ProjectEntityTypeConfiguration : IEntityTypeConfiguration<Project>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Project> builder)
|
||||
{
|
||||
builder
|
||||
.Property(s => s.Id)
|
||||
.ValueGeneratedNever();
|
||||
|
||||
builder
|
||||
.HasKey(s => s.Id)
|
||||
.IsClustered();
|
||||
|
||||
builder
|
||||
.HasIndex(s => s.DeletedDate)
|
||||
.IsClustered(false);
|
||||
|
||||
builder
|
||||
.HasIndex(s => s.OrganizationId)
|
||||
.IsClustered(false);
|
||||
|
||||
builder.ToTable(nameof(Project));
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
using Bit.Infrastructure.EntityFramework.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Configurations;
|
||||
|
||||
public class SecretEntityTypeConfiguration : IEntityTypeConfiguration<Secret>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Secret> builder)
|
||||
{
|
||||
builder
|
||||
.Property(s => s.Id)
|
||||
.ValueGeneratedNever();
|
||||
|
||||
builder
|
||||
.HasKey(s => s.Id)
|
||||
.IsClustered();
|
||||
|
||||
builder
|
||||
.HasIndex(s => s.DeletedDate)
|
||||
.IsClustered(false);
|
||||
|
||||
builder
|
||||
.HasIndex(s => s.OrganizationId)
|
||||
.IsClustered(false);
|
||||
|
||||
builder.ToTable(nameof(Secret));
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
using Bit.Infrastructure.EntityFramework.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
public class ServiceAccountEntityTypeConfiguration : IEntityTypeConfiguration<ServiceAccount>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ServiceAccount> builder)
|
||||
{
|
||||
builder
|
||||
.Property(s => s.Id)
|
||||
.ValueGeneratedNever();
|
||||
|
||||
builder
|
||||
.HasKey(s => s.Id)
|
||||
.IsClustered();
|
||||
|
||||
builder
|
||||
.HasIndex(s => s.OrganizationId)
|
||||
.IsClustered(false);
|
||||
|
||||
builder.ToTable(nameof(ServiceAccount));
|
||||
}
|
||||
}
|
19
src/Infrastructure.EntityFramework/EfExtensions.cs
Normal file
19
src/Infrastructure.EntityFramework/EfExtensions.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework;
|
||||
|
||||
public static class EfExtensions
|
||||
{
|
||||
public static T AttachToOrGet<T>(this DbContext context, Func<T, bool> predicate, Func<T> factory)
|
||||
where T : class, new()
|
||||
{
|
||||
var match = context.Set<T>().Local.FirstOrDefault(predicate);
|
||||
if (match == null)
|
||||
{
|
||||
match = factory();
|
||||
context.Attach(match);
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
}
|
@ -5,18 +5,18 @@ using LinqToDB.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework;
|
||||
|
||||
public static class EntityFrameworkServiceCollectionExtensions
|
||||
{
|
||||
public static void AddEFRepositories(this IServiceCollection services, bool selfHosted, string connectionString,
|
||||
SupportedDatabaseProviders provider)
|
||||
public static void SetupEntityFramework(this IServiceCollection services, string connectionString, SupportedDatabaseProviders provider)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(connectionString))
|
||||
{
|
||||
throw new Exception($"Database provider type {provider} was selected but no connection string was found.");
|
||||
}
|
||||
|
||||
// TODO: We should move away from using LINQ syntax for EF (TDL-48).
|
||||
LinqToDBForEFTools.Initialize();
|
||||
|
||||
services.AddAutoMapper(typeof(UserRepository));
|
||||
services.AddDbContext<DatabaseContext>(options =>
|
||||
{
|
||||
@ -35,7 +35,17 @@ public static class EntityFrameworkServiceCollectionExtensions
|
||||
{
|
||||
options.UseSqlite(connectionString, b => b.MigrationsAssembly("SqliteMigrations"));
|
||||
}
|
||||
else if (provider == SupportedDatabaseProviders.SqlServer)
|
||||
{
|
||||
options.UseSqlServer(connectionString);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void AddPasswordManagerEFRepositories(this IServiceCollection services, bool selfHosted)
|
||||
{
|
||||
services.AddSingleton<IApiKeyRepository, ApiKeyRepository>();
|
||||
services.AddSingleton<IAuthRequestRepository, AuthRequestRepository>();
|
||||
services.AddSingleton<ICipherRepository, CipherRepository>();
|
||||
services.AddSingleton<ICollectionCipherRepository, CollectionCipherRepository>();
|
||||
services.AddSingleton<ICollectionRepository, CollectionRepository>();
|
||||
@ -46,22 +56,21 @@ public static class EntityFrameworkServiceCollectionExtensions
|
||||
services.AddSingleton<IGroupRepository, GroupRepository>();
|
||||
services.AddSingleton<IInstallationRepository, InstallationRepository>();
|
||||
services.AddSingleton<IMaintenanceRepository, MaintenanceRepository>();
|
||||
services.AddSingleton<IOrganizationRepository, OrganizationRepository>();
|
||||
services.AddSingleton<IOrganizationApiKeyRepository, OrganizationApiKeyRepository>();
|
||||
services.AddSingleton<IOrganizationConnectionRepository, OrganizationConnectionRepository>();
|
||||
services.AddSingleton<IOrganizationRepository, OrganizationRepository>();
|
||||
services.AddSingleton<IOrganizationSponsorshipRepository, OrganizationSponsorshipRepository>();
|
||||
services.AddSingleton<IOrganizationUserRepository, OrganizationUserRepository>();
|
||||
services.AddSingleton<IPolicyRepository, PolicyRepository>();
|
||||
services.AddSingleton<IProviderOrganizationRepository, ProviderOrganizationRepository>();
|
||||
services.AddSingleton<IProviderRepository, ProviderRepository>();
|
||||
services.AddSingleton<IProviderUserRepository, ProviderUserRepository>();
|
||||
services.AddSingleton<ISendRepository, SendRepository>();
|
||||
services.AddSingleton<ISsoConfigRepository, SsoConfigRepository>();
|
||||
services.AddSingleton<ISsoUserRepository, SsoUserRepository>();
|
||||
services.AddSingleton<ITaxRateRepository, TaxRateRepository>();
|
||||
services.AddSingleton<ITransactionRepository, TransactionRepository>();
|
||||
services.AddSingleton<IUserRepository, UserRepository>();
|
||||
services.AddSingleton<IProviderRepository, ProviderRepository>();
|
||||
services.AddSingleton<IProviderUserRepository, ProviderUserRepository>();
|
||||
services.AddSingleton<IProviderOrganizationRepository, ProviderOrganizationRepository>();
|
||||
services.AddSingleton<IAuthRequestRepository, AuthRequestRepository>();
|
||||
|
||||
if (selfHosted)
|
||||
{
|
||||
|
@ -2,15 +2,15 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
|
||||
<PackageReference Include="linq2db.EntityFrameworkCore" Version="6.11.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.12" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.12" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.12" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.8" />
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.2" />
|
||||
<PackageReference Include="linq2db.EntityFrameworkCore" Version="6.11.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Core\Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
60
src/Infrastructure.EntityFramework/Models/AccessPolicy.cs
Normal file
60
src/Infrastructure.EntityFramework/Models/AccessPolicy.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using AutoMapper;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Models;
|
||||
|
||||
public class BaseAccessPolicy : Core.Entities.BaseAccessPolicy
|
||||
{
|
||||
public string Discriminator { get; set; }
|
||||
}
|
||||
|
||||
public class AccessPolicyMapperProfile : Profile
|
||||
{
|
||||
public AccessPolicyMapperProfile()
|
||||
{
|
||||
CreateMap<Core.Entities.AccessPolicy, AccessPolicy>().ReverseMap();
|
||||
}
|
||||
}
|
||||
|
||||
public class AccessPolicy : BaseAccessPolicy
|
||||
{
|
||||
}
|
||||
|
||||
public class UserProjectAccessPolicy : AccessPolicy
|
||||
{
|
||||
public Guid? OrganizationUserId { get; set; }
|
||||
public virtual OrganizationUser OrganizationUser { get; set; }
|
||||
public Guid? GrantedProjectId { get; set; }
|
||||
public virtual Project GrantedProject { get; set; }
|
||||
}
|
||||
|
||||
public class UserServiceAccountAccessPolicy : AccessPolicy
|
||||
{
|
||||
public Guid? OrganizationUserId { get; set; }
|
||||
public virtual OrganizationUser OrganizationUser { get; set; }
|
||||
public Guid? GrantedServiceAccountId { get; set; }
|
||||
public virtual ServiceAccount GrantedServiceAccount { get; set; }
|
||||
}
|
||||
|
||||
public class GroupProjectAccessPolicy : AccessPolicy
|
||||
{
|
||||
public Guid? GroupId { get; set; }
|
||||
public virtual Group Group { get; set; }
|
||||
public Guid? GrantedProjectId { get; set; }
|
||||
public virtual Project GrantedProject { get; set; }
|
||||
}
|
||||
|
||||
public class GroupServiceAccountAccessPolicy : AccessPolicy
|
||||
{
|
||||
public Guid? GroupId { get; set; }
|
||||
public virtual Group Group { get; set; }
|
||||
public Guid? GrantedServiceAccountId { get; set; }
|
||||
public virtual ServiceAccount GrantedServiceAccount { get; set; }
|
||||
}
|
||||
|
||||
public class ServiceAccountProjectAccessPolicy : AccessPolicy
|
||||
{
|
||||
public Guid? ServiceAccountId { get; set; }
|
||||
public virtual ServiceAccount ServiceAccount { get; set; }
|
||||
public Guid? GrantedProjectId { get; set; }
|
||||
public virtual Project GrantedProject { get; set; }
|
||||
}
|
16
src/Infrastructure.EntityFramework/Models/ApiKey.cs
Normal file
16
src/Infrastructure.EntityFramework/Models/ApiKey.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using AutoMapper;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Models;
|
||||
|
||||
public class ApiKey : Core.Entities.ApiKey
|
||||
{
|
||||
public virtual ServiceAccount ServiceAccount { get; set; }
|
||||
}
|
||||
|
||||
public class ApiKeyMapperProfile : Profile
|
||||
{
|
||||
public ApiKeyMapperProfile()
|
||||
{
|
||||
CreateMap<Core.Entities.ApiKey, ApiKey>().ReverseMap();
|
||||
}
|
||||
}
|
22
src/Infrastructure.EntityFramework/Models/Project.cs
Normal file
22
src/Infrastructure.EntityFramework/Models/Project.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using AutoMapper;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Models;
|
||||
|
||||
public class Project : Core.Entities.Project
|
||||
{
|
||||
public virtual new ICollection<Secret> Secrets { get; set; }
|
||||
public virtual Organization Organization { get; set; }
|
||||
public virtual ICollection<GroupProjectAccessPolicy> GroupAccessPolicies { get; set; }
|
||||
public virtual ICollection<UserProjectAccessPolicy> UserAccessPolicies { get; set; }
|
||||
public virtual ICollection<ServiceAccountProjectAccessPolicy> ServiceAccountAccessPolicies { get; set; }
|
||||
}
|
||||
|
||||
public class ProjectMapperProfile : Profile
|
||||
{
|
||||
public ProjectMapperProfile()
|
||||
{
|
||||
CreateMap<Core.Entities.Project, Project>()
|
||||
.PreserveReferences()
|
||||
.ReverseMap();
|
||||
}
|
||||
}
|
19
src/Infrastructure.EntityFramework/Models/Secret.cs
Normal file
19
src/Infrastructure.EntityFramework/Models/Secret.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using AutoMapper;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Models;
|
||||
|
||||
public class Secret : Core.Entities.Secret
|
||||
{
|
||||
public virtual new ICollection<Project> Projects { get; set; }
|
||||
public virtual Organization Organization { get; set; }
|
||||
}
|
||||
|
||||
public class SecretMapperProfile : Profile
|
||||
{
|
||||
public SecretMapperProfile()
|
||||
{
|
||||
CreateMap<Core.Entities.Secret, Secret>()
|
||||
.PreserveReferences()
|
||||
.ReverseMap();
|
||||
}
|
||||
}
|
16
src/Infrastructure.EntityFramework/Models/ServiceAccount.cs
Normal file
16
src/Infrastructure.EntityFramework/Models/ServiceAccount.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using AutoMapper;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Models;
|
||||
|
||||
public class ServiceAccount : Core.Entities.ServiceAccount
|
||||
{
|
||||
public virtual Organization Organization { get; set; }
|
||||
}
|
||||
|
||||
public class ServiceAccountMapperProfile : Profile
|
||||
{
|
||||
public ServiceAccountMapperProfile()
|
||||
{
|
||||
CreateMap<Core.Entities.ServiceAccount, ServiceAccount>().ReverseMap();
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
using AutoMapper;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Infrastructure.EntityFramework.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using CoreAccessPolicy = Bit.Core.Entities.AccessPolicy;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public class AccessPolicyRepository : IAccessPolicyRepository
|
||||
{
|
||||
public AccessPolicyRepository(IServiceScopeFactory serviceScopeFactory, IMapper mapper)
|
||||
{
|
||||
}
|
||||
|
||||
protected Func<DatabaseContext, DbSet<AccessPolicy>> GetDbSet { get; private set; }
|
||||
|
||||
public Task<CoreAccessPolicy> GetByIdAsync(Guid id) => throw new NotImplementedException();
|
||||
|
||||
public Task<CoreAccessPolicy> CreateAsync(CoreAccessPolicy obj) => throw new NotImplementedException();
|
||||
|
||||
public Task ReplaceAsync(CoreAccessPolicy obj) => throw new NotImplementedException();
|
||||
|
||||
public Task UpsertAsync(CoreAccessPolicy obj) => throw new NotImplementedException();
|
||||
|
||||
public Task DeleteAsync(CoreAccessPolicy obj) => throw new NotImplementedException();
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
using AutoMapper;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Infrastructure.EntityFramework.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Bit.Infrastructure.EntityFramework.Repositories;
|
||||
|
||||
public class ApiKeyRepository : Repository<Core.Entities.ApiKey, ApiKey, Guid>, IApiKeyRepository
|
||||
{
|
||||
public ApiKeyRepository(IServiceScopeFactory serviceScopeFactory, IMapper mapper)
|
||||
: base(serviceScopeFactory, mapper, (DatabaseContext context) => context.ApiKeys)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<ApiKeyDetails> GetDetailsByIdAsync(Guid id)
|
||||
{
|
||||
using var scope = ServiceScopeFactory.CreateScope();
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
var entity = await GetDbSet(dbContext)
|
||||
.Where(apiKey => apiKey.Id == id)
|
||||
.Include(apiKey => apiKey.ServiceAccount)
|
||||
.Select(apiKey => new ServiceAccountApiKeyDetails(apiKey, apiKey.ServiceAccount.OrganizationId))
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
return Mapper.Map<ServiceAccountApiKeyDetails>(entity);
|
||||
}
|
||||
|
||||
public async Task<ICollection<Core.Entities.ApiKey>> GetManyByServiceAccountIdAsync(Guid id)
|
||||
{
|
||||
using var scope = ServiceScopeFactory.CreateScope();
|
||||
var dbContext = GetDatabaseContext(scope);
|
||||
var apiKeys = await GetDbSet(dbContext).Where(e => e.ServiceAccountId == id).ToListAsync();
|
||||
|
||||
return Mapper.Map<List<Core.Entities.ApiKey>>(apiKeys);
|
||||
}
|
||||
}
|
@ -12,6 +12,8 @@ public class DatabaseContext : DbContext
|
||||
: base(options)
|
||||
{ }
|
||||
|
||||
public DbSet<AccessPolicy> AccessPolicies { get; set; }
|
||||
public DbSet<ApiKey> ApiKeys { get; set; }
|
||||
public DbSet<Cipher> Ciphers { get; set; }
|
||||
public DbSet<Collection> Collections { get; set; }
|
||||
public DbSet<CollectionCipher> CollectionCiphers { get; set; }
|
||||
@ -32,6 +34,9 @@ public class DatabaseContext : DbContext
|
||||
public DbSet<OrganizationUser> OrganizationUsers { get; set; }
|
||||
public DbSet<Policy> Policies { get; set; }
|
||||
public DbSet<Provider> Providers { get; set; }
|
||||
public DbSet<Secret> Secret { get; set; }
|
||||
public DbSet<ServiceAccount> ServiceAccount { get; set; }
|
||||
public DbSet<Project> Project { get; set; }
|
||||
public DbSet<ProviderUser> ProviderUsers { get; set; }
|
||||
public DbSet<ProviderOrganization> ProviderOrganizations { get; set; }
|
||||
public DbSet<Send> Sends { get; set; }
|
||||
@ -44,6 +49,13 @@ public class DatabaseContext : DbContext
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
// Scans and loads all configurations implementing the `IEntityTypeConfiguration` from the
|
||||
// `Infrastructure.EntityFramework` Module. Note to get the assembly we can use a random class
|
||||
// from this module.
|
||||
builder.ApplyConfigurationsFromAssembly(typeof(DatabaseContext).Assembly);
|
||||
|
||||
// Going forward use `IEntityTypeConfiguration` in the Configurations folder for managing
|
||||
// Entity Framework code first database configurations.
|
||||
var eCipher = builder.Entity<Cipher>();
|
||||
var eCollection = builder.Entity<Collection>();
|
||||
var eCollectionCipher = builder.Entity<CollectionCipher>();
|
||||
@ -101,7 +113,6 @@ public class DatabaseContext : DbContext
|
||||
eGrant.HasKey(x => x.Key);
|
||||
eGroupUser.HasKey(gu => new { gu.GroupId, gu.OrganizationUserId });
|
||||
|
||||
|
||||
if (Database.IsNpgsql())
|
||||
{
|
||||
// the postgres provider doesn't currently support database level non-deterministic collations.
|
||||
|
@ -42,6 +42,16 @@
|
||||
"SQLitePCLRaw.bundle_e_sqlite3": "2.1.2"
|
||||
}
|
||||
},
|
||||
"Microsoft.EntityFrameworkCore.SqlServer": {
|
||||
"type": "Direct",
|
||||
"requested": "[6.0.12, )",
|
||||
"resolved": "6.0.12",
|
||||
"contentHash": "bdKnSz1w+WZz9QYWhs3wwGuMn4YssjdR+HOBpzChQ6C3+dblq4Pammm5fzugcPOhTgCiWftOT2jPOT5hEy4bYg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.SqlClient": "2.1.4",
|
||||
"Microsoft.EntityFrameworkCore.Relational": "6.0.12"
|
||||
}
|
||||
},
|
||||
"Npgsql.EntityFrameworkCore.PostgreSQL": {
|
||||
"type": "Direct",
|
||||
"requested": "[6.0.8, )",
|
||||
|
Reference in New Issue
Block a user