mirror of
https://github.com/bitwarden/server
synced 2025-12-10 13:23:27 +00:00
* [PM-21034] Database changes for signature keypairs (#5906) * Add signing key repositories, models, and sql migration scripts * Rename UserSigningKeys table to UserSigningKey * Rename signedpublickeyownershipclaim to signedpublickey * Move signedPublicKey to last parameter * Add newline at end of file * Rename to signature key pair * Further rename to signaturekeypair * Rename to UserSignatureKeyPairRepository * Add newline * Rename more instances to UserSignatureKeyPair * Update parameter order * Fix order * Add more renames * Cleanup * Fix sql * Add ef migrations * Fix difference in SQL SP compared to migration SP * Fix difference in SQL SP vs migration * Fix difference in SQL SP vs migration * Attempt to fix sql * Rename migration to start later * Address feedback * Move UserSignatureKeyPair to KM codeownership * Fix build * Fix build * Fix build * Move out entitytypeconfiguration * Use view for reading usersignaturekeypairs * Fix migration script * Fix migration script * Drop view if exists * Enable nullable * Replace with create or alter view * Switch go generatecomb * Switch to generatecomb * Move signature algorithm * Move useresignaturekeypairentitytypeconfiguration to km ownership * Move userSignatureKeyPair model * Unswap file names * Move sql files to km ownership * Add index on userid for signature keys * Fix wrong filename * Remove string length limit * Regenerate EF migrations * Undo changes to program.cs * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Rename dbset to plural * Update src/Infrastructure.EntityFramework/KeyManagement/Repositories/UserSignatureKeyPairRepository.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> --------- Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * [PM-21034] Implement api changes to retreive signing keys (#5932) * Add signing key repositories, models, and sql migration scripts * Rename UserSigningKeys table to UserSigningKey * Rename signedpublickeyownershipclaim to signedpublickey * Move signedPublicKey to last parameter * Add newline at end of file * Rename to signature key pair * Further rename to signaturekeypair * Rename to UserSignatureKeyPairRepository * Add newline * Rename more instances to UserSignatureKeyPair * Update parameter order * Fix order * Add more renames * Cleanup * Fix sql * Add ef migrations * Fix difference in SQL SP compared to migration SP * Fix difference in SQL SP vs migration * Fix difference in SQL SP vs migration * Attempt to fix sql * Rename migration to start later * Address feedback * Move UserSignatureKeyPair to KM codeownership * Fix build * Fix build * Fix build * Move out entitytypeconfiguration * Use view for reading usersignaturekeypairs * Fix migration script * Fix migration script * Add initial get keys endpoint * Add sync response * Cleanup * Add query and fix types * Add tests and cleanup * Fix test * Drop view if exists * Add km queries * Cleanup * Enable nullable * Cleanup * Cleanup * Enable nullable * Fix incorrect namespace * Remove unused using * Fix test build * Fix build error * Fix build * Attempt to fix tests * Attempt to fix tests * Replace with create or alter view * Attempt to fix tests * Attempt to fix build * Rename to include async suffix * Fix test * Rename repo * Attempt to fix tests * Cleanup * Test * Undo test * Fix tests * Fix test * Switch go generatecomb * Switch to generatecomb * Move signature algorithm * Move useresignaturekeypairentitytypeconfiguration to km ownership * Move userSignatureKeyPair model * Unswap file names * Move sql files to km ownership * Add index on userid for signature keys * Fix wrong filename * Fix build * Remove string length limit * Regenerate EF migrations * Undo changes to program.cs * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Rename dbset to plural * Update src/Infrastructure.EntityFramework/KeyManagement/Repositories/UserSignatureKeyPairRepository.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/KeyManagement/Models/Response/PrivateKeysResponseModel.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/KeyManagement/Controllers/UsersController.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Cleanup and move query to core * Fix test * Fix build * Fix tests * Update src/Api/KeyManagement/Models/Response/PrivateKeysResponseModel.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Switch away from primary constructor * Use argumentNullException * Add test * Pass user account keys directly to profileresponsemodel * Move registration to core * Update src/Api/Startup.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/Startup.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Remove empty line * Apply suggestions * Fix tests * Fix tests --------- Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * [PM-22384] Implement key-rotation based enrollment to user-crypto v2 (#5934) * Add signing key repositories, models, and sql migration scripts * Rename UserSigningKeys table to UserSigningKey * Rename signedpublickeyownershipclaim to signedpublickey * Move signedPublicKey to last parameter * Add newline at end of file * Rename to signature key pair * Further rename to signaturekeypair * Rename to UserSignatureKeyPairRepository * Add newline * Rename more instances to UserSignatureKeyPair * Update parameter order * Fix order * Add more renames * Cleanup * Fix sql * Add ef migrations * Fix difference in SQL SP compared to migration SP * Fix difference in SQL SP vs migration * Fix difference in SQL SP vs migration * Attempt to fix sql * Rename migration to start later * Address feedback * Move UserSignatureKeyPair to KM codeownership * Fix build * Fix build * Fix build * Move out entitytypeconfiguration * Use view for reading usersignaturekeypairs * Fix migration script * Fix migration script * Add initial get keys endpoint * Add sync response * Cleanup * Add query and fix types * Add tests and cleanup * Fix test * Drop view if exists * Add km queries * Cleanup * Enable nullable * Cleanup * Cleanup * Enable nullable * Fix incorrect namespace * Remove unused using * Fix test build * Fix build error * Fix build * Attempt to fix tests * Attempt to fix tests * Replace with create or alter view * Attempt to fix tests * Attempt to fix build * Rename to include async suffix * Fix test * Rename repo * Attempt to fix tests * Cleanup * Test * Undo test * Fix tests * Fix test * Switch go generatecomb * Switch to generatecomb * Move signature algorithm * Move useresignaturekeypairentitytypeconfiguration to km ownership * Move userSignatureKeyPair model * Unswap file names * Move sql files to km ownership * Add index on userid for signature keys * Fix wrong filename * Fix build * Remove string length limit * Regenerate EF migrations * Undo changes to program.cs * Cleanup * Add migration to user encryption v2 * Fix build * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Rename dbset to plural * Cleanup * Cleanup * Fix build * Fix test * Add validation * Fix test * Apply fixes * Fix tests * Improve tests * Add tests * Add error message validation * Fix tests * Fix tests * Fix test * Add test * Fix tests and errors * Update src/Infrastructure.EntityFramework/KeyManagement/Repositories/UserSignatureKeyPairRepository.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/KeyManagement/Models/Response/PrivateKeysResponseModel.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/KeyManagement/Controllers/UsersController.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Cleanup and move query to core * Fix test * Fix build * Fix tests * Update src/Api/KeyManagement/Models/Response/PrivateKeysResponseModel.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Switch away from primary constructor * Use argumentNullException * Add test * Pass user account keys directly to profileresponsemodel * Fix build * Fix namespace * Make signedpublickey optional * Remove unused file * Fix cases for request data conversion * Revert constructor change * Undo comments change * Apply fixes * Move registration to core * Update src/Api/Startup.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/Startup.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Remove empty line * Apply suggestions * Fix tests * Fix tests * Fix build of integration tests * Attempt to fix tests * Add test * Move v2 encryption user async below public functions * Add todo * Rename to have async suffix * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Address feedback * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Add test coverage * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Split up validation from rotation * Fix tests * Increase test coverage * Rename tests * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Add test for no signature keypair data * Fix build * Enable nullable * Fix build * Clean up data model * Fix tests * Cleanup --------- Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Fix build * [PM-22862] Account security version (#5995) * Add signing key repositories, models, and sql migration scripts * Rename UserSigningKeys table to UserSigningKey * Rename signedpublickeyownershipclaim to signedpublickey * Move signedPublicKey to last parameter * Add newline at end of file * Rename to signature key pair * Further rename to signaturekeypair * Rename to UserSignatureKeyPairRepository * Add newline * Rename more instances to UserSignatureKeyPair * Update parameter order * Fix order * Add more renames * Cleanup * Fix sql * Add ef migrations * Fix difference in SQL SP compared to migration SP * Fix difference in SQL SP vs migration * Fix difference in SQL SP vs migration * Attempt to fix sql * Rename migration to start later * Address feedback * Move UserSignatureKeyPair to KM codeownership * Fix build * Fix build * Fix build * Move out entitytypeconfiguration * Use view for reading usersignaturekeypairs * Fix migration script * Fix migration script * Add initial get keys endpoint * Add sync response * Cleanup * Add query and fix types * Add tests and cleanup * Fix test * Drop view if exists * Add km queries * Cleanup * Enable nullable * Cleanup * Cleanup * Enable nullable * Fix incorrect namespace * Remove unused using * Fix test build * Fix build error * Fix build * Attempt to fix tests * Attempt to fix tests * Replace with create or alter view * Attempt to fix tests * Attempt to fix build * Rename to include async suffix * Fix test * Rename repo * Attempt to fix tests * Cleanup * Test * Undo test * Fix tests * Fix test * Switch go generatecomb * Switch to generatecomb * Move signature algorithm * Move useresignaturekeypairentitytypeconfiguration to km ownership * Move userSignatureKeyPair model * Unswap file names * Move sql files to km ownership * Add index on userid for signature keys * Fix wrong filename * Fix build * Remove string length limit * Regenerate EF migrations * Undo changes to program.cs * Cleanup * Add migration to user encryption v2 * Fix build * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Rename dbset to plural * Cleanup * Cleanup * Fix build * Fix test * Add validation * Fix test * Apply fixes * Fix tests * Improve tests * Add tests * Add error message validation * Fix tests * Fix tests * Fix test * Add test * Fix tests and errors * Update src/Infrastructure.EntityFramework/KeyManagement/Repositories/UserSignatureKeyPairRepository.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/KeyManagement/Models/Response/PrivateKeysResponseModel.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/KeyManagement/Controllers/UsersController.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Cleanup and move query to core * Fix test * Fix build * Fix tests * Update src/Api/KeyManagement/Models/Response/PrivateKeysResponseModel.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Switch away from primary constructor * Use argumentNullException * Add test * Pass user account keys directly to profileresponsemodel * Fix build * Fix namespace * Make signedpublickey optional * Remove unused file * Fix cases for request data conversion * Revert constructor change * Undo comments change * Apply fixes * Move registration to core * Update src/Api/Startup.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/Startup.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Remove empty line * Apply suggestions * Fix tests * Fix tests * Fix build of integration tests * Attempt to fix tests * Add test * Move v2 encryption user async below public functions * Add todo * Rename to have async suffix * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Address feedback * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Add test coverage * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Split up validation from rotation * Fix tests * Increase test coverage * Rename tests * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Add test for no signature keypair data * Fix build * Enable nullable * Fix build * Clean up data model * Fix tests * Merge branch 'km/signing-upgrade-rotation' into km/account-security-version * Add security state to rotation * Update tests * Update tests and check for security state in v2 model * Cleanup * Add tests * Add security state data to integration test * Re-sort and remove limit * Update migrations * Fix sql * Fix sql * Fix sql * Fix fixture * Fix test * Fix test * Fix test --------- Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * [PM-22853] Add feature flag (#6090) * Add signing key repositories, models, and sql migration scripts * Rename UserSigningKeys table to UserSigningKey * Rename signedpublickeyownershipclaim to signedpublickey * Move signedPublicKey to last parameter * Add newline at end of file * Rename to signature key pair * Further rename to signaturekeypair * Rename to UserSignatureKeyPairRepository * Add newline * Rename more instances to UserSignatureKeyPair * Update parameter order * Fix order * Add more renames * Cleanup * Fix sql * Add ef migrations * Fix difference in SQL SP compared to migration SP * Fix difference in SQL SP vs migration * Fix difference in SQL SP vs migration * Attempt to fix sql * Rename migration to start later * Address feedback * Move UserSignatureKeyPair to KM codeownership * Fix build * Fix build * Fix build * Move out entitytypeconfiguration * Use view for reading usersignaturekeypairs * Fix migration script * Fix migration script * Add initial get keys endpoint * Add sync response * Cleanup * Add query and fix types * Add tests and cleanup * Fix test * Drop view if exists * Add km queries * Cleanup * Enable nullable * Cleanup * Cleanup * Enable nullable * Fix incorrect namespace * Remove unused using * Fix test build * Fix build error * Fix build * Attempt to fix tests * Attempt to fix tests * Replace with create or alter view * Attempt to fix tests * Attempt to fix build * Rename to include async suffix * Fix test * Rename repo * Attempt to fix tests * Cleanup * Test * Undo test * Fix tests * Fix test * Switch go generatecomb * Switch to generatecomb * Move signature algorithm * Move useresignaturekeypairentitytypeconfiguration to km ownership * Move userSignatureKeyPair model * Unswap file names * Move sql files to km ownership * Add index on userid for signature keys * Fix wrong filename * Fix build * Remove string length limit * Regenerate EF migrations * Undo changes to program.cs * Cleanup * Add migration to user encryption v2 * Fix build * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Rename dbset to plural * Cleanup * Cleanup * Fix build * Fix test * Add validation * Fix test * Apply fixes * Fix tests * Improve tests * Add tests * Add error message validation * Fix tests * Fix tests * Fix test * Add test * Fix tests and errors * Update src/Infrastructure.EntityFramework/KeyManagement/Repositories/UserSignatureKeyPairRepository.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/KeyManagement/Models/Response/PrivateKeysResponseModel.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/KeyManagement/Controllers/UsersController.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Cleanup and move query to core * Fix test * Fix build * Fix tests * Update src/Api/KeyManagement/Models/Response/PrivateKeysResponseModel.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Switch away from primary constructor * Use argumentNullException * Add test * Pass user account keys directly to profileresponsemodel * Fix build * Fix namespace * Make signedpublickey optional * Remove unused file * Fix cases for request data conversion * Revert constructor change * Undo comments change * Apply fixes * Move registration to core * Update src/Api/Startup.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/Startup.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Remove empty line * Apply suggestions * Fix tests * Fix tests * Fix build of integration tests * Attempt to fix tests * Add test * Move v2 encryption user async below public functions * Add todo * Rename to have async suffix * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Address feedback * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Add test coverage * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Split up validation from rotation * Fix tests * Increase test coverage * Rename tests * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Add test for no signature keypair data * Fix build * Enable nullable * Fix build * Clean up data model * Fix tests * Merge branch 'km/signing-upgrade-rotation' into km/account-security-version * Add security state to rotation * Update tests * Add feature flag * Update tests and check for security state in v2 model * Cleanup * Add tests * Add security state data to integration test * Re-sort and remove limit * Update migrations * Fix sql * Fix sql * Fix sql * Fix fixture * Fix test * Fix test * Fix test --------- Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * [PM-23222] Update revision date on key rotation (#6038) * Add signing key repositories, models, and sql migration scripts * Rename UserSigningKeys table to UserSigningKey * Rename signedpublickeyownershipclaim to signedpublickey * Move signedPublicKey to last parameter * Add newline at end of file * Rename to signature key pair * Further rename to signaturekeypair * Rename to UserSignatureKeyPairRepository * Add newline * Rename more instances to UserSignatureKeyPair * Update parameter order * Fix order * Add more renames * Cleanup * Fix sql * Add ef migrations * Fix difference in SQL SP compared to migration SP * Fix difference in SQL SP vs migration * Fix difference in SQL SP vs migration * Attempt to fix sql * Rename migration to start later * Address feedback * Move UserSignatureKeyPair to KM codeownership * Fix build * Fix build * Fix build * Move out entitytypeconfiguration * Use view for reading usersignaturekeypairs * Fix migration script * Fix migration script * Add initial get keys endpoint * Add sync response * Cleanup * Add query and fix types * Add tests and cleanup * Fix test * Drop view if exists * Add km queries * Cleanup * Enable nullable * Cleanup * Cleanup * Enable nullable * Fix incorrect namespace * Remove unused using * Fix test build * Fix build error * Fix build * Attempt to fix tests * Attempt to fix tests * Replace with create or alter view * Attempt to fix tests * Attempt to fix build * Rename to include async suffix * Fix test * Rename repo * Attempt to fix tests * Cleanup * Test * Undo test * Fix tests * Fix test * Switch go generatecomb * Switch to generatecomb * Move signature algorithm * Move useresignaturekeypairentitytypeconfiguration to km ownership * Move userSignatureKeyPair model * Unswap file names * Move sql files to km ownership * Add index on userid for signature keys * Fix wrong filename * Fix build * Remove string length limit * Regenerate EF migrations * Undo changes to program.cs * Cleanup * Add migration to user encryption v2 * Fix build * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update util/Migrator/DbScripts/2025-06-01_00_AddSignatureKeyPairTable.sql Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Rename dbset to plural * Cleanup * Cleanup * Fix build * Fix test * Add validation * Fix test * Apply fixes * Fix tests * Improve tests * Add tests * Add error message validation * Fix tests * Fix tests * Fix test * Add test * Fix tests and errors * Update src/Infrastructure.EntityFramework/KeyManagement/Repositories/UserSignatureKeyPairRepository.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/KeyManagement/Models/Response/PrivateKeysResponseModel.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/KeyManagement/Controllers/UsersController.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Cleanup and move query to core * Fix test * Fix build * Fix tests * Update src/Api/KeyManagement/Models/Response/PrivateKeysResponseModel.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Switch away from primary constructor * Use argumentNullException * Add test * Pass user account keys directly to profileresponsemodel * Fix build * Fix namespace * Make signedpublickey optional * Remove unused file * Fix cases for request data conversion * Revert constructor change * Undo comments change * Apply fixes * Move registration to core * Update src/Api/Startup.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/Startup.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Remove empty line * Apply suggestions * Fix tests * Fix tests * Fix build of integration tests * Attempt to fix tests * Add test * Move v2 encryption user async below public functions * Add todo * Rename to have async suffix * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Address feedback * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Add test coverage * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Split up validation from rotation * Fix tests * Increase test coverage * Rename tests * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Update src/Core/KeyManagement/UserKey/Implementations/RotateUserAccountkeysCommand.cs Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Add test for no signature keypair data * Fix build * Enable nullable * Fix build * Clean up data model * Fix tests * Merge branch 'km/signing-upgrade-rotation' into km/account-security-version * Add security state to rotation * Update tests * Update revision date on key rotation * Update tests and check for security state in v2 model * Cleanup * Add tests * Add security state data to integration test * Re-sort and remove limit * Update migrations * Fix sql * Fix sql * Fix sql * Fix fixture * Fix test * Fix test * Fix test * Add test for change date --------- Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com> * Fix signing keys * Update sql migrations * Fix tests * Add keys to identity token response * Fix tests * Fix tests * Fix formatting * Update src/Infrastructure.EntityFramework/KeyManagement/Repositories/UserSignatureKeyPairRepository.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Infrastructure.Dapper/KeyManagement/Repositories/UserSignatureKeyPairRepository.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/KeyManagement/Controllers/UsersController.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/KeyManagement/Models/Requests/SignatureKeyPairRequestModel.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Api/KeyManagement/Models/Requests/PublicKeyEncryptionKeyPairRequestModel.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Core/KeyManagement/Entities/UserSignatureKeyPair.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Core/KeyManagement/Repositories/IUserSignatureKeyPairRepository.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Core/KeyManagement/Queries/UserAccountKeysQuery.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Core/KeyManagement/Models/Data/PublicKeyEncryptionKeyPairData.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Core/KeyManagement/Entities/UserSignatureKeyPair.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Core/KeyManagement/Models/Data/RotateUserAccountKeysData.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Core/KeyManagement/Models/Data/SignatureKeyPairData.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Core/KeyManagement/Models/Data/SecurityStateData.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Core/KeyManagement/Models/Data/UserAccountKeysData.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Core/KeyManagement/Models/Request/SecurityStateModel.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Core/KeyManagement/Models/Response/PrivateKeysResponseModel.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Core/KeyManagement/Models/Response/PublicKeysResponseModel.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Core/KeyManagement/Models/Response/PublicKeyEncryptionKeyPairResponseModel.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Core/KeyManagement/Queries/Interfaces/IUserAcountKeysQuery.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update src/Core/KeyManagement/Models/Response/SignatureKeyPairResponseModel.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Remove unnecessary file * Add eof spacing * Move models * Fix build * Move models to API subdirectory * Rename model * Remove migrations * Add new ef migrations * Remove empty line * Only query account keys if the user has keys * Dotnet format * Fix test * Update test/Identity.Test/IdentityServer/BaseRequestValidatorTests.cs Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Apply suggestion * Fix whitespace * Force camel case on response models * Address feedback for sql files * Fix build * Make index unique * Add contstraints * Fix sql * Fix order * Cleanup * Fix build * Update migrations * Update EF migrations * Change parameters to nvarchar * Update to Varchar * Apply feedback * Move refresh view * Attempt to fix build * Undo sql changes * Apply feedback about varchar * Apply feedback about refresh view * Apply feedback about new lines * Address SQL feedback * Re-sort columns * Fix build * Fix order * Fix build --------- Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> Co-authored-by: Maciej Zieniuk <167752252+mzieniukbw@users.noreply.github.com>
366 lines
20 KiB
C#
366 lines
20 KiB
C#
#nullable enable
|
|
using System.Security.Claims;
|
|
using Bit.Api.AdminConsole.Models.Request.Organizations;
|
|
using Bit.Api.Auth.Models.Request;
|
|
using Bit.Api.Auth.Models.Request.WebAuthn;
|
|
using Bit.Api.KeyManagement.Controllers;
|
|
using Bit.Api.KeyManagement.Models.Requests;
|
|
using Bit.Api.KeyManagement.Validators;
|
|
using Bit.Api.Tools.Models.Request;
|
|
using Bit.Api.Vault.Models.Request;
|
|
using Bit.Core;
|
|
using Bit.Core.Auth.Entities;
|
|
using Bit.Core.Auth.Models.Data;
|
|
using Bit.Core.Entities;
|
|
using Bit.Core.Exceptions;
|
|
using Bit.Core.KeyManagement.Commands.Interfaces;
|
|
using Bit.Core.KeyManagement.Models.Data;
|
|
using Bit.Core.KeyManagement.UserKey;
|
|
using Bit.Core.Repositories;
|
|
using Bit.Core.Services;
|
|
using Bit.Core.Tools.Entities;
|
|
using Bit.Core.Vault.Entities;
|
|
using Bit.Test.Common.AutoFixture;
|
|
using Bit.Test.Common.AutoFixture.Attributes;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using NSubstitute;
|
|
using NSubstitute.ReturnsExtensions;
|
|
using Xunit;
|
|
|
|
namespace Bit.Api.Test.KeyManagement.Controllers;
|
|
|
|
[ControllerCustomize(typeof(AccountsKeyManagementController))]
|
|
[SutProviderCustomize]
|
|
[JsonDocumentCustomize]
|
|
public class AccountsKeyManagementControllerTests
|
|
{
|
|
[Theory]
|
|
[BitAutoData]
|
|
public async Task RegenerateKeysAsync_FeatureFlagOff_Throws(
|
|
SutProvider<AccountsKeyManagementController> sutProvider,
|
|
KeyRegenerationRequestModel data)
|
|
{
|
|
sutProvider.GetDependency<IFeatureService>().IsEnabled(Arg.Is(FeatureFlagKeys.PrivateKeyRegeneration))
|
|
.Returns(false);
|
|
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>()).ReturnsNull();
|
|
|
|
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.RegenerateKeysAsync(data));
|
|
|
|
await sutProvider.GetDependency<IOrganizationUserRepository>().ReceivedWithAnyArgs(0)
|
|
.GetManyByUserAsync(Arg.Any<Guid>());
|
|
await sutProvider.GetDependency<IEmergencyAccessRepository>().ReceivedWithAnyArgs(0)
|
|
.GetManyDetailsByGranteeIdAsync(Arg.Any<Guid>());
|
|
await sutProvider.GetDependency<IRegenerateUserAsymmetricKeysCommand>().ReceivedWithAnyArgs(0)
|
|
.RegenerateKeysAsync(Arg.Any<UserAsymmetricKeys>(),
|
|
Arg.Any<ICollection<OrganizationUser>>(),
|
|
Arg.Any<ICollection<EmergencyAccessDetails>>());
|
|
}
|
|
|
|
[Theory]
|
|
[BitAutoData]
|
|
public async Task RegenerateKeysAsync_UserNull_Throws(SutProvider<AccountsKeyManagementController> sutProvider,
|
|
KeyRegenerationRequestModel data)
|
|
{
|
|
sutProvider.GetDependency<IFeatureService>().IsEnabled(Arg.Is(FeatureFlagKeys.PrivateKeyRegeneration))
|
|
.Returns(true);
|
|
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>()).ReturnsNull();
|
|
|
|
await Assert.ThrowsAsync<UnauthorizedAccessException>(() => sutProvider.Sut.RegenerateKeysAsync(data));
|
|
|
|
await sutProvider.GetDependency<IOrganizationUserRepository>().ReceivedWithAnyArgs(0)
|
|
.GetManyByUserAsync(Arg.Any<Guid>());
|
|
await sutProvider.GetDependency<IEmergencyAccessRepository>().ReceivedWithAnyArgs(0)
|
|
.GetManyDetailsByGranteeIdAsync(Arg.Any<Guid>());
|
|
await sutProvider.GetDependency<IRegenerateUserAsymmetricKeysCommand>().ReceivedWithAnyArgs(0)
|
|
.RegenerateKeysAsync(Arg.Any<UserAsymmetricKeys>(),
|
|
Arg.Any<ICollection<OrganizationUser>>(),
|
|
Arg.Any<ICollection<EmergencyAccessDetails>>());
|
|
}
|
|
|
|
[Theory]
|
|
[BitAutoData]
|
|
public async Task RegenerateKeysAsync_Success(SutProvider<AccountsKeyManagementController> sutProvider,
|
|
KeyRegenerationRequestModel data, User user, ICollection<OrganizationUser> orgUsers,
|
|
ICollection<EmergencyAccessDetails> accessDetails)
|
|
{
|
|
sutProvider.GetDependency<IFeatureService>().IsEnabled(Arg.Is(FeatureFlagKeys.PrivateKeyRegeneration))
|
|
.Returns(true);
|
|
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>()).Returns(user);
|
|
sutProvider.GetDependency<IOrganizationUserRepository>().GetManyByUserAsync(Arg.Is(user.Id)).Returns(orgUsers);
|
|
sutProvider.GetDependency<IEmergencyAccessRepository>().GetManyDetailsByGranteeIdAsync(Arg.Is(user.Id))
|
|
.Returns(accessDetails);
|
|
|
|
await sutProvider.Sut.RegenerateKeysAsync(data);
|
|
|
|
await sutProvider.GetDependency<IOrganizationUserRepository>().Received(1)
|
|
.GetManyByUserAsync(Arg.Is(user.Id));
|
|
await sutProvider.GetDependency<IEmergencyAccessRepository>().Received(1)
|
|
.GetManyDetailsByGranteeIdAsync(Arg.Is(user.Id));
|
|
await sutProvider.GetDependency<IRegenerateUserAsymmetricKeysCommand>().Received(1)
|
|
.RegenerateKeysAsync(
|
|
Arg.Is<UserAsymmetricKeys>(u =>
|
|
u.UserId == user.Id && u.PublicKey == data.UserPublicKey &&
|
|
u.UserKeyEncryptedPrivateKey == data.UserKeyEncryptedUserPrivateKey),
|
|
Arg.Is(orgUsers),
|
|
Arg.Is(accessDetails));
|
|
}
|
|
|
|
[Theory]
|
|
[BitAutoData]
|
|
public async Task RotateUserAccountKeysSuccess(SutProvider<AccountsKeyManagementController> sutProvider,
|
|
RotateUserAccountKeysAndDataRequestModel data, User user)
|
|
{
|
|
data.AccountKeys.SignatureKeyPair = null;
|
|
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>()).Returns(user);
|
|
sutProvider.GetDependency<IRotateUserAccountKeysCommand>().RotateUserAccountKeysAsync(Arg.Any<User>(), Arg.Any<RotateUserAccountKeysData>())
|
|
.Returns(IdentityResult.Success);
|
|
await sutProvider.Sut.RotateUserAccountKeysAsync(data);
|
|
|
|
await sutProvider.GetDependency<IRotationValidator<IEnumerable<EmergencyAccessWithIdRequestModel>, IEnumerable<EmergencyAccess>>>().Received(1)
|
|
.ValidateAsync(Arg.Any<User>(), Arg.Is(data.AccountUnlockData.EmergencyAccessUnlockData));
|
|
await sutProvider.GetDependency<IRotationValidator<IEnumerable<ResetPasswordWithOrgIdRequestModel>, IReadOnlyList<OrganizationUser>>>().Received(1)
|
|
.ValidateAsync(Arg.Any<User>(), Arg.Is(data.AccountUnlockData.OrganizationAccountRecoveryUnlockData));
|
|
await sutProvider.GetDependency<IRotationValidator<IEnumerable<WebAuthnLoginRotateKeyRequestModel>, IEnumerable<WebAuthnLoginRotateKeyData>>>().Received(1)
|
|
.ValidateAsync(Arg.Any<User>(), Arg.Is(data.AccountUnlockData.PasskeyUnlockData));
|
|
|
|
await sutProvider.GetDependency<IRotationValidator<IEnumerable<CipherWithIdRequestModel>, IEnumerable<Cipher>>>().Received(1)
|
|
.ValidateAsync(Arg.Any<User>(), Arg.Is(data.AccountData.Ciphers));
|
|
await sutProvider.GetDependency<IRotationValidator<IEnumerable<FolderWithIdRequestModel>, IEnumerable<Folder>>>().Received(1)
|
|
.ValidateAsync(Arg.Any<User>(), Arg.Is(data.AccountData.Folders));
|
|
await sutProvider.GetDependency<IRotationValidator<IEnumerable<SendWithIdRequestModel>, IReadOnlyList<Send>>>().Received(1)
|
|
.ValidateAsync(Arg.Any<User>(), Arg.Is(data.AccountData.Sends));
|
|
|
|
await sutProvider.GetDependency<IRotateUserAccountKeysCommand>().Received(1)
|
|
.RotateUserAccountKeysAsync(Arg.Is(user), Arg.Is<RotateUserAccountKeysData>(d =>
|
|
d.OldMasterKeyAuthenticationHash == data.OldMasterKeyAuthenticationHash
|
|
|
|
&& d.MasterPasswordUnlockData.KdfType == data.AccountUnlockData.MasterPasswordUnlockData.KdfType
|
|
&& d.MasterPasswordUnlockData.KdfIterations == data.AccountUnlockData.MasterPasswordUnlockData.KdfIterations
|
|
&& d.MasterPasswordUnlockData.KdfMemory == data.AccountUnlockData.MasterPasswordUnlockData.KdfMemory
|
|
&& d.MasterPasswordUnlockData.KdfParallelism == data.AccountUnlockData.MasterPasswordUnlockData.KdfParallelism
|
|
&& d.MasterPasswordUnlockData.Email == data.AccountUnlockData.MasterPasswordUnlockData.Email
|
|
|
|
&& d.MasterPasswordUnlockData.MasterKeyAuthenticationHash == data.AccountUnlockData.MasterPasswordUnlockData.MasterKeyAuthenticationHash
|
|
&& d.MasterPasswordUnlockData.MasterKeyEncryptedUserKey == data.AccountUnlockData.MasterPasswordUnlockData.MasterKeyEncryptedUserKey
|
|
|
|
&& d.AccountKeys!.PublicKeyEncryptionKeyPairData.WrappedPrivateKey == data.AccountKeys.PublicKeyEncryptionKeyPair!.WrappedPrivateKey
|
|
&& d.AccountKeys!.PublicKeyEncryptionKeyPairData.PublicKey == data.AccountKeys.PublicKeyEncryptionKeyPair!.PublicKey
|
|
));
|
|
}
|
|
|
|
[Theory]
|
|
[BitAutoData]
|
|
public async Task RotateUserAccountKeys_UserCryptoV2_Success_Async(SutProvider<AccountsKeyManagementController> sutProvider,
|
|
RotateUserAccountKeysAndDataRequestModel data, User user)
|
|
{
|
|
data.AccountKeys.SignatureKeyPair = new SignatureKeyPairRequestModel
|
|
{
|
|
SignatureAlgorithm = "ed25519",
|
|
WrappedSigningKey = "wrappedSigningKey",
|
|
VerifyingKey = "verifyingKey"
|
|
};
|
|
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>()).Returns(user);
|
|
sutProvider.GetDependency<IRotateUserAccountKeysCommand>().RotateUserAccountKeysAsync(Arg.Any<User>(), Arg.Any<RotateUserAccountKeysData>())
|
|
.Returns(IdentityResult.Success);
|
|
await sutProvider.Sut.RotateUserAccountKeysAsync(data);
|
|
|
|
await sutProvider.GetDependency<IRotationValidator<IEnumerable<EmergencyAccessWithIdRequestModel>, IEnumerable<EmergencyAccess>>>().Received(1)
|
|
.ValidateAsync(Arg.Any<User>(), Arg.Is(data.AccountUnlockData.EmergencyAccessUnlockData));
|
|
await sutProvider.GetDependency<IRotationValidator<IEnumerable<ResetPasswordWithOrgIdRequestModel>, IReadOnlyList<OrganizationUser>>>().Received(1)
|
|
.ValidateAsync(Arg.Any<User>(), Arg.Is(data.AccountUnlockData.OrganizationAccountRecoveryUnlockData));
|
|
await sutProvider.GetDependency<IRotationValidator<IEnumerable<WebAuthnLoginRotateKeyRequestModel>, IEnumerable<WebAuthnLoginRotateKeyData>>>().Received(1)
|
|
.ValidateAsync(Arg.Any<User>(), Arg.Is(data.AccountUnlockData.PasskeyUnlockData));
|
|
|
|
await sutProvider.GetDependency<IRotationValidator<IEnumerable<CipherWithIdRequestModel>, IEnumerable<Cipher>>>().Received(1)
|
|
.ValidateAsync(Arg.Any<User>(), Arg.Is(data.AccountData.Ciphers));
|
|
await sutProvider.GetDependency<IRotationValidator<IEnumerable<FolderWithIdRequestModel>, IEnumerable<Folder>>>().Received(1)
|
|
.ValidateAsync(Arg.Any<User>(), Arg.Is(data.AccountData.Folders));
|
|
await sutProvider.GetDependency<IRotationValidator<IEnumerable<SendWithIdRequestModel>, IReadOnlyList<Send>>>().Received(1)
|
|
.ValidateAsync(Arg.Any<User>(), Arg.Is(data.AccountData.Sends));
|
|
|
|
await sutProvider.GetDependency<IRotateUserAccountKeysCommand>().Received(1)
|
|
.RotateUserAccountKeysAsync(Arg.Is(user), Arg.Is<RotateUserAccountKeysData>(d =>
|
|
d.OldMasterKeyAuthenticationHash == data.OldMasterKeyAuthenticationHash
|
|
|
|
&& d.MasterPasswordUnlockData.KdfType == data.AccountUnlockData.MasterPasswordUnlockData.KdfType
|
|
&& d.MasterPasswordUnlockData.KdfIterations == data.AccountUnlockData.MasterPasswordUnlockData.KdfIterations
|
|
&& d.MasterPasswordUnlockData.KdfMemory == data.AccountUnlockData.MasterPasswordUnlockData.KdfMemory
|
|
&& d.MasterPasswordUnlockData.KdfParallelism == data.AccountUnlockData.MasterPasswordUnlockData.KdfParallelism
|
|
&& d.MasterPasswordUnlockData.Email == data.AccountUnlockData.MasterPasswordUnlockData.Email
|
|
|
|
&& d.MasterPasswordUnlockData.MasterKeyAuthenticationHash == data.AccountUnlockData.MasterPasswordUnlockData.MasterKeyAuthenticationHash
|
|
&& d.MasterPasswordUnlockData.MasterKeyEncryptedUserKey == data.AccountUnlockData.MasterPasswordUnlockData.MasterKeyEncryptedUserKey
|
|
|
|
&& d.AccountKeys!.PublicKeyEncryptionKeyPairData.WrappedPrivateKey == data.AccountKeys.PublicKeyEncryptionKeyPair!.WrappedPrivateKey
|
|
&& d.AccountKeys!.PublicKeyEncryptionKeyPairData.PublicKey == data.AccountKeys.PublicKeyEncryptionKeyPair!.PublicKey
|
|
&& d.AccountKeys!.PublicKeyEncryptionKeyPairData.SignedPublicKey == data.AccountKeys.PublicKeyEncryptionKeyPair!.SignedPublicKey
|
|
&& d.AccountKeys!.SignatureKeyPairData!.SignatureAlgorithm == Core.KeyManagement.Enums.SignatureAlgorithm.Ed25519
|
|
&& d.AccountKeys!.SignatureKeyPairData.WrappedSigningKey == data.AccountKeys.SignatureKeyPair!.WrappedSigningKey
|
|
&& d.AccountKeys!.SignatureKeyPairData.VerifyingKey == data.AccountKeys.SignatureKeyPair!.VerifyingKey
|
|
));
|
|
}
|
|
|
|
|
|
[Theory]
|
|
[BitAutoData]
|
|
public async Task RotateUserKeyNoUser_Throws(SutProvider<AccountsKeyManagementController> sutProvider,
|
|
RotateUserAccountKeysAndDataRequestModel data)
|
|
{
|
|
data.AccountKeys.SignatureKeyPair = null;
|
|
User? user = null;
|
|
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>()).Returns(user);
|
|
sutProvider.GetDependency<IRotateUserAccountKeysCommand>().RotateUserAccountKeysAsync(Arg.Any<User>(), Arg.Any<RotateUserAccountKeysData>())
|
|
.Returns(IdentityResult.Success);
|
|
await Assert.ThrowsAsync<UnauthorizedAccessException>(() => sutProvider.Sut.RotateUserAccountKeysAsync(data));
|
|
}
|
|
|
|
[Theory]
|
|
[BitAutoData]
|
|
public async Task RotateUserKeyWrongData_Throws(SutProvider<AccountsKeyManagementController> sutProvider,
|
|
RotateUserAccountKeysAndDataRequestModel data, User user, IdentityErrorDescriber _identityErrorDescriber)
|
|
{
|
|
data.AccountKeys.SignatureKeyPair = null;
|
|
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>()).Returns(user);
|
|
sutProvider.GetDependency<IRotateUserAccountKeysCommand>().RotateUserAccountKeysAsync(Arg.Any<User>(), Arg.Any<RotateUserAccountKeysData>())
|
|
.Returns(IdentityResult.Failed(_identityErrorDescriber.PasswordMismatch()));
|
|
try
|
|
{
|
|
await sutProvider.Sut.RotateUserAccountKeysAsync(data);
|
|
Assert.Fail("Should have thrown");
|
|
}
|
|
catch (BadRequestException ex)
|
|
{
|
|
Assert.NotEmpty(ex.ModelState!.Values);
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[BitAutoData]
|
|
public async Task PostSetKeyConnectorKeyAsync_UserNull_Throws(
|
|
SutProvider<AccountsKeyManagementController> sutProvider,
|
|
SetKeyConnectorKeyRequestModel data)
|
|
{
|
|
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>()).ReturnsNull();
|
|
|
|
await Assert.ThrowsAsync<UnauthorizedAccessException>(() => sutProvider.Sut.PostSetKeyConnectorKeyAsync(data));
|
|
|
|
await sutProvider.GetDependency<IUserService>().ReceivedWithAnyArgs(0)
|
|
.SetKeyConnectorKeyAsync(Arg.Any<User>(), Arg.Any<string>(), Arg.Any<string>());
|
|
}
|
|
|
|
[Theory]
|
|
[BitAutoData]
|
|
public async Task PostSetKeyConnectorKeyAsync_SetKeyConnectorKeyFails_ThrowsBadRequestWithErrorResponse(
|
|
SutProvider<AccountsKeyManagementController> sutProvider,
|
|
SetKeyConnectorKeyRequestModel data, User expectedUser)
|
|
{
|
|
expectedUser.PublicKey = null;
|
|
expectedUser.PrivateKey = null;
|
|
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>())
|
|
.Returns(expectedUser);
|
|
sutProvider.GetDependency<IUserService>()
|
|
.SetKeyConnectorKeyAsync(Arg.Any<User>(), Arg.Any<string>(), Arg.Any<string>())
|
|
.Returns(IdentityResult.Failed(new IdentityError { Description = "set key connector key error" }));
|
|
|
|
var badRequestException =
|
|
await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.PostSetKeyConnectorKeyAsync(data));
|
|
|
|
Assert.Equal(1, badRequestException.ModelState!.ErrorCount);
|
|
Assert.Equal("set key connector key error", badRequestException.ModelState.Root.Errors[0].ErrorMessage);
|
|
await sutProvider.GetDependency<IUserService>().Received(1)
|
|
.SetKeyConnectorKeyAsync(Arg.Do<User>(user =>
|
|
{
|
|
Assert.Equal(expectedUser.Id, user.Id);
|
|
Assert.Equal(data.Key, user.Key);
|
|
Assert.Equal(data.Kdf, user.Kdf);
|
|
Assert.Equal(data.KdfIterations, user.KdfIterations);
|
|
Assert.Equal(data.KdfMemory, user.KdfMemory);
|
|
Assert.Equal(data.KdfParallelism, user.KdfParallelism);
|
|
Assert.Equal(data.Keys.PublicKey, user.PublicKey);
|
|
Assert.Equal(data.Keys.EncryptedPrivateKey, user.PrivateKey);
|
|
}), Arg.Is(data.Key), Arg.Is(data.OrgIdentifier));
|
|
}
|
|
|
|
[Theory]
|
|
[BitAutoData]
|
|
public async Task PostSetKeyConnectorKeyAsync_SetKeyConnectorKeySucceeds_OkResponse(
|
|
SutProvider<AccountsKeyManagementController> sutProvider,
|
|
SetKeyConnectorKeyRequestModel data, User expectedUser)
|
|
{
|
|
expectedUser.PublicKey = null;
|
|
expectedUser.PrivateKey = null;
|
|
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>())
|
|
.Returns(expectedUser);
|
|
sutProvider.GetDependency<IUserService>()
|
|
.SetKeyConnectorKeyAsync(Arg.Any<User>(), Arg.Any<string>(), Arg.Any<string>())
|
|
.Returns(IdentityResult.Success);
|
|
|
|
await sutProvider.Sut.PostSetKeyConnectorKeyAsync(data);
|
|
|
|
await sutProvider.GetDependency<IUserService>().Received(1)
|
|
.SetKeyConnectorKeyAsync(Arg.Do<User>(user =>
|
|
{
|
|
Assert.Equal(expectedUser.Id, user.Id);
|
|
Assert.Equal(data.Key, user.Key);
|
|
Assert.Equal(data.Kdf, user.Kdf);
|
|
Assert.Equal(data.KdfIterations, user.KdfIterations);
|
|
Assert.Equal(data.KdfMemory, user.KdfMemory);
|
|
Assert.Equal(data.KdfParallelism, user.KdfParallelism);
|
|
Assert.Equal(data.Keys.PublicKey, user.PublicKey);
|
|
Assert.Equal(data.Keys.EncryptedPrivateKey, user.PrivateKey);
|
|
}), Arg.Is(data.Key), Arg.Is(data.OrgIdentifier));
|
|
}
|
|
|
|
[Theory]
|
|
[BitAutoData]
|
|
public async Task PostConvertToKeyConnectorAsync_UserNull_Throws(
|
|
SutProvider<AccountsKeyManagementController> sutProvider)
|
|
{
|
|
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>()).ReturnsNull();
|
|
|
|
await Assert.ThrowsAsync<UnauthorizedAccessException>(() => sutProvider.Sut.PostConvertToKeyConnectorAsync());
|
|
|
|
await sutProvider.GetDependency<IUserService>().ReceivedWithAnyArgs(0)
|
|
.ConvertToKeyConnectorAsync(Arg.Any<User>());
|
|
}
|
|
|
|
[Theory]
|
|
[BitAutoData]
|
|
public async Task PostConvertToKeyConnectorAsync_ConvertToKeyConnectorFails_ThrowsBadRequestWithErrorResponse(
|
|
SutProvider<AccountsKeyManagementController> sutProvider,
|
|
User expectedUser)
|
|
{
|
|
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>())
|
|
.Returns(expectedUser);
|
|
sutProvider.GetDependency<IUserService>()
|
|
.ConvertToKeyConnectorAsync(Arg.Any<User>())
|
|
.Returns(IdentityResult.Failed(new IdentityError { Description = "convert to key connector error" }));
|
|
|
|
var badRequestException =
|
|
await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.PostConvertToKeyConnectorAsync());
|
|
|
|
Assert.Equal(1, badRequestException.ModelState!.ErrorCount);
|
|
Assert.Equal("convert to key connector error", badRequestException.ModelState.Root.Errors[0].ErrorMessage);
|
|
await sutProvider.GetDependency<IUserService>().Received(1)
|
|
.ConvertToKeyConnectorAsync(Arg.Is(expectedUser));
|
|
}
|
|
|
|
[Theory]
|
|
[BitAutoData]
|
|
public async Task PostConvertToKeyConnectorAsync_ConvertToKeyConnectorSucceeds_OkResponse(
|
|
SutProvider<AccountsKeyManagementController> sutProvider,
|
|
User expectedUser)
|
|
{
|
|
sutProvider.GetDependency<IUserService>().GetUserByPrincipalAsync(Arg.Any<ClaimsPrincipal>())
|
|
.Returns(expectedUser);
|
|
sutProvider.GetDependency<IUserService>()
|
|
.ConvertToKeyConnectorAsync(Arg.Any<User>())
|
|
.Returns(IdentityResult.Success);
|
|
|
|
await sutProvider.Sut.PostConvertToKeyConnectorAsync();
|
|
|
|
await sutProvider.GetDependency<IUserService>().Received(1)
|
|
.ConvertToKeyConnectorAsync(Arg.Is(expectedUser));
|
|
}
|
|
}
|