mirror of
https://github.com/bitwarden/server
synced 2025-12-19 17:53:44 +00:00
Add UpdateAccountCryptographicState repository function (#6669)
* Add user repository update function for account cryptographic state * Remove comment * Remove transaction logic * Fix security version * Apply feedback * Update tests * Add support for external actions
This commit is contained in:
@@ -2,16 +2,16 @@
|
||||
using System.Text.Json;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.KeyManagement.Models.Data;
|
||||
using Bit.Core.KeyManagement.UserKey;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Repositories;
|
||||
using Bit.Core.Settings;
|
||||
using Bit.Core.Utilities;
|
||||
using Dapper;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.Infrastructure.Dapper.Repositories;
|
||||
|
||||
public class UserRepository : Repository<User, Guid>, IUserRepository
|
||||
@@ -288,6 +288,63 @@ public class UserRepository : Repository<User, Guid>, IUserRepository
|
||||
UnprotectData(user);
|
||||
}
|
||||
|
||||
public async Task SetV2AccountCryptographicStateAsync(
|
||||
Guid userId,
|
||||
UserAccountKeysData accountKeysData,
|
||||
IEnumerable<UpdateUserData>? updateUserDataActions = null)
|
||||
{
|
||||
if (!accountKeysData.IsV2Encryption())
|
||||
{
|
||||
throw new ArgumentException("Provided account keys data is not valid V2 encryption data.", nameof(accountKeysData));
|
||||
}
|
||||
|
||||
var timestamp = DateTime.UtcNow;
|
||||
var signatureKeyPairId = CoreHelpers.GenerateComb();
|
||||
|
||||
await using var connection = new SqlConnection(ConnectionString);
|
||||
await connection.OpenAsync();
|
||||
|
||||
await using var transaction = connection.BeginTransaction();
|
||||
try
|
||||
{
|
||||
await connection.ExecuteAsync(
|
||||
"[dbo].[User_UpdateAccountCryptographicState]",
|
||||
new
|
||||
{
|
||||
Id = userId,
|
||||
PublicKey = accountKeysData.PublicKeyEncryptionKeyPairData.PublicKey,
|
||||
PrivateKey = accountKeysData.PublicKeyEncryptionKeyPairData.WrappedPrivateKey,
|
||||
SignedPublicKey = accountKeysData.PublicKeyEncryptionKeyPairData.SignedPublicKey,
|
||||
SecurityState = accountKeysData.SecurityStateData!.SecurityState,
|
||||
SecurityVersion = accountKeysData.SecurityStateData!.SecurityVersion,
|
||||
SignatureKeyPairId = signatureKeyPairId,
|
||||
SignatureAlgorithm = accountKeysData.SignatureKeyPairData!.SignatureAlgorithm,
|
||||
SigningKey = accountKeysData.SignatureKeyPairData!.WrappedSigningKey,
|
||||
VerifyingKey = accountKeysData.SignatureKeyPairData!.VerifyingKey,
|
||||
RevisionDate = timestamp,
|
||||
AccountRevisionDate = timestamp
|
||||
},
|
||||
transaction: transaction,
|
||||
commandType: CommandType.StoredProcedure);
|
||||
|
||||
// Update user data that depends on cryptographic state
|
||||
if (updateUserDataActions != null)
|
||||
{
|
||||
foreach (var action in updateUserDataActions)
|
||||
{
|
||||
await action(connection, transaction);
|
||||
}
|
||||
}
|
||||
|
||||
await transaction.CommitAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
await transaction.RollbackAsync();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<User>> GetManyAsync(IEnumerable<Guid> ids)
|
||||
{
|
||||
using (var connection = new SqlConnection(ReadOnlyConnectionString))
|
||||
|
||||
Reference in New Issue
Block a user