1
0
mirror of https://github.com/bitwarden/server.git synced 2025-01-05 19:17:36 +01:00
bitwarden-server/perf/MicroBenchmarks/Identity/IdentityServer/RedisPersistedGrantStoreTests.cs
Kyle Spearrin a6db79f613
[PM-5645] Cosmos DB Grant Storage (#3634)
* table storage grants

* simple shard on storage accounts

* use is not

* cosmos grant repo

* remove single storage connection string

* some fixes to dapper grant repo

* pattern matching

* add fallback to base PersistedGrantStore

* service collection extension cleanup

* cleanup

* remove unused Id

* empty string rowkey

* fix sharding method logic

* ttl for cosmos

* make ttl an int

* fixes to cosmos implementation

* fix partition key values

* catch notfound exceptions

* indenting

* update grantitem with custom serialization

* use new transform helpers

* grantloader perf test tool

* ref

* remove grant loader project

* remove table storage implementation

* remove table storage stuff

* all redis fallback to build to null

* revert sln file change

* EOF new line

* remove trailing comma

* lint fixes

* add grant to names

* move cosmos serilaizer to utils

* add some .net 8 keyed service comments

* EnableContentResponseOnWrite

* Fix type in EF grant repository
2024-01-10 12:59:16 +00:00

111 lines
7.7 KiB
C#

using BenchmarkDotNet.Attributes;
using Bit.Identity.IdentityServer;
using Bit.Infrastructure.Dapper.Auth.Repositories;
using Duende.IdentityServer.Models;
using Duende.IdentityServer.Stores;
using Microsoft.Extensions.Logging.Abstractions;
using StackExchange.Redis;
namespace Bit.MicroBenchmarks.Identity.IdentityServer;
[MemoryDiagnoser]
public class RedisPersistedGrantStoreTests
{
const string SQL = nameof(SQL);
const string Redis = nameof(Redis);
const string Cosmos = nameof(Cosmos);
private readonly IPersistedGrantStore _redisGrantStore;
private readonly IPersistedGrantStore _sqlGrantStore;
private readonly IPersistedGrantStore _cosmosGrantStore;
private readonly PersistedGrant _updateGrant;
private IPersistedGrantStore _grantStore = null!;
// 1) "ConsumedTime"
// 2) ""
// 3) "Description"
// 4) ""
// 5) "SubjectId"
// 6) "97f31e32-6e44-407f-b8ba-b04c00f51b41"
// 7) "CreationTime"
// 8) "638350407400000000"
// 9) "Data"
// 10) "{\"CreationTime\":\"2023-11-08T11:45:40Z\",\"Lifetime\":2592001,\"ConsumedTime\":null,\"AccessToken\":{\"AllowedSigningAlgorithms\":[],\"Confirmation\":null,\"Audiences\":[],\"Issuer\":\"http://localhost\",\"CreationTime\":\"2023-11-08T11:45:40Z\",\"Lifetime\":3600,\"Type\":\"access_token\",\"ClientId\":\"web\",\"AccessTokenType\":0,\"Description\":null,\"Claims\":[{\"Type\":\"client_id\",\"Value\":\"web\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"scope\",\"Value\":\"api\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"scope\",\"Value\":\"offline_access\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"sub\",\"Value\":\"97f31e32-6e44-407f-b8ba-b04c00f51b41\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"auth_time\",\"Value\":\"1699443940\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#integer64\"},{\"Type\":\"idp\",\"Value\":\"bitwarden\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"amr\",\"Value\":\"Application\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"premium\",\"Value\":\"false\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#boolean\"},{\"Type\":\"email\",\"Value\":\"jbaur+test@bitwarden.com\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"email_verified\",\"Value\":\"false\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#boolean\"},{\"Type\":\"sstamp\",\"Value\":\"a4f2e0f3-e9f8-4014-b94e-b761d446a34b\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"name\",\"Value\":\"Justin Test\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"orgowner\",\"Value\":\"8ff8fefb-b035-436b-a25c-b04c00e30351\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"accesssecretsmanager\",\"Value\":\"8ff8fefb-b035-436b-a25c-b04c00e30351\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"device\",\"Value\":\"64b49c58-7768-4c30-8396-f851176daca6\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"jti\",\"Value\":\"CE008210A8276DAB966D9C2607533E0C\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"iat\",\"Value\":\"1699443940\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#integer64\"}],\"Version\":4},\"Version\":4}"
// 11) "Type"
// 12) "refresh_token"
// 13) "SessionId"
// 14) ""
// 15) "ClientId"
// 16) "web"
public RedisPersistedGrantStoreTests()
{
_redisGrantStore = new RedisPersistedGrantStore(
ConnectionMultiplexer.Connect("localhost"),
NullLogger<RedisPersistedGrantStore>.Instance,
new InMemoryPersistedGrantStore()
);
var sqlConnectionString = "YOUR CONNECTION STRING HERE";
_sqlGrantStore = new PersistedGrantStore(
new GrantRepository(
sqlConnectionString,
sqlConnectionString
),
g => new Bit.Core.Auth.Entities.Grant(g)
);
var cosmosConnectionString = "YOUR CONNECTION STRING HERE";
_cosmosGrantStore = new PersistedGrantStore(
new Bit.Core.Auth.Repositories.Cosmos.GrantRepository(cosmosConnectionString),
g => new Bit.Core.Auth.Models.Data.GrantItem(g)
);
var creationTime = new DateTime(638350407400000000, DateTimeKind.Utc);
_updateGrant = new PersistedGrant
{
Key = "i11JLqd7PE1yQltB2o5tRpfbMkpDPr+3w0Lc2Hx7kfE=",
ConsumedTime = null,
Description = null,
SubjectId = "97f31e32-6e44-407f-b8ba-b04c00f51b41",
CreationTime = creationTime,
Data = "{\"CreationTime\":\"2023-11-08T11:45:40Z\",\"Lifetime\":2592001,\"ConsumedTime\":null,\"AccessToken\":{\"AllowedSigningAlgorithms\":[],\"Confirmation\":null,\"Audiences\":[],\"Issuer\":\"http://localhost\",\"CreationTime\":\"2023-11-08T11:45:40Z\",\"Lifetime\":3600,\"Type\":\"access_token\",\"ClientId\":\"web\",\"AccessTokenType\":0,\"Description\":null,\"Claims\":[{\"Type\":\"client_id\",\"Value\":\"web\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"scope\",\"Value\":\"api\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"scope\",\"Value\":\"offline_access\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"sub\",\"Value\":\"97f31e32-6e44-407f-b8ba-b04c00f51b41\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"auth_time\",\"Value\":\"1699443940\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#integer64\"},{\"Type\":\"idp\",\"Value\":\"bitwarden\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"amr\",\"Value\":\"Application\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"premium\",\"Value\":\"false\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#boolean\"},{\"Type\":\"email\",\"Value\":\"jbaur+test@bitwarden.com\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"email_verified\",\"Value\":\"false\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#boolean\"},{\"Type\":\"sstamp\",\"Value\":\"a4f2e0f3-e9f8-4014-b94e-b761d446a34b\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"name\",\"Value\":\"Justin Test\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"orgowner\",\"Value\":\"8ff8fefb-b035-436b-a25c-b04c00e30351\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"accesssecretsmanager\",\"Value\":\"8ff8fefb-b035-436b-a25c-b04c00e30351\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"device\",\"Value\":\"64b49c58-7768-4c30-8396-f851176daca6\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"jti\",\"Value\":\"CE008210A8276DAB966D9C2607533E0C\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#string\"},{\"Type\":\"iat\",\"Value\":\"1699443940\",\"ValueType\":\"http://www.w3.org/2001/XMLSchema#integer64\"}],\"Version\":4},\"Version\":4}",
Type = "refresh_token",
SessionId = null,
ClientId = "web",
Expiration = creationTime.AddHours(1),
};
}
[Params(Redis, SQL, Cosmos)]
public string StoreType { get; set; } = null!;
[GlobalSetup]
public void Setup()
{
if (StoreType == Redis)
{
_grantStore = _redisGrantStore;
}
else if (StoreType == SQL)
{
_grantStore = _sqlGrantStore;
}
else if (StoreType == Cosmos)
{
_grantStore = _cosmosGrantStore;
}
else
{
throw new InvalidProgramException();
}
}
[Benchmark]
public async Task StoreAsync()
{
await _grantStore.StoreAsync(_updateGrant);
}
}