Skip to content

Commit

Permalink
fixed pull request things
Browse files Browse the repository at this point in the history
added original_referrer
  • Loading branch information
Dimfred authored and xeroc committed Aug 5, 2019
1 parent aac074d commit 8fdcd8f
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 19 deletions.
2 changes: 2 additions & 0 deletions api_access.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
{
"required_lifetime_member": false,
"required_registrar": "registrar_name1",
"required_referrer": "",
"allowed_apis":
[
"database_api",
Expand All @@ -49,6 +50,7 @@
{
"required_lifetime_member": true,
"required_registrar": "registrar_name2",
"required_referrer": "",
"allowed_apis":
[
"database_api",
Expand Down
55 changes: 42 additions & 13 deletions libraries/app/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,22 @@ namespace graphene { namespace app {
auto op = trx.operations[0];
if( op.which() != operation::tag<transfer_operation>::value ) // only transfer op for validation
return false;

const auto acc_id = op.get<transfer_operation>().from;
const auto to = op.get<transfer_operation>().to;
if( acc_id != to ) // prevent MITM attacks
return false;

const auto& signature_keys = trx.get_signature_keys( db->get_chain_id() );
if( signature_keys.empty() )
return false;

const auto& public_key = *signature_keys.begin();

auto key_refs = (*_database_api)->get_key_references( {public_key} )[0];
if( std::find( key_refs.begin(), key_refs.end(), acc_id ) == key_refs.end() )
return false;

const auto& acc = acc_id(*db);
optional< api_access_info_signed_variant > api_access_info_var = _app.get_api_access_info_signed( acc.name );
if( !api_access_info_var )
Expand All @@ -123,7 +127,7 @@ namespace graphene { namespace app {
{
const auto& api_access_info = api_access_info_var->get<api_access_info_signed>();
if( !verify_api_access_info_signed( acc, api_access_info ) )
return false; // TODO or try default login then???
return false;

for( const auto& api : api_access_info.allowed_apis )
enable_api( api );
Expand All @@ -150,23 +154,48 @@ namespace graphene { namespace app {
bool login_api::verify_api_access_info_signed( const account_object& acc,
const api_access_info_signed& api_access_info )
{
auto db = _app.chain_database();

if( api_access_info.required_lifetime_member && !acc.is_lifetime_member() )
return false;

const auto& required_registrar_name = api_access_info.required_registrar;
if( required_registrar_name == "" )
bool registrar_required = required_registrar_name != "" ? true : false;

const auto& required_referrer_name = api_access_info.required_referrer;
bool referrer_required = required_referrer_name != "" ? true : false;

if( !referrer_required && !registrar_required )
return true;

auto db = _app.chain_database();
const string account_registrar_name = acc.registrar(*db).name;
string account_original_registrar_name;
if( acc.original_registrar )
account_original_registrar_name = (*acc.original_registrar)(*db).name;

bool has_required_registrar = required_registrar_name == account_registrar_name
|| required_registrar_name == account_original_registrar_name;
bool has_required_registrar = true;
if( registrar_required )
{
const string acc_registrar_name = acc.registrar(*db).name;

string acc_original_registrar_name;
if( acc.original_registrar )
acc_original_registrar_name = (*acc.original_registrar)(*db).name;

has_required_registrar = required_registrar_name == acc_registrar_name
|| required_registrar_name == acc_original_registrar_name;
}

bool has_required_referrer = true;
if( referrer_required )
{
const string acc_referrer_name = acc.referrer(*db).name;

string acc_original_referrer_name;
if( acc.original_referrer )
acc_original_referrer_name = (*acc.original_registrar)(*db).name;

has_required_referrer = required_referrer_name == acc_referrer_name
|| required_referrer_name == acc_original_referrer_name;
}

return has_required_registrar;
return has_required_registrar && has_required_referrer;
}

void login_api::enable_api( const std::string& api_name )
Expand Down
4 changes: 2 additions & 2 deletions libraries/app/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,11 +231,11 @@ void application_impl::new_connection( const fc::http::websocket_connection_ptr&
auto wsc = std::make_shared<fc::rpc::websocket_api_connection>(c, GRAPHENE_NET_MAX_NESTED_OBJECTS);
auto login = std::make_shared<graphene::app::login_api>( std::ref(*_self) );
login->enable_api("database_api");

wsc->register_api(login->database());
wsc->register_api(fc::api<graphene::app::login_api>(login));
c->set_session_data( wsc );

std::string username = "*";
std::string password = "*";
// Try to extract login information from "Authorization" header if present
Expand Down
3 changes: 2 additions & 1 deletion libraries/app/include/graphene/app/api_access.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ struct api_access_info_signed
{
bool required_lifetime_member;
std::string required_registrar;
std::string required_referrer;
std::vector< std::string > allowed_apis;
};

Expand All @@ -58,7 +59,6 @@ typedef fc::static_variant<
std::vector< api_access_info_signed >
> api_access_info_signed_variant;


} } // graphene::app

FC_REFLECT( graphene::app::api_access_info,
Expand All @@ -70,6 +70,7 @@ FC_REFLECT( graphene::app::api_access_info,
FC_REFLECT( graphene::app::api_access_info_signed,
(required_lifetime_member)
(required_registrar)
(required_referrer)
(allowed_apis)
)

Expand Down
3 changes: 2 additions & 1 deletion libraries/chain/account_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ object_id_type account_create_evaluator::do_apply( const account_create_operatio
{
obj.registrar = o.registrar;
obj.referrer = o.referrer;
obj.original_referrer = o.referrer;
obj.lifetime_referrer = o.referrer(d).lifetime_referrer;

const auto& params = global_properties.parameters;
Expand Down Expand Up @@ -417,7 +418,7 @@ void_result account_upgrade_evaluator::do_evaluate(const account_upgrade_evaluat
void_result account_upgrade_evaluator::do_apply(const account_upgrade_evaluator::operation_type& o)
{ try {
database& d = db();

d.modify(*account, [&](account_object& a) {
if( o.upgrade_to_lifetime_member )
{
Expand Down
5 changes: 4 additions & 1 deletion libraries/chain/include/graphene/chain/account_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ namespace graphene { namespace chain {
account_id_type lifetime_referrer;
/// The original registrar of this account, this value is set when account_upgrade_operation is performed
optional<account_id_type> original_registrar;
/// The original referrer of this account, this value is set when account_upgrade_operation is performed
optional<account_id_type> original_referrer;

/// Percentage of fee which should go to network.
uint16_t network_fee_percentage = GRAPHENE_DEFAULT_NETWORK_PERCENT_OF_FEE;
Expand All @@ -184,7 +186,7 @@ namespace graphene { namespace chain {

/// The account's name. This name must be unique among all account names on the graph. May not be empty.
string name;

/**
* The owner authority represents absolute control over the account. Usually the keys in this authority will
* be kept in cold storage, as they should not be needed very often and compromise of these keys constitutes
Expand Down Expand Up @@ -456,6 +458,7 @@ FC_REFLECT_DERIVED( graphene::chain::account_object,
(top_n_control_flags)
(allowed_assets)
(original_registrar)
(original_referrer)
)

FC_REFLECT_DERIVED( graphene::chain::account_balance_object,
Expand Down
33 changes: 32 additions & 1 deletion tests/tests/login_signed_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ BOOST_AUTO_TEST_CASE( fail_with_timestamp_too_fresh )
ACTOR( alice );
transfer_operation op;
op.from = alice_id;
op.to = alice_id;

signed_transaction trx;
trx.operations.push_back( op );
Expand All @@ -74,6 +75,7 @@ BOOST_AUTO_TEST_CASE( fail_with_timestamp_too_old )
ACTOR( alice );
transfer_operation op;
op.from = alice_id;
op.to = alice_id;

signed_transaction trx;
trx.operations.push_back( op );
Expand All @@ -89,13 +91,35 @@ BOOST_AUTO_TEST_CASE( fail_with_timestamp_too_old )

} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_CASE( fail_with_from_neq_to )
{ try {

ACTORS( (alice) (bob) );
transfer_operation op;
op.from = alice_id;
op.to = bob_id;

signed_transaction trx;
trx.operations.push_back( op );
trx.expiration = db.head_block_time() + 60; // too far in the past
trx.sign( alice_private_key, db.get_chain_id() );

auto json = fc::json::to_string<signed_transaction>( trx );
auto encoded = fc::base64_encode( json );

login_api login_api( app );
bool logged_in = login_api.login_signed( encoded );
BOOST_CHECK( !logged_in );

} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_CASE( fail_with_not_transfer_op_in_trx )
{ try {

ACTOR( alice );
account_update_operation op;
op.account = alice_id;

signed_transaction trx;
trx.operations.push_back( op );
trx.expiration = db.head_block_time() + 60;
Expand All @@ -116,6 +140,7 @@ BOOST_AUTO_TEST_CASE( fail_with_empty_signature_keys )
ACTOR( alice );
transfer_operation op;
op.from = alice_id;
op.to = alice_id;

signed_transaction trx;
trx.operations.push_back( op );
Expand All @@ -136,6 +161,7 @@ BOOST_AUTO_TEST_CASE( fail_with_wrong_signature )
ACTORS( (alice) (bob) );
transfer_operation op;
op.from = alice_id;
op.to = alice_id;

signed_transaction trx;
trx.operations.push_back( op );
Expand Down Expand Up @@ -165,6 +191,7 @@ BOOST_AUTO_TEST_CASE( fail_as_default_user_no_lifetime_member )
ACTOR( alice );
transfer_operation op;
op.from = alice_id;
op.to = alice_id;

signed_transaction trx;
trx.operations.push_back( op );
Expand Down Expand Up @@ -194,6 +221,7 @@ BOOST_AUTO_TEST_CASE( fail_as_default_user_no_required_registrar )
ACTOR( alice );
transfer_operation op;
op.from = alice_id;
op.to = alice_id;

signed_transaction trx;
trx.operations.push_back( op );
Expand Down Expand Up @@ -223,6 +251,7 @@ BOOST_AUTO_TEST_CASE( pass_as_default_user_no_specials )
ACTOR( alice );
transfer_operation op;
op.from = alice_id;
op.to = alice_id;

signed_transaction trx;
trx.operations.push_back( op );
Expand Down Expand Up @@ -256,6 +285,7 @@ BOOST_AUTO_TEST_CASE( pass_as_default_user_with_lifetime_member )

transfer_operation op;
op.from = alice_id;
op.to = alice_id;

signed_transaction trx;
trx.operations.push_back( op );
Expand Down Expand Up @@ -285,6 +315,7 @@ BOOST_AUTO_TEST_CASE( pass_as_special_user )
ACTOR( alice );
transfer_operation op;
op.from = alice_id;
op.to = alice_id;

signed_transaction trx;
trx.operations.push_back( op );
Expand Down

0 comments on commit 8fdcd8f

Please sign in to comment.