Skip to content

Commit

Permalink
reworked hex keys test and added query signature test
Browse files Browse the repository at this point in the history
Signed-off-by: Mikhail Boldyrev <[email protected]>
  • Loading branch information
MBoldyrev authored and lebdron committed Jul 27, 2020
1 parent 98211c9 commit 6337964
Showing 1 changed file with 89 additions and 130 deletions.
219 changes: 89 additions & 130 deletions test/integration/acceptance/hex_keys_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,24 @@
* SPDX-License-Identifier: Apache-2.0
*/

#include <gtest/gtest-param-test.h>
#include <gtest/gtest.h>
#include "cryptography/keypair.hpp"
#include "integration/acceptance/acceptance_fixture.hpp"

#include <boost/algorithm/string.hpp>
#include <cctype>
#include <functional>
#include <iterator>
#include <utility>
#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"

Expand All @@ -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<Transformer, Transformer>(&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<Transformer, Transformer>> {
IntegrationTestFramework itf;
HexKeys() : itf(1), kNow(iroha::time::now()) {}

Expand All @@ -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),
Expand Down Expand Up @@ -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;
};
Expand All @@ -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();

Expand All @@ -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))
Expand All @@ -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))
Expand All @@ -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)
Expand All @@ -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<AccountResponse const &>(&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));

0 comments on commit 6337964

Please sign in to comment.