1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-01 08:02:49 -05:00

[PM-5518] Sql-backed IDistributedCache (#3791)

* Sql-backed IDistributedCache

* sqlserver cache table

* remove unused using

* setup EF entity

* cache indexes

* add back cipher

* revert SetupEntityFramework change

* ef cache

* EntityFrameworkCache

* IServiceScopeFactory for db context

* implement EntityFrameworkCache

* move to _serviceScopeFactory

* move to config file

* ef migrations

* fixes

* datetime and error codes

* revert migrations

* migrations

* format

* static and namespace fix

* use time provider

* Move SQL migration and remove EF one for the moment

* Add clean migration of just the new table

* Formatting

* Test Custom `IDistributedCache` Implementation

* Add Back Logging

* Remove Double Logging

* Skip Test When Not EntityFrameworkCache

* Format

---------

Co-authored-by: Matt Bishop <mbishop@bitwarden.com>
Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com>
This commit is contained in:
Kyle Spearrin
2024-07-03 12:48:23 -04:00
committed by GitHub
parent b8f71271eb
commit 0d3a7b3dd5
21 changed files with 8748 additions and 41 deletions

View File

@ -69,41 +69,7 @@ public static class ServiceCollectionExtensions
{
public static SupportedDatabaseProviders AddDatabaseRepositories(this IServiceCollection services, GlobalSettings globalSettings)
{
var selectedDatabaseProvider = globalSettings.DatabaseProvider;
var provider = SupportedDatabaseProviders.SqlServer;
var connectionString = string.Empty;
if (!string.IsNullOrWhiteSpace(selectedDatabaseProvider))
{
switch (selectedDatabaseProvider.ToLowerInvariant())
{
case "postgres":
case "postgresql":
provider = SupportedDatabaseProviders.Postgres;
connectionString = globalSettings.PostgreSql.ConnectionString;
break;
case "mysql":
case "mariadb":
provider = SupportedDatabaseProviders.MySql;
connectionString = globalSettings.MySql.ConnectionString;
break;
case "sqlite":
provider = SupportedDatabaseProviders.Sqlite;
connectionString = globalSettings.Sqlite.ConnectionString;
break;
case "sqlserver":
connectionString = globalSettings.SqlServer.ConnectionString;
break;
default:
break;
}
}
else
{
// Default to attempting to use SqlServer connection string if globalSettings.DatabaseProvider has no value.
connectionString = globalSettings.SqlServer.ConnectionString;
}
var (provider, connectionString) = GetDatabaseProvider(globalSettings);
services.SetupEntityFramework(connectionString, provider);
if (provider != SupportedDatabaseProviders.SqlServer)
@ -730,7 +696,20 @@ public static class ServiceCollectionExtensions
}
else
{
services.AddDistributedMemoryCache();
var (databaseProvider, databaseConnectionString) = GetDatabaseProvider(globalSettings);
if (databaseProvider == SupportedDatabaseProviders.SqlServer)
{
services.AddDistributedSqlServerCache(o =>
{
o.ConnectionString = databaseConnectionString;
o.SchemaName = "dbo";
o.TableName = "Cache";
});
}
else
{
services.AddSingleton<IDistributedCache, EntityFrameworkCache>();
}
}
if (!string.IsNullOrEmpty(globalSettings.DistributedCache?.Cosmos?.ConnectionString))
@ -746,7 +725,7 @@ public static class ServiceCollectionExtensions
}
else
{
services.AddKeyedSingleton<IDistributedCache, MemoryDistributedCache>("persistent");
services.AddKeyedSingleton("persistent", (s, _) => s.GetRequiredService<IDistributedCache>());
}
}
@ -762,4 +741,45 @@ public static class ServiceCollectionExtensions
return services;
}
private static (SupportedDatabaseProviders provider, string connectionString)
GetDatabaseProvider(GlobalSettings globalSettings)
{
var selectedDatabaseProvider = globalSettings.DatabaseProvider;
var provider = SupportedDatabaseProviders.SqlServer;
var connectionString = string.Empty;
if (!string.IsNullOrWhiteSpace(selectedDatabaseProvider))
{
switch (selectedDatabaseProvider.ToLowerInvariant())
{
case "postgres":
case "postgresql":
provider = SupportedDatabaseProviders.Postgres;
connectionString = globalSettings.PostgreSql.ConnectionString;
break;
case "mysql":
case "mariadb":
provider = SupportedDatabaseProviders.MySql;
connectionString = globalSettings.MySql.ConnectionString;
break;
case "sqlite":
provider = SupportedDatabaseProviders.Sqlite;
connectionString = globalSettings.Sqlite.ConnectionString;
break;
case "sqlserver":
connectionString = globalSettings.SqlServer.ConnectionString;
break;
default:
break;
}
}
else
{
// Default to attempting to use SqlServer connection string if globalSettings.DatabaseProvider has no value.
connectionString = globalSettings.SqlServer.ConnectionString;
}
return (provider, connectionString);
}
}