Skip to content

Commit 3caf697

Browse files
Dimfredxeroc
authored andcommitted
fixed pull request things
added original_referrer
1 parent 8a94314 commit 3caf697

File tree

7 files changed

+86
-19
lines changed

7 files changed

+86
-19
lines changed

api_access.json

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
{
3939
"required_lifetime_member": false,
4040
"required_registrar": "registrar_name1",
41+
"required_referrer": "",
4142
"allowed_apis":
4243
[
4344
"database_api",
@@ -49,6 +50,7 @@
4950
{
5051
"required_lifetime_member": true,
5152
"required_registrar": "registrar_name2",
53+
"required_referrer": "",
5254
"allowed_apis":
5355
[
5456
"database_api",

libraries/app/api.cpp

+42-13
Original file line numberDiff line numberDiff line change
@@ -102,18 +102,22 @@ namespace graphene { namespace app {
102102
auto op = trx.operations[0];
103103
if( op.which() != operation::tag<transfer_operation>::value ) // only transfer op for validation
104104
return false;
105+
105106
const auto acc_id = op.get<transfer_operation>().from;
107+
const auto to = op.get<transfer_operation>().to;
108+
if( acc_id != to ) // prevent MITM attacks
109+
return false;
106110

107111
const auto& signature_keys = trx.get_signature_keys( db->get_chain_id() );
108112
if( signature_keys.empty() )
109113
return false;
110-
114+
111115
const auto& public_key = *signature_keys.begin();
112-
116+
113117
auto key_refs = (*_database_api)->get_key_references( {public_key} )[0];
114118
if( std::find( key_refs.begin(), key_refs.end(), acc_id ) == key_refs.end() )
115119
return false;
116-
120+
117121
const auto& acc = acc_id(*db);
118122
optional< api_access_info_signed_variant > api_access_info_var = _app.get_api_access_info_signed( acc.name );
119123
if( !api_access_info_var )
@@ -123,7 +127,7 @@ namespace graphene { namespace app {
123127
{
124128
const auto& api_access_info = api_access_info_var->get<api_access_info_signed>();
125129
if( !verify_api_access_info_signed( acc, api_access_info ) )
126-
return false; // TODO or try default login then???
130+
return false;
127131

128132
for( const auto& api : api_access_info.allowed_apis )
129133
enable_api( api );
@@ -150,23 +154,48 @@ namespace graphene { namespace app {
150154
bool login_api::verify_api_access_info_signed( const account_object& acc,
151155
const api_access_info_signed& api_access_info )
152156
{
157+
auto db = _app.chain_database();
158+
153159
if( api_access_info.required_lifetime_member && !acc.is_lifetime_member() )
154160
return false;
155161

156162
const auto& required_registrar_name = api_access_info.required_registrar;
157-
if( required_registrar_name == "" )
163+
bool registrar_required = required_registrar_name != "" ? true : false;
164+
165+
const auto& required_referrer_name = api_access_info.required_referrer;
166+
bool referrer_required = required_referrer_name != "" ? true : false;
167+
168+
if( !referrer_required && !registrar_required )
158169
return true;
159170

160-
auto db = _app.chain_database();
161-
const string account_registrar_name = acc.registrar(*db).name;
162-
string account_original_registrar_name;
163-
if( acc.original_registrar )
164-
account_original_registrar_name = (*acc.original_registrar)(*db).name;
165171

166-
bool has_required_registrar = required_registrar_name == account_registrar_name
167-
|| required_registrar_name == account_original_registrar_name;
172+
bool has_required_registrar = true;
173+
if( registrar_required )
174+
{
175+
const string acc_registrar_name = acc.registrar(*db).name;
176+
177+
string acc_original_registrar_name;
178+
if( acc.original_registrar )
179+
acc_original_registrar_name = (*acc.original_registrar)(*db).name;
180+
181+
has_required_registrar = required_registrar_name == acc_registrar_name
182+
|| required_registrar_name == acc_original_registrar_name;
183+
}
184+
185+
bool has_required_referrer = true;
186+
if( referrer_required )
187+
{
188+
const string acc_referrer_name = acc.referrer(*db).name;
189+
190+
string acc_original_referrer_name;
191+
if( acc.original_referrer )
192+
acc_original_referrer_name = (*acc.original_registrar)(*db).name;
193+
194+
has_required_referrer = required_referrer_name == acc_referrer_name
195+
|| required_referrer_name == acc_original_referrer_name;
196+
}
168197

169-
return has_required_registrar;
198+
return has_required_registrar && has_required_referrer;
170199
}
171200

172201
void login_api::enable_api( const std::string& api_name )

libraries/app/application.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -231,11 +231,11 @@ void application_impl::new_connection( const fc::http::websocket_connection_ptr&
231231
auto wsc = std::make_shared<fc::rpc::websocket_api_connection>(c, GRAPHENE_NET_MAX_NESTED_OBJECTS);
232232
auto login = std::make_shared<graphene::app::login_api>( std::ref(*_self) );
233233
login->enable_api("database_api");
234-
234+
235235
wsc->register_api(login->database());
236236
wsc->register_api(fc::api<graphene::app::login_api>(login));
237237
c->set_session_data( wsc );
238-
238+
239239
std::string username = "*";
240240
std::string password = "*";
241241
// Try to extract login information from "Authorization" header if present

libraries/app/include/graphene/app/api_access.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ struct api_access_info_signed
4343
{
4444
bool required_lifetime_member;
4545
std::string required_registrar;
46+
std::string required_referrer;
4647
std::vector< std::string > allowed_apis;
4748
};
4849

@@ -58,7 +59,6 @@ typedef fc::static_variant<
5859
std::vector< api_access_info_signed >
5960
> api_access_info_signed_variant;
6061

61-
6262
} } // graphene::app
6363

6464
FC_REFLECT( graphene::app::api_access_info,
@@ -70,6 +70,7 @@ FC_REFLECT( graphene::app::api_access_info,
7070
FC_REFLECT( graphene::app::api_access_info_signed,
7171
(required_lifetime_member)
7272
(required_registrar)
73+
(required_referrer)
7374
(allowed_apis)
7475
)
7576

libraries/chain/account_evaluator.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ object_id_type account_create_evaluator::do_apply( const account_create_operatio
185185
{
186186
obj.registrar = o.registrar;
187187
obj.referrer = o.referrer;
188+
obj.original_referrer = o.referrer;
188189
obj.lifetime_referrer = o.referrer(d).lifetime_referrer;
189190

190191
const auto& params = global_properties.parameters;
@@ -417,7 +418,7 @@ void_result account_upgrade_evaluator::do_evaluate(const account_upgrade_evaluat
417418
void_result account_upgrade_evaluator::do_apply(const account_upgrade_evaluator::operation_type& o)
418419
{ try {
419420
database& d = db();
420-
421+
421422
d.modify(*account, [&](account_object& a) {
422423
if( o.upgrade_to_lifetime_member )
423424
{

libraries/chain/include/graphene/chain/account_object.hpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ namespace graphene { namespace chain {
173173
account_id_type lifetime_referrer;
174174
/// The original registrar of this account, this value is set when account_upgrade_operation is performed
175175
optional<account_id_type> original_registrar;
176+
/// The original referrer of this account, this value is set when account_upgrade_operation is performed
177+
optional<account_id_type> original_referrer;
176178

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

185187
/// The account's name. This name must be unique among all account names on the graph. May not be empty.
186188
string name;
187-
189+
188190
/**
189191
* The owner authority represents absolute control over the account. Usually the keys in this authority will
190192
* be kept in cold storage, as they should not be needed very often and compromise of these keys constitutes
@@ -456,6 +458,7 @@ FC_REFLECT_DERIVED( graphene::chain::account_object,
456458
(top_n_control_flags)
457459
(allowed_assets)
458460
(original_registrar)
461+
(original_referrer)
459462
)
460463

461464
FC_REFLECT_DERIVED( graphene::chain::account_balance_object,

tests/tests/login_signed_tests.cpp

+32-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ BOOST_AUTO_TEST_CASE( fail_with_timestamp_too_fresh )
5252
ACTOR( alice );
5353
transfer_operation op;
5454
op.from = alice_id;
55+
op.to = alice_id;
5556

5657
signed_transaction trx;
5758
trx.operations.push_back( op );
@@ -74,6 +75,7 @@ BOOST_AUTO_TEST_CASE( fail_with_timestamp_too_old )
7475
ACTOR( alice );
7576
transfer_operation op;
7677
op.from = alice_id;
78+
op.to = alice_id;
7779

7880
signed_transaction trx;
7981
trx.operations.push_back( op );
@@ -89,13 +91,35 @@ BOOST_AUTO_TEST_CASE( fail_with_timestamp_too_old )
8991

9092
} FC_LOG_AND_RETHROW() }
9193

94+
BOOST_AUTO_TEST_CASE( fail_with_from_neq_to )
95+
{ try {
96+
97+
ACTORS( (alice) (bob) );
98+
transfer_operation op;
99+
op.from = alice_id;
100+
op.to = bob_id;
101+
102+
signed_transaction trx;
103+
trx.operations.push_back( op );
104+
trx.expiration = db.head_block_time() + 60; // too far in the past
105+
trx.sign( alice_private_key, db.get_chain_id() );
106+
107+
auto json = fc::json::to_string<signed_transaction>( trx );
108+
auto encoded = fc::base64_encode( json );
109+
110+
login_api login_api( app );
111+
bool logged_in = login_api.login_signed( encoded );
112+
BOOST_CHECK( !logged_in );
113+
114+
} FC_LOG_AND_RETHROW() }
115+
92116
BOOST_AUTO_TEST_CASE( fail_with_not_transfer_op_in_trx )
93117
{ try {
94118

95119
ACTOR( alice );
96120
account_update_operation op;
97121
op.account = alice_id;
98-
122+
99123
signed_transaction trx;
100124
trx.operations.push_back( op );
101125
trx.expiration = db.head_block_time() + 60;
@@ -116,6 +140,7 @@ BOOST_AUTO_TEST_CASE( fail_with_empty_signature_keys )
116140
ACTOR( alice );
117141
transfer_operation op;
118142
op.from = alice_id;
143+
op.to = alice_id;
119144

120145
signed_transaction trx;
121146
trx.operations.push_back( op );
@@ -136,6 +161,7 @@ BOOST_AUTO_TEST_CASE( fail_with_wrong_signature )
136161
ACTORS( (alice) (bob) );
137162
transfer_operation op;
138163
op.from = alice_id;
164+
op.to = alice_id;
139165

140166
signed_transaction trx;
141167
trx.operations.push_back( op );
@@ -165,6 +191,7 @@ BOOST_AUTO_TEST_CASE( fail_as_default_user_no_lifetime_member )
165191
ACTOR( alice );
166192
transfer_operation op;
167193
op.from = alice_id;
194+
op.to = alice_id;
168195

169196
signed_transaction trx;
170197
trx.operations.push_back( op );
@@ -194,6 +221,7 @@ BOOST_AUTO_TEST_CASE( fail_as_default_user_no_required_registrar )
194221
ACTOR( alice );
195222
transfer_operation op;
196223
op.from = alice_id;
224+
op.to = alice_id;
197225

198226
signed_transaction trx;
199227
trx.operations.push_back( op );
@@ -223,6 +251,7 @@ BOOST_AUTO_TEST_CASE( pass_as_default_user_no_specials )
223251
ACTOR( alice );
224252
transfer_operation op;
225253
op.from = alice_id;
254+
op.to = alice_id;
226255

227256
signed_transaction trx;
228257
trx.operations.push_back( op );
@@ -256,6 +285,7 @@ BOOST_AUTO_TEST_CASE( pass_as_default_user_with_lifetime_member )
256285

257286
transfer_operation op;
258287
op.from = alice_id;
288+
op.to = alice_id;
259289

260290
signed_transaction trx;
261291
trx.operations.push_back( op );
@@ -285,6 +315,7 @@ BOOST_AUTO_TEST_CASE( pass_as_special_user )
285315
ACTOR( alice );
286316
transfer_operation op;
287317
op.from = alice_id;
318+
op.to = alice_id;
288319

289320
signed_transaction trx;
290321
trx.operations.push_back( op );

0 commit comments

Comments
 (0)