mirror of
https://github.com/bitwarden/server.git
synced 2025-05-28 23:04:50 -05:00
cipher details create/update
This commit is contained in:
parent
3d5437e238
commit
26b553c248
@ -65,7 +65,7 @@ namespace Bit.Api.Controllers
|
|||||||
{
|
{
|
||||||
var userId = _userService.GetProperUserId(User).Value;
|
var userId = _userService.GetProperUserId(User).Value;
|
||||||
var folderCiphers = model.Folders.Select(f => f.ToFolder(userId)).ToList();
|
var folderCiphers = model.Folders.Select(f => f.ToFolder(userId)).ToList();
|
||||||
var otherCiphers = model.Logins.Select(s => s.ToCipher(userId)).ToList();
|
var otherCiphers = model.Logins.Select(s => s.ToCipherDetails(userId)).ToList();
|
||||||
|
|
||||||
await _cipherService.ImportCiphersAsync(
|
await _cipherService.ImportCiphersAsync(
|
||||||
folderCiphers,
|
folderCiphers,
|
||||||
|
@ -58,7 +58,7 @@ namespace Bit.Api.Controllers
|
|||||||
public async Task<LoginResponseModel> Post([FromBody]LoginRequestModel model)
|
public async Task<LoginResponseModel> Post([FromBody]LoginRequestModel model)
|
||||||
{
|
{
|
||||||
var userId = _userService.GetProperUserId(User).Value;
|
var userId = _userService.GetProperUserId(User).Value;
|
||||||
var login = model.ToCipher(userId);
|
var login = model.ToCipherDetails(userId);
|
||||||
await _cipherService.SaveAsync(login);
|
await _cipherService.SaveAsync(login);
|
||||||
|
|
||||||
var response = new LoginResponseModel(login);
|
var response = new LoginResponseModel(login);
|
||||||
@ -76,7 +76,7 @@ namespace Bit.Api.Controllers
|
|||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
await _cipherService.SaveAsync(model.ToCipher(login));
|
await _cipherService.SaveAsync(model.ToCipherDetails(login));
|
||||||
|
|
||||||
var response = new LoginResponseModel(login);
|
var response = new LoginResponseModel(login);
|
||||||
return response;
|
return response;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using Bit.Core.Models.Table;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Core.Models.Data;
|
using Core.Models.Data;
|
||||||
|
|
||||||
@ -29,15 +28,15 @@ namespace Bit.Core.Models.Api
|
|||||||
[StringLength(10000)]
|
[StringLength(10000)]
|
||||||
public string Notes { get; set; }
|
public string Notes { get; set; }
|
||||||
|
|
||||||
public CipherDetails ToCipher(Guid userId)
|
public CipherDetails ToCipherDetails(Guid userId)
|
||||||
{
|
{
|
||||||
return ToCipher(new CipherDetails
|
return ToCipherDetails(new CipherDetails
|
||||||
{
|
{
|
||||||
UserId = userId
|
UserId = userId
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public CipherDetails ToCipher(CipherDetails existingLogin)
|
public CipherDetails ToCipherDetails(CipherDetails existingLogin)
|
||||||
{
|
{
|
||||||
existingLogin.FolderId = string.IsNullOrWhiteSpace(FolderId) ? null : (Guid?)new Guid(FolderId);
|
existingLogin.FolderId = string.IsNullOrWhiteSpace(FolderId) ? null : (Guid?)new Guid(FolderId);
|
||||||
existingLogin.Favorite = Favorite;
|
existingLogin.Favorite = Favorite;
|
||||||
|
@ -20,7 +20,7 @@ namespace Bit.Core.Models.Api
|
|||||||
throw new ArgumentNullException(nameof(deletedIds));
|
throw new ArgumentNullException(nameof(deletedIds));
|
||||||
}
|
}
|
||||||
|
|
||||||
Revised = revisedCiphers.Select(c => new CipherResponseModel(c));
|
//Revised = revisedCiphers.Select(c => new CipherResponseModel(c));
|
||||||
Deleted = deletedIds.Select(id => id.ToString());
|
Deleted = deletedIds.Select(id => id.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,32 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using Bit.Core.Models.Table;
|
|
||||||
using Core.Models.Data;
|
using Core.Models.Data;
|
||||||
|
|
||||||
namespace Bit.Core.Models.Api
|
namespace Bit.Core.Models.Api
|
||||||
{
|
{
|
||||||
public class CipherResponseModel : ResponseModel
|
public class CipherResponseModel : ResponseModel
|
||||||
{
|
{
|
||||||
public CipherResponseModel(Cipher cipher, string obj = "cipher")
|
|
||||||
: base(obj)
|
|
||||||
{
|
|
||||||
if(cipher == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(cipher));
|
|
||||||
}
|
|
||||||
|
|
||||||
Id = cipher.Id.ToString();
|
|
||||||
Type = cipher.Type;
|
|
||||||
RevisionDate = cipher.RevisionDate;
|
|
||||||
|
|
||||||
switch(cipher.Type)
|
|
||||||
{
|
|
||||||
case Enums.CipherType.Login:
|
|
||||||
Data = new LoginDataModel(cipher);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ArgumentException("Unsupported " + nameof(Type) + ".");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public CipherResponseModel(CipherDetails cipher, string obj = "cipher")
|
public CipherResponseModel(CipherDetails cipher, string obj = "cipher")
|
||||||
: base(obj)
|
: base(obj)
|
||||||
{
|
{
|
||||||
@ -38,6 +16,8 @@ namespace Bit.Core.Models.Api
|
|||||||
Id = cipher.Id.ToString();
|
Id = cipher.Id.ToString();
|
||||||
Type = cipher.Type;
|
Type = cipher.Type;
|
||||||
RevisionDate = cipher.RevisionDate;
|
RevisionDate = cipher.RevisionDate;
|
||||||
|
FolderId = cipher.FolderId?.ToString();
|
||||||
|
Favorite = cipher.Favorite;
|
||||||
|
|
||||||
switch(cipher.Type)
|
switch(cipher.Type)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using Core.Models.Data;
|
using Core.Models.Data;
|
||||||
using Bit.Core.Models.Table;
|
|
||||||
|
|
||||||
namespace Bit.Core.Models.Api
|
namespace Bit.Core.Models.Api
|
||||||
{
|
{
|
||||||
@ -41,8 +40,5 @@ namespace Bit.Core.Models.Api
|
|||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
public string Notes { get; set; }
|
public string Notes { get; set; }
|
||||||
public DateTime RevisionDate { get; set; }
|
public DateTime RevisionDate { get; set; }
|
||||||
|
|
||||||
// Expandables
|
|
||||||
public FolderResponseModel Folder { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,9 @@ namespace Bit.Core.Repositories
|
|||||||
Task<ICollection<CipherDetails>> GetManyByTypeAndUserIdAsync(Enums.CipherType type, Guid userId);
|
Task<ICollection<CipherDetails>> GetManyByTypeAndUserIdAsync(Enums.CipherType type, Guid userId);
|
||||||
Task<Tuple<ICollection<CipherDetails>, ICollection<Guid>>> GetManySinceRevisionDateAndUserIdWithDeleteHistoryAsync(
|
Task<Tuple<ICollection<CipherDetails>, ICollection<Guid>>> GetManySinceRevisionDateAndUserIdWithDeleteHistoryAsync(
|
||||||
DateTime sinceRevisionDate, Guid userId);
|
DateTime sinceRevisionDate, Guid userId);
|
||||||
|
Task CreateAsync(CipherDetails cipher);
|
||||||
|
Task ReplaceAsync(CipherDetails cipher);
|
||||||
|
Task UpsertAsync(CipherDetails cipher);
|
||||||
Task UpdateUserEmailPasswordAndCiphersAsync(User user, IEnumerable<Cipher> ciphers);
|
Task UpdateUserEmailPasswordAndCiphersAsync(User user, IEnumerable<Cipher> ciphers);
|
||||||
Task CreateAsync(IEnumerable<Cipher> ciphers);
|
Task CreateAsync(IEnumerable<Cipher> ciphers);
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,41 @@ namespace Bit.Core.Repositories.SqlServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task CreateAsync(CipherDetails cipher)
|
||||||
|
{
|
||||||
|
cipher.SetNewId();
|
||||||
|
using(var connection = new SqlConnection(ConnectionString))
|
||||||
|
{
|
||||||
|
var results = await connection.ExecuteAsync(
|
||||||
|
$"[{Schema}].[CipherDetails_Create]",
|
||||||
|
cipher,
|
||||||
|
commandType: CommandType.StoredProcedure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ReplaceAsync(CipherDetails obj)
|
||||||
|
{
|
||||||
|
using(var connection = new SqlConnection(ConnectionString))
|
||||||
|
{
|
||||||
|
var results = await connection.ExecuteAsync(
|
||||||
|
$"[{Schema}].[CipherDetails_Update]",
|
||||||
|
obj,
|
||||||
|
commandType: CommandType.StoredProcedure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpsertAsync(CipherDetails cipher)
|
||||||
|
{
|
||||||
|
if(cipher.Id.Equals(default(Guid)))
|
||||||
|
{
|
||||||
|
await CreateAsync(cipher);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await ReplaceAsync(cipher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Task UpdateUserEmailPasswordAndCiphersAsync(User user, IEnumerable<Cipher> ciphers)
|
public Task UpdateUserEmailPasswordAndCiphersAsync(User user, IEnumerable<Cipher> ciphers)
|
||||||
{
|
{
|
||||||
if(ciphers.Count() == 0)
|
if(ciphers.Count() == 0)
|
||||||
|
@ -7,7 +7,7 @@ namespace Bit.Core.Services
|
|||||||
{
|
{
|
||||||
public interface ICipherService
|
public interface ICipherService
|
||||||
{
|
{
|
||||||
Task SaveAsync(Cipher cipher);
|
Task SaveAsync(CipherDetails cipher);
|
||||||
Task DeleteAsync(Cipher cipher);
|
Task DeleteAsync(Cipher cipher);
|
||||||
Task SaveFolderAsync(Folder folder);
|
Task SaveFolderAsync(Folder folder);
|
||||||
Task DeleteFolderAsync(Folder folder);
|
Task DeleteFolderAsync(Folder folder);
|
||||||
|
@ -27,7 +27,7 @@ namespace Bit.Core.Services
|
|||||||
_pushService = pushService;
|
_pushService = pushService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SaveAsync(Cipher cipher)
|
public async Task SaveAsync(CipherDetails cipher)
|
||||||
{
|
{
|
||||||
if(cipher.Id == default(Guid))
|
if(cipher.Id == default(Guid))
|
||||||
{
|
{
|
||||||
|
@ -165,5 +165,8 @@
|
|||||||
<Build Include="dbo\Stored Procedures\CipherDetails_ReadById.sql" />
|
<Build Include="dbo\Stored Procedures\CipherDetails_ReadById.sql" />
|
||||||
<Build Include="dbo\Views\FolderView.sql" />
|
<Build Include="dbo\Views\FolderView.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\Folder_ReadByUserId.sql" />
|
<Build Include="dbo\Stored Procedures\Folder_ReadByUserId.sql" />
|
||||||
|
<Build Include="dbo\Stored Procedures\CipherDetails_Update.sql" />
|
||||||
|
<Build Include="dbo\Stored Procedures\CipherDetails_Create.sql" />
|
||||||
|
<Build Include="dbo\Stored Procedures\FolderCipher_DeleteByUserId.sql" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
45
src/Sql/dbo/Stored Procedures/CipherDetails_Create.sql
Normal file
45
src/Sql/dbo/Stored Procedures/CipherDetails_Create.sql
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
CREATE PROCEDURE [dbo].[CipherDetails_Create]
|
||||||
|
@Id UNIQUEIDENTIFIER,
|
||||||
|
@UserId UNIQUEIDENTIFIER,
|
||||||
|
@OrganizationId UNIQUEIDENTIFIER,
|
||||||
|
@Type TINYINT,
|
||||||
|
@Data NVARCHAR(MAX),
|
||||||
|
@CreationDate DATETIME2(7),
|
||||||
|
@RevisionDate DATETIME2(7),
|
||||||
|
@FolderId UNIQUEIDENTIFIER,
|
||||||
|
@Favorite BIT
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON
|
||||||
|
|
||||||
|
INSERT INTO [dbo].[Cipher]
|
||||||
|
(
|
||||||
|
[Id],
|
||||||
|
[UserId],
|
||||||
|
[OrganizationId],
|
||||||
|
[Type],
|
||||||
|
[Data],
|
||||||
|
[CreationDate],
|
||||||
|
[RevisionDate]
|
||||||
|
)
|
||||||
|
VALUES
|
||||||
|
(
|
||||||
|
@Id,
|
||||||
|
@UserId,
|
||||||
|
@OrganizationId,
|
||||||
|
@Type,
|
||||||
|
@Data,
|
||||||
|
@CreationDate,
|
||||||
|
@RevisionDate
|
||||||
|
)
|
||||||
|
|
||||||
|
IF @FolderId IS NOT NULL
|
||||||
|
BEGIN
|
||||||
|
EXEC [dbo].[FolderCipher_Create] @FolderId, @Id
|
||||||
|
END
|
||||||
|
|
||||||
|
IF @Favorite = 1
|
||||||
|
BEGIN
|
||||||
|
EXEC [dbo].[Favorite_Create] @UserId, @Id
|
||||||
|
END
|
||||||
|
END
|
44
src/Sql/dbo/Stored Procedures/CipherDetails_Update.sql
Normal file
44
src/Sql/dbo/Stored Procedures/CipherDetails_Update.sql
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
CREATE PROCEDURE [dbo].[CipherDetails_Update]
|
||||||
|
@Id UNIQUEIDENTIFIER,
|
||||||
|
@UserId UNIQUEIDENTIFIER,
|
||||||
|
@OrganizationId UNIQUEIDENTIFIER,
|
||||||
|
@Type TINYINT,
|
||||||
|
@Data NVARCHAR(MAX),
|
||||||
|
@CreationDate DATETIME2(7),
|
||||||
|
@RevisionDate DATETIME2(7),
|
||||||
|
@FolderId UNIQUEIDENTIFIER,
|
||||||
|
@Favorite BIT
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON
|
||||||
|
|
||||||
|
UPDATE
|
||||||
|
[dbo].[Cipher]
|
||||||
|
SET
|
||||||
|
[UserId] = @UserId,
|
||||||
|
[OrganizationId] = @OrganizationId,
|
||||||
|
[Type] = @Type,
|
||||||
|
[Data] = @Data,
|
||||||
|
[CreationDate] = @CreationDate,
|
||||||
|
[RevisionDate] = @RevisionDate
|
||||||
|
WHERE
|
||||||
|
[Id] = @Id
|
||||||
|
|
||||||
|
IF @FolderId IS NULL
|
||||||
|
BEGIN
|
||||||
|
EXEC [dbo].[FolderCipher_DeleteByUserId] @UserId, @Id
|
||||||
|
END
|
||||||
|
ELSE IF (SELECT COUNT(1) FROM [dbo].[FolderCipher] WHERE [FolderId] = @FolderId AND [CipherId] = @Id) = 0
|
||||||
|
BEGIN
|
||||||
|
EXEC [dbo].[FolderCipher_Create] @FolderId, @Id
|
||||||
|
END
|
||||||
|
|
||||||
|
IF @Favorite = 0
|
||||||
|
BEGIN
|
||||||
|
EXEC [dbo].[Favorite_Delete] @UserId, @Id
|
||||||
|
END
|
||||||
|
ELSE IF (SELECT COUNT(1) FROM [dbo].[Favorite] WHERE [UserId] = @UserId AND [CipherId] = @Id) = 0
|
||||||
|
BEGIN
|
||||||
|
EXEC [dbo].[Favorite_Create] @UserId, @Id
|
||||||
|
END
|
||||||
|
END
|
@ -5,10 +5,7 @@
|
|||||||
@Type TINYINT,
|
@Type TINYINT,
|
||||||
@Data NVARCHAR(MAX),
|
@Data NVARCHAR(MAX),
|
||||||
@CreationDate DATETIME2(7),
|
@CreationDate DATETIME2(7),
|
||||||
@RevisionDate DATETIME2(7),
|
@RevisionDate DATETIME2(7)
|
||||||
-- Extra, unused props from cipher details model since dapper maps all child properties too. This is kind of a hack.
|
|
||||||
@FolderId UNIQUEIDENTIFIER,
|
|
||||||
@Favorite BIT
|
|
||||||
AS
|
AS
|
||||||
BEGIN
|
BEGIN
|
||||||
SET NOCOUNT ON
|
SET NOCOUNT ON
|
||||||
|
@ -5,10 +5,7 @@
|
|||||||
@Type TINYINT,
|
@Type TINYINT,
|
||||||
@Data NVARCHAR(MAX),
|
@Data NVARCHAR(MAX),
|
||||||
@CreationDate DATETIME2(7),
|
@CreationDate DATETIME2(7),
|
||||||
@RevisionDate DATETIME2(7),
|
@RevisionDate DATETIME2(7)
|
||||||
-- Extra, unused props from cipher details model since dapper maps all child properties too. This is kind of a hack.
|
|
||||||
@FolderId UNIQUEIDENTIFIER,
|
|
||||||
@Favorite BIT
|
|
||||||
AS
|
AS
|
||||||
BEGIN
|
BEGIN
|
||||||
SET NOCOUNT ON
|
SET NOCOUNT ON
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
CREATE PROCEDURE [dbo].[FolderCipher_DeleteByUserId]
|
||||||
|
@UserId UNIQUEIDENTIFIER,
|
||||||
|
@CipherId UNIQUEIDENTIFIER
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON
|
||||||
|
|
||||||
|
DELETE FC
|
||||||
|
FROM
|
||||||
|
[dbo].[FolderCipher] FC
|
||||||
|
INNER JOIN
|
||||||
|
[dbo].[Folder] F ON F.[Id] = FC.[FolderId]
|
||||||
|
WHERE
|
||||||
|
F.[UserId] = @UserId
|
||||||
|
AND [CipherId] = @CipherId
|
||||||
|
END
|
Loading…
x
Reference in New Issue
Block a user