1
0
mirror of https://github.com/bitwarden/server.git synced 2025-01-12 20:20:37 +01:00

added cipher history API for data syncing with client databases

This commit is contained in:
Kyle Spearrin 2016-06-08 20:40:20 -04:00
parent 6861303586
commit 89e524e1e4
6 changed files with 86 additions and 0 deletions

View File

@ -50,6 +50,14 @@ namespace Bit.Api.Controllers
return new ListResponseModel<CipherResponseModel>(responses);
}
[HttpGet("history")]
public async Task<CipherHistoryResponseModel> Get(DateTime since)
{
var history = await _cipherRepository.GetManySinceRevisionDateAndUserIdWithDeleteHistoryAsync(
since, new Guid(_userManager.GetUserId(User)));
return new CipherHistoryResponseModel(history.Item1, history.Item2);
}
[HttpPost("import")]
public async Task PostImport([FromBody]ImportRequestModel model)
{

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Bit.Core.Domains;
namespace Bit.Api.Models
{
public class CipherHistoryResponseModel : ResponseModel
{
public CipherHistoryResponseModel(IEnumerable<Cipher> revisedCiphers, IEnumerable<Guid> deletedIds)
: base("cipherHistory")
{
if(revisedCiphers == null)
{
throw new ArgumentNullException(nameof(revisedCiphers));
}
if(deletedIds == null)
{
throw new ArgumentNullException(nameof(deletedIds));
}
Revised = revisedCiphers.Select(c => new CipherResponseModel(c));
Deleted = deletedIds.Select(id => id.ToString());
}
public IEnumerable<CipherResponseModel> Revised { get; set; }
public IEnumerable<string> Deleted { get; set; }
}
}

View File

@ -10,6 +10,8 @@ namespace Bit.Core.Repositories
Task<Cipher> GetByIdAsync(Guid id, Guid userId);
Task<ICollection<Cipher>> GetManyByUserIdAsync(Guid userId);
Task<ICollection<Cipher>> GetManyByTypeAndUserIdAsync(Enums.CipherType type, Guid userId);
Task<Tuple<ICollection<Cipher>, ICollection<Guid>>>
GetManySinceRevisionDateAndUserIdWithDeleteHistoryAsync(DateTime sinceRevisionDate, Guid userId);
Task UpdateUserEmailPasswordAndCiphersAsync(User user, IEnumerable<Cipher> ciphers);
Task CreateAsync(IEnumerable<Cipher> ciphers);
}

View File

@ -57,6 +57,27 @@ namespace Bit.Core.Repositories.SqlServer
}
}
public async Task<Tuple<ICollection<Cipher>, ICollection<Guid>>>
GetManySinceRevisionDateAndUserIdWithDeleteHistoryAsync(DateTime sinceRevisionDate, Guid userId)
{
using(var connection = new SqlConnection(ConnectionString))
{
var results = await connection.QueryMultipleAsync(
$"[{Schema}].[{Table}_ReadByRevisionDateUserWithDeleteHistory]",
new
{
SinceRevisionDate = sinceRevisionDate,
UserId = userId
},
commandType: CommandType.StoredProcedure);
var ciphers = await results.ReadAsync<Cipher>();
var deletes = await results.ReadAsync<Guid>();
return new Tuple<ICollection<Cipher>, ICollection<Guid>>(ciphers.ToList(), deletes.ToList());
}
}
public Task UpdateUserEmailPasswordAndCiphersAsync(User user, IEnumerable<Cipher> ciphers)
{
if(ciphers.Count() == 0)

View File

@ -84,5 +84,6 @@
<Build Include="dbo\Stored Procedures\User_Update.sql" />
<Build Include="dbo\Stored Procedures\Cipher_ReadByUserId.sql" />
<Build Include="dbo\Stored Procedures\User_UpdateEmailPassword.sql" />
<Build Include="dbo\Stored Procedures\Cipher_ReadByRevisionDateWithDeleteHistory.sql" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,24 @@
CREATE PROCEDURE [dbo].[Cipher_ReadByRevisionDateUserWithDeleteHistory]
@SinceRevisionDate DATETIME2(7),
@UserId UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON
SELECT
*
FROM
[dbo].[CipherView]
WHERE
[RevisionDate] > @SinceRevisionDate
AND [UserId] = @UserId
SELECT
[CipherId]
FROM
[dbo].[History]
WHERE
[Date] > @SinceRevisionDate
AND [Event] = 2 -- Only cipher delete events.
AND [UserId] = @UserId
END