mirror of
https://github.com/bitwarden/server.git
synced 2025-05-20 19:14:32 -05:00
added cipher history API for data syncing with client databases
This commit is contained in:
parent
6861303586
commit
89e524e1e4
@ -50,6 +50,14 @@ namespace Bit.Api.Controllers
|
|||||||
return new ListResponseModel<CipherResponseModel>(responses);
|
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")]
|
[HttpPost("import")]
|
||||||
public async Task PostImport([FromBody]ImportRequestModel model)
|
public async Task PostImport([FromBody]ImportRequestModel model)
|
||||||
{
|
{
|
||||||
|
30
src/Api/Models/Response/CipherHistoryResponseModel.cs
Normal file
30
src/Api/Models/Response/CipherHistoryResponseModel.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,8 @@ namespace Bit.Core.Repositories
|
|||||||
Task<Cipher> GetByIdAsync(Guid id, Guid userId);
|
Task<Cipher> GetByIdAsync(Guid id, Guid userId);
|
||||||
Task<ICollection<Cipher>> GetManyByUserIdAsync(Guid userId);
|
Task<ICollection<Cipher>> GetManyByUserIdAsync(Guid userId);
|
||||||
Task<ICollection<Cipher>> GetManyByTypeAndUserIdAsync(Enums.CipherType type, 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 UpdateUserEmailPasswordAndCiphersAsync(User user, IEnumerable<Cipher> ciphers);
|
||||||
Task CreateAsync(IEnumerable<Cipher> ciphers);
|
Task CreateAsync(IEnumerable<Cipher> ciphers);
|
||||||
}
|
}
|
||||||
|
@ -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)
|
public Task UpdateUserEmailPasswordAndCiphersAsync(User user, IEnumerable<Cipher> ciphers)
|
||||||
{
|
{
|
||||||
if(ciphers.Count() == 0)
|
if(ciphers.Count() == 0)
|
||||||
|
@ -84,5 +84,6 @@
|
|||||||
<Build Include="dbo\Stored Procedures\User_Update.sql" />
|
<Build Include="dbo\Stored Procedures\User_Update.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\Cipher_ReadByUserId.sql" />
|
<Build Include="dbo\Stored Procedures\Cipher_ReadByUserId.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\User_UpdateEmailPassword.sql" />
|
<Build Include="dbo\Stored Procedures\User_UpdateEmailPassword.sql" />
|
||||||
|
<Build Include="dbo\Stored Procedures\Cipher_ReadByRevisionDateWithDeleteHistory.sql" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user