From 633796429782bc4f6fa075ae04313778c503c3ee Mon Sep 17 00:00:00 2001 From: Mikhail Boldyrev Date: Tue, 21 Jul 2020 19:35:06 -0500 Subject: [PATCH] reworked hex keys test and added query signature test Signed-off-by: Mikhail Boldyrev --- test/integration/acceptance/hex_keys_test.cpp | 219 +++++++----------- 1 file changed, 89 insertions(+), 130 deletions(-) diff --git a/test/integration/acceptance/hex_keys_test.cpp b/test/integration/acceptance/hex_keys_test.cpp index da5b72f78c7..205057d8929 100644 --- a/test/integration/acceptance/hex_keys_test.cpp +++ b/test/integration/acceptance/hex_keys_test.cpp @@ -3,13 +3,24 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include +#include +#include "cryptography/keypair.hpp" #include "integration/acceptance/acceptance_fixture.hpp" #include +#include +#include +#include +#include +#include "backend/protobuf/query_responses/proto_query_response.hpp" #include "backend/protobuf/transaction.hpp" #include "datetime/time.hpp" #include "framework/integration_framework/integration_test_framework.hpp" +#include "interfaces/common_objects/string_view_types.hpp" +#include "interfaces/common_objects/types.hpp" #include "interfaces/permissions.hpp" +#include "interfaces/query_responses/account_response.hpp" #include "module/shared_model/builders/protobuf/test_transaction_builder.hpp" #include "module/shared_model/cryptography/crypto_defaults.hpp" @@ -18,7 +29,35 @@ using namespace shared_model::crypto; using namespace shared_model::interface::types; using namespace integration_framework; -struct HexKeys : public AcceptanceFixture { +namespace { + using Transformer = int (*)(int); + + static auto kUpperLowerTransformers{ + ::testing::Values(&std::tolower, + &std::toupper)}; + + std::string transformHexPublicKey(PublicKeyHexStringView public_key, + Transformer transformer) { + std::string_view const &original_pubkey = public_key; + std::string transformed_pubkey; + std::transform(original_pubkey.begin(), + original_pubkey.end(), + std::back_inserter(transformed_pubkey), + *transformer); + return transformed_pubkey; + } + + Keypair transformHexPublicKey(Keypair keypair, Transformer transformer) { + return Keypair{ + PublicKeyHexStringView{transformHexPublicKey( + PublicKeyHexStringView{keypair.publicKey()}, transformer)}, + crypto::PrivateKey(keypair.privateKey())}; + } +} // namespace + +struct HexKeys : public AcceptanceFixture, + public ::testing::WithParamInterface< + std::tuple> { IntegrationTestFramework itf; HexKeys() : itf(1), kNow(iroha::time::now()) {} @@ -28,7 +67,8 @@ struct HexKeys : public AcceptanceFixture { Role::kRemoveSignatory, Role::kAddPeer, Role::kCreateAccount, - Role::kAppendRole}; + Role::kAppendRole, + Role::kGetMyAccount}; itf.setInitialState(common_constants::kAdminKeypair) .sendTxAwait(AcceptanceFixture::makeUserWithPerms(permissions), @@ -64,37 +104,15 @@ struct HexKeys : public AcceptanceFixture { imaginary_address, key); } - auto composeKeypairFromHex(PublicKeyHexStringView public_key, - std::string private_key) { - return crypto::Keypair( - public_key, - crypto::PrivateKey(crypto::Blob::fromHexString(private_key))); - } - Keypair keypair = DefaultCryptoAlgorithmType::generateKeypair(); - Keypair anotherKeypair = DefaultCryptoAlgorithmType::generateKeypair(); - - const std::string kLowercasedPublicKey = [this]() { - std::string result{keypair.publicKey()}; - std::transform(result.begin(), result.end(), result.begin(), [](char c) { - return std::tolower(c); - }); - return result; - }(); - PublicKeyHexStringView kLowercasedPublicKeyView{kLowercasedPublicKey}; + Keypair keypair_v1 = transformHexPublicKey(keypair, std::get<0>(GetParam())); + Keypair keypair_v2 = transformHexPublicKey(keypair, std::get<1>(GetParam())); - const std::string kUppercasedPublicKey = [this]() { - std::string result{keypair.publicKey()}; - std::transform(result.begin(), result.end(), result.begin(), [](char c) { - return std::toupper(c); - }); + PublicKeyHexStringView public_key_v1{keypair_v1.publicKey()}; + PublicKeyHexStringView public_key_v2{keypair_v2.publicKey()}; - return result; - }(); - PublicKeyHexStringView kUppercasedPublicKeyView{kUppercasedPublicKey}; - - const std::string kPrivateKey = keypair.privateKey().hex(); + Keypair another_keypair = DefaultCryptoAlgorithmType::generateKeypair(); const interface::types::TimestampType kNow; }; @@ -104,36 +122,9 @@ struct HexKeys : public AcceptanceFixture { * @when the same public key is used twice but written in different case * @then only first attempt to add the key succeeds */ -TEST_F(HexKeys, AddSignatory) { - auto tx1 = complete(addSignatory(kLowercasedPublicKeyView, kNow)); - auto tx2 = complete(addSignatory(kUppercasedPublicKeyView, kNow + 1)); - auto hash1 = tx1.hash(); - auto hash2 = tx2.hash(); - - itf.sendTx(tx1) - .checkStatus(hash1, CHECK_STATELESS_VALID) - .checkStatus(hash1, CHECK_ENOUGH_SIGNATURES) - .checkStatus(hash1, CHECK_STATEFUL_VALID) - .checkStatus(hash1, CHECK_COMMITTED) - .sendTx(tx2) - .checkStatus(hash2, CHECK_STATELESS_VALID) - .checkStatus(hash2, CHECK_ENOUGH_SIGNATURES) - .checkStatus(hash2, CHECK_STATEFUL_INVALID) - .checkStatus(hash2, CHECK_REJECTED); -} - -/** - * The same as the previous test, but the keys are swapped. - * Thus we ensure that there is no difference what case of the key is used - * first. - * - * @given an account with kAddSignatory permission - * @when the same public key is used twice but written in different case - * @then only first attempt to add the key succeeds - */ -TEST_F(HexKeys, AddSignatoryReverse) { - auto tx1 = complete(addSignatory(kUppercasedPublicKeyView, kNow)); - auto tx2 = complete(addSignatory(kLowercasedPublicKeyView, kNow + 1)); +TEST_P(HexKeys, AddSignatory) { + auto tx1 = complete(addSignatory(public_key_v1, kNow)); + auto tx2 = complete(addSignatory(public_key_v2, kNow + 1)); auto hash1 = tx1.hash(); auto hash2 = tx2.hash(); @@ -154,27 +145,9 @@ TEST_F(HexKeys, AddSignatoryReverse) { * @when a user adds a signatory using uppercased key string * @then the signatory can be removed using lowercased key string */ -TEST_F(HexKeys, RemoveSignatoryUl) { - auto tx1 = complete(addSignatory(kUppercasedPublicKeyView, kNow)); - auto tx2 = complete(removeSignatory(kLowercasedPublicKeyView, kNow + 1)); - auto hash2 = tx2.hash(); - - itf.sendTxAwait(tx1, CHECK_TXS_QUANTITY(1)) - .sendTx(tx2) - .checkStatus(hash2, CHECK_STATELESS_VALID) - .checkStatus(hash2, CHECK_ENOUGH_SIGNATURES) - .checkStatus(hash2, CHECK_STATEFUL_VALID) - .checkStatus(hash2, CHECK_COMMITTED); -} - -/** - * @given a user with kAddSignatory and kRemoveSignatory permissions - * @when a user adds a signatory using lowercased key string - * @then the signatory can be removed using uppercased key string - */ -TEST_F(HexKeys, RemoveSignatorylU) { - auto tx1 = complete(addSignatory(kLowercasedPublicKeyView, kNow)); - auto tx2 = complete(removeSignatory(kUppercasedPublicKeyView, kNow + 1)); +TEST_P(HexKeys, RemoveSignatory) { + auto tx1 = complete(addSignatory(public_key_v1, kNow)); + auto tx2 = complete(removeSignatory(public_key_v2, kNow + 1)); auto hash2 = tx2.hash(); itf.sendTxAwait(tx1, CHECK_TXS_QUANTITY(1)) @@ -191,63 +164,25 @@ TEST_F(HexKeys, RemoveSignatorylU) { * @then the first key can be removed even when it passed in lower case to a * command */ -TEST_F(HexKeys, CreateAccountUl) { +TEST_P(HexKeys, CreateAccount) { auto user = common_constants::kSameDomainUserId; - auto keypair = composeKeypairFromHex(kLowercasedPublicKeyView, kPrivateKey); // kUserId creates kSameDomainUserId and appends the role with test // permissions - auto tx1 = complete(createAccount(kUppercasedPublicKeyView, kNow) + auto tx1 = complete(createAccount(public_key_v1, kNow) .appendRole(user, common_constants::kRole)); // kSameDomainUserId adds one more key to own account auto tx2 = complete( addSignatory( - PublicKeyHexStringView{anotherKeypair.publicKey()}, kNow + 1, user) + PublicKeyHexStringView{another_keypair.publicKey()}, kNow + 1, user) .creatorAccountId(user), - keypair); + keypair_v2); // kSameDomainUserId removes the initial key specifing it in other font case - auto tx3 = complete(removeSignatory(kLowercasedPublicKeyView, kNow + 2, user) - .creatorAccountId(user), - keypair); - - itf.sendTxAwait(tx1, CHECK_TXS_QUANTITY(1)) - .sendTxAwait(tx2, CHECK_TXS_QUANTITY(1)) - .sendTxAwait(tx3, CHECK_TXS_QUANTITY(1)); -} - -/** - * The same as the previous test, but the keys are swapped. - * Thus we ensure that there is no difference what case of the key is used - * first. - * - * @given a user created with uppercased public key - * @when some additional key is added to the user - * @then the first key can be removed even when it passed in lower case to a - * command - */ -TEST_F(HexKeys, CreateAccountlU) { - auto user = common_constants::kSameDomainUserId; - auto keypair = composeKeypairFromHex(kUppercasedPublicKeyView, kPrivateKey); - - // kUserId creates kSameDomainUserId and appends the role with test - // permissions - auto tx1 = complete(createAccount(kLowercasedPublicKeyView, kNow) - .appendRole(user, common_constants::kRole)); - - // kSameDomainUserId adds one more key to own account - auto tx2 = complete( - addSignatory( - PublicKeyHexStringView{anotherKeypair.publicKey()}, kNow + 1, user) - .creatorAccountId(user), - keypair); - - // kSameDomainUserId removes the initial key specifing it in other font - // case - auto tx3 = complete(removeSignatory(kUppercasedPublicKeyView, kNow + 2, user) - .creatorAccountId(user), - keypair); + auto tx3 = complete( + removeSignatory(public_key_v2, kNow + 2, user).creatorAccountId(user), + keypair_v2); itf.sendTxAwait(tx1, CHECK_TXS_QUANTITY(1)) .sendTxAwait(tx2, CHECK_TXS_QUANTITY(1)) @@ -260,13 +195,12 @@ TEST_F(HexKeys, CreateAccountlU) { * has, but written in a different font case * @then the transaction is considered as stateful invalid */ -TEST_F(HexKeys, AddPeerSameKeyDifferentCase) { +TEST_P(HexKeys, AddPeerSameKeyDifferentCase) { std::string original_key{common_constants::kAdminKeypair.publicKey()}; - std::string same_key_uppercased = original_key; - boost::to_upper(same_key_uppercased); - ASSERT_NE(original_key, same_key_uppercased); + std::string same_key_transformed = transformHexPublicKey( + PublicKeyHexStringView{original_key}, std::get<0>(GetParam())); auto tx = - complete(addPeer(PublicKeyHexStringView{same_key_uppercased}, kNow)); + complete(addPeer(PublicKeyHexStringView{same_key_transformed}, kNow)); auto hash = tx.hash(); itf.sendTx(tx) @@ -275,3 +209,28 @@ TEST_F(HexKeys, AddPeerSameKeyDifferentCase) { .checkStatus(hash, CHECK_STATEFUL_INVALID) .checkStatus(hash, CHECK_REJECTED); } + +/** + * @given a user with kGetMyAccount permission + * @when query their account with transformed signatures + * @then query succeeds + */ +TEST_P(HexKeys, QuerySignature) { + using namespace shared_model::interface; + itf.sendQuery( + complete(baseQry().getAccount(common_constants::kUserId), + transformHexPublicKey(common_constants::kUserKeypair, + std::get<0>(GetParam()))), + [](auto const &general_response) { + AccountResponse const *account_response = + boost::get(&general_response.get()); + ASSERT_NE(account_response, nullptr); + EXPECT_EQ(account_response->account().accountId(), + common_constants::kUserId); + }); +} + +INSTANTIATE_TEST_SUITE_P(LowerAndUpper, + HexKeys, + ::testing::Combine(kUpperLowerTransformers, + kUpperLowerTransformers));