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

Added redis caching libraries and implemented for user by id caching.

This commit is contained in:
Kyle Spearrin
2016-06-17 17:42:22 -04:00
parent df94150848
commit 1ff49cd5b3
9 changed files with 109 additions and 34 deletions

7
src/Core/Constants.cs Normal file
View File

@ -0,0 +1,7 @@
namespace Bit.Core
{
public static class Constants
{
public const string UserIdCacheKey = "User:Id_{0}";
}
}

View File

@ -1,4 +1,5 @@
using System;
using StackExchange.Redis.Extensions.Core.Configuration;
using System;
using System.Collections.Generic;
namespace Bit.Core
@ -11,6 +12,7 @@ namespace Bit.Core
public virtual SqlServerSettings SqlServer { get; set; } = new SqlServerSettings();
public virtual MailSettings Mail { get; set; } = new MailSettings();
public virtual LoggrSettings Loggr { get; set; } = new LoggrSettings();
public virtual CacheSettings Cache { get; set; } = new CacheSettings();
public class SqlServerSettings
{
@ -28,5 +30,11 @@ namespace Bit.Core
public string LogKey { get; set; }
public string ApiKey { get; set; }
}
public class CacheSettings
{
public string ConnectionString { get; set; }
public int Database { get; set; }
}
}
}

View File

@ -9,7 +9,6 @@ namespace Bit.Core.Repositories
Task CreateAsync(T obj);
Task ReplaceAsync(T obj);
Task UpsertAsync(T obj);
Task DeleteByIdAsync(TId id);
Task DeleteAsync(T obj);
}
}

View File

@ -7,15 +7,24 @@ using DataTableProxy;
using Bit.Core.Domains;
using System.Data;
using Dapper;
using StackExchange.Redis.Extensions.Core;
namespace Bit.Core.Repositories.SqlServer
{
public class CipherRepository : Repository<Cipher, Guid>, ICipherRepository
{
public CipherRepository(string connectionString)
: base(connectionString)
private readonly ICacheClient _cacheClient;
public CipherRepository(GlobalSettings globalSettings, ICacheClient cacheClient)
: this(globalSettings.SqlServer.ConnectionString, cacheClient)
{ }
public CipherRepository(string connectionString, ICacheClient cacheClient)
: base(connectionString)
{
_cacheClient = cacheClient;
}
public async Task<Cipher> GetByIdAsync(Guid id, Guid userId)
{
var cipher = await GetByIdAsync(id);
@ -57,7 +66,7 @@ namespace Bit.Core.Repositories.SqlServer
}
}
public async Task<Tuple<ICollection<Cipher>, ICollection<Guid>>>
public async Task<Tuple<ICollection<Cipher>, ICollection<Guid>>>
GetManySinceRevisionDateAndUserIdWithDeleteHistoryAsync(DateTime sinceRevisionDate, Guid userId)
{
using(var connection = new SqlConnection(ConnectionString))
@ -78,11 +87,11 @@ namespace Bit.Core.Repositories.SqlServer
}
}
public Task UpdateUserEmailPasswordAndCiphersAsync(User user, IEnumerable<Cipher> ciphers)
public async Task UpdateUserEmailPasswordAndCiphersAsync(User user, IEnumerable<Cipher> ciphers)
{
if(ciphers.Count() == 0)
{
return Task.FromResult(0);
return;
}
using(var connection = new SqlConnection(ConnectionString))
@ -167,7 +176,8 @@ namespace Bit.Core.Repositories.SqlServer
}
}
return Task.FromResult(0);
// Cleanup user cache
await _cacheClient.RemoveAllAsync(new string[] { string.Format(Constants.UserIdCacheKey, user.Id) });
}
public Task CreateAsync(IEnumerable<Cipher> ciphers)

View File

@ -75,17 +75,12 @@ namespace Bit.Core.Repositories.SqlServer
}
public virtual async Task DeleteAsync(T obj)
{
await DeleteByIdAsync(obj.Id);
}
public virtual async Task DeleteByIdAsync(TId id)
{
using(var connection = new SqlConnection(ConnectionString))
{
await connection.ExecuteAsync(
$"[{Schema}].[{Table}_DeleteById]",
new { Id = id },
new { Id = obj.Id },
commandType: CommandType.StoredProcedure);
}
}

View File

@ -5,15 +5,39 @@ using System.Linq;
using System.Threading.Tasks;
using Bit.Core.Domains;
using Dapper;
using StackExchange.Redis.Extensions.Core;
namespace Bit.Core.Repositories.SqlServer
{
public class UserRepository : Repository<User, Guid>, IUserRepository
{
public UserRepository(string connectionString)
: base(connectionString)
private readonly ICacheClient _cacheClient;
public UserRepository(GlobalSettings globalSettings, ICacheClient cacheClient)
: this(globalSettings.SqlServer.ConnectionString, cacheClient)
{ }
public UserRepository(string connectionString, ICacheClient cacheClient)
: base(connectionString)
{
_cacheClient = cacheClient;
}
public override async Task<User> GetByIdAsync(Guid id)
{
var cacheKey = string.Format(Constants.UserIdCacheKey, id);
var user = await _cacheClient.GetAsync<User>(cacheKey);
if(user != null)
{
return user;
}
user = await base.GetByIdAsync(id);
await _cacheClient.AddAsync(cacheKey, user);
return user;
}
public async Task<User> GetByEmailAsync(string email)
{
using(var connection = new SqlConnection(ConnectionString))
@ -26,5 +50,22 @@ namespace Bit.Core.Repositories.SqlServer
return results.SingleOrDefault();
}
}
public override async Task ReplaceAsync(User user)
{
await base.ReplaceAsync(user);
await PurgeCacheAsync(user);
}
public override async Task DeleteAsync(User user)
{
await base.DeleteAsync(user);
await PurgeCacheAsync(user);
}
private async Task PurgeCacheAsync(User user)
{
await _cacheClient.RemoveAllAsync(new string[] { string.Format(Constants.UserIdCacheKey, user.Id) });
}
}
}

View File

@ -10,7 +10,9 @@
"Microsoft.AspNetCore.Mvc.Abstractions": "1.0.0-rc2-final",
"Dapper": "1.42.0",
"DataTableProxy": "1.2.0",
"Sendgrid": "6.3.4"
"Sendgrid": "6.3.4",
"StackExchange.Redis": "1.0.488",
"StackExchange.Redis.Extensions.Protobuf": "1.3.5"
},
"frameworks": {