rbac1 - evaluators and op validators added

This commit is contained in:
satyakoneru 2020-05-26 12:28:25 +00:00
parent d8ca4d4625
commit 2a7c8749d3
18 changed files with 731 additions and 1 deletions

View file

@ -61,6 +61,8 @@ add_library( graphene_chain
protocol/vote.cpp protocol/vote.cpp
protocol/tournament.cpp protocol/tournament.cpp
protocol/small_ops.cpp protocol/small_ops.cpp
protocol/custom_permission.cpp
protocol/custom_account_authority.cpp
genesis_state.cpp genesis_state.cpp
get_config.cpp get_config.cpp
@ -112,6 +114,8 @@ add_library( graphene_chain
betting_market_evaluator.cpp betting_market_evaluator.cpp
betting_market_object.cpp betting_market_object.cpp
betting_market_group_object.cpp betting_market_group_object.cpp
custom_permission_evaluator.cpp
custom_account_authority_evaluator.cpp
affiliate_payout.cpp affiliate_payout.cpp

View file

@ -0,0 +1,150 @@
#include <graphene/chain/custom_account_authority_evaluator.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/custom_account_authority_object.hpp>
#include <graphene/chain/custom_permission_object.hpp>
#include <graphene/chain/hardfork.hpp>
namespace graphene
{
namespace chain
{
struct rbac_operation_hardfork_visitor
{
typedef void result_type;
const fc::time_point_sec block_time;
rbac_operation_hardfork_visitor( const fc::time_point_sec bt ) : block_time(bt) {}
template<typename T>
void operator()(const T &v) const {}
void operator()(const custom_permission_create_operation &op) const {
FC_ASSERT( block_time >= HARDFORK_RBAC_TIME, "custom_permission_create_operation not allowed yet!" );
}
void operator()(const custom_permission_update_operation &op) const {
FC_ASSERT( block_time >= HARDFORK_RBAC_TIME, "custom_permission_update_operation not allowed yet!" );
}
void operator()(const custom_permission_delete_operation &op) const {
FC_ASSERT( block_time >= HARDFORK_RBAC_TIME, "custom_permission_delete_operation not allowed yet!" );
}
void operator()(const custom_account_authority_create_operation &op) const {
FC_ASSERT( block_time >= HARDFORK_RBAC_TIME, "custom_account_authority_create_operation not allowed yet!" );
}
void operator()(const custom_account_authority_update_operation &op) const {
FC_ASSERT( block_time >= HARDFORK_RBAC_TIME, "custom_account_authority_update_operation not allowed yet!" );
}
void operator()(const custom_account_authority_delete_operation &op) const {
FC_ASSERT( block_time >= HARDFORK_RBAC_TIME, "custom_account_authority_delete_operation not allowed yet!" );
}
};
void_result create_custom_account_authority_evaluator::do_evaluate(const custom_account_authority_create_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_RBAC_TIME, "Not allowed until RBAC HF");
op.owner_account(d);
const custom_permission_object& pobj = op.permission_id(d);
FC_ASSERT(pobj.account == op.owner_account, "Only owner account can update account authority object");
FC_ASSERT(op.valid_to > now, "valid_to expiry should be in future");
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
object_id_type create_custom_account_authority_evaluator::do_apply(const custom_account_authority_create_operation &op)
{
try
{
database &d = db();
return d.create<custom_account_authority_object>([&op](custom_account_authority_object &obj) mutable {
obj.permission_id = op.permission_id;
obj.operation_type = op.operation_type;
obj.valid_from = op.valid_from;
obj.valid_to = op.valid_to;
}).id;
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result update_custom_account_authority_evaluator::do_evaluate(const custom_account_authority_update_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_RBAC_TIME, "Not allowed until RBAC HF");
op.owner_account(d);
const custom_account_authority_object& aobj = op.auth_id(d);
const custom_permission_object& pobj = aobj.permission_id(d);
FC_ASSERT(pobj.account == op.owner_account, "Only owner account can update account authority object");
auto valid_from = aobj.valid_from;
auto valid_to = aobj.valid_to;
if (op.new_valid_from) {
FC_ASSERT(*op.new_valid_from != aobj.valid_from,
"New valid_from provided is not different from old valid_from");
valid_from = *op.new_valid_from;
}
if (op.new_valid_to) {
FC_ASSERT(*op.new_valid_to != aobj.valid_to,
"New valid_to provided is not different from old valid_to");
FC_ASSERT(*op.new_valid_to > now, "New valid_to expiry should be in the future");
valid_to = *op.new_valid_to;
}
FC_ASSERT(valid_from < valid_to, "valid_from should be before valid_to");
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
object_id_type update_custom_account_authority_evaluator::do_apply(const custom_account_authority_update_operation &op)
{
try
{
database& d = db();
const custom_account_authority_object& aobj = op.auth_id(d);
d.modify(aobj, [&op](custom_account_authority_object &obj) {
if (op.new_valid_from)
obj.valid_from = *op.new_valid_from;
if (op.new_valid_to)
obj.valid_to = *op.new_valid_to;
});
return op.auth_id;
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result delete_custom_account_authority_evaluator::do_evaluate(const custom_account_authority_delete_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_RBAC_TIME, "Not allowed until RBAC HF");
op.owner_account(d);
const custom_account_authority_object& aobj = op.auth_id(d);
const custom_permission_object& pobj = aobj.permission_id(d);
FC_ASSERT(pobj.account == op.owner_account, "Only owner account can delete account authority object");
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
object_id_type delete_custom_account_authority_evaluator::do_apply(const custom_account_authority_delete_operation &op)
{
try
{
database &d = db();
const custom_account_authority_object& aobj = op.auth_id(d);
d.remove(aobj);
}
FC_CAPTURE_AND_RETHROW((op))
}
} // namespace chain
} // namespace graphene

View file

@ -0,0 +1,115 @@
#include <graphene/chain/custom_permission_evaluator.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/custom_permission_object.hpp>
#include <graphene/chain/hardfork.hpp>
namespace graphene
{
namespace chain
{
void_result create_custom_permission_evaluator::do_evaluate(const custom_permission_create_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_RBAC_TIME, "Not allowed until RBAC HF");
op.owner_account(d);
for (const auto &account_weight_pair : op.auth.account_auths)
{
account_weight_pair.first(d);
}
const auto &pindex = d.get_index_type<custom_permission_index>().indices().get<by_account_and_permission>();
auto pitr = pindex.find(boost::make_tuple(op.owner_account, op.permission_name));
FC_ASSERT(pitr == pindex.end(), "Permission name already exists for the given account");
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
object_id_type create_custom_permission_evaluator::do_apply(const custom_permission_create_operation &op)
{
try
{
database &d = db();
return d.create<custom_permission_object>([&op](custom_permission_object &obj) mutable {
obj.account = op.owner_account;
obj.permission_name = op.permission_name;
obj.auth = op.auth;
}).id;
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result update_custom_permission_evaluator::do_evaluate(const custom_permission_update_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_RBAC_TIME, "Not allowed until RBAC HF");
op.owner_account(d);
const custom_permission_object& pobj = op.permission_id(d);
FC_ASSERT(pobj.account == op.owner_account, "Only owner account can update permission object");
if (op.new_auth)
{
FC_ASSERT(!(*op.new_auth == pobj.auth), "New authority provided is not different from old authority");
for (const auto &account_weight_pair : op.new_auth->account_auths)
{
account_weight_pair.first(d);
}
}
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
object_id_type update_custom_permission_evaluator::do_apply(const custom_permission_update_operation &op)
{
try
{
database &d = db();
const custom_permission_object& pobj = op.permission_id(d);
d.modify(pobj, [&op](custom_permission_object &obj) {
if (op.new_auth)
obj.auth = *op.new_auth;
});
return op.permission_id;
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result delete_custom_permission_evaluator::do_evaluate(const custom_permission_delete_operation &op)
{
try
{
const database &d = db();
auto now = d.head_block_time();
FC_ASSERT(now >= HARDFORK_RBAC_TIME, "Not allowed until RBAC HF");
op.owner_account(d);
const custom_permission_object& pobj = op.permission_id(d);
FC_ASSERT(pobj.account == op.owner_account, "Only owner account can delete permission object");
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
void_result delete_custom_permission_evaluator::do_apply(const custom_permission_delete_operation &op)
{
try
{
database &d = db();
const custom_permission_object& pobj = op.permission_id(d);
// TODO: Remove all the custom_account_authority_object linked to this permission object.
d.remove(pobj);
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
}
} // namespace chain
} // namespace graphene

View file

@ -49,6 +49,8 @@
#include <graphene/chain/tournament_object.hpp> #include <graphene/chain/tournament_object.hpp>
#include <graphene/chain/match_object.hpp> #include <graphene/chain/match_object.hpp>
#include <graphene/chain/game_object.hpp> #include <graphene/chain/game_object.hpp>
#include <graphene/chain/custom_permission_object.hpp>
#include <graphene/chain/custom_account_authority_object.hpp>
#include <graphene/chain/sport_object.hpp> #include <graphene/chain/sport_object.hpp>
@ -77,6 +79,8 @@
#include <graphene/chain/event_evaluator.hpp> #include <graphene/chain/event_evaluator.hpp>
#include <graphene/chain/betting_market_evaluator.hpp> #include <graphene/chain/betting_market_evaluator.hpp>
#include <graphene/chain/tournament_evaluator.hpp> #include <graphene/chain/tournament_evaluator.hpp>
#include <graphene/chain/custom_permission_evaluator.hpp>
#include <graphene/chain/custom_account_authority_evaluator.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp> #include <graphene/chain/protocol/fee_schedule.hpp>
@ -243,6 +247,12 @@ void database::initialize_evaluators()
register_evaluator<lottery_reward_evaluator>(); register_evaluator<lottery_reward_evaluator>();
register_evaluator<lottery_end_evaluator>(); register_evaluator<lottery_end_evaluator>();
register_evaluator<sweeps_vesting_claim_evaluator>(); register_evaluator<sweeps_vesting_claim_evaluator>();
register_evaluator<create_custom_permission_evaluator>();
register_evaluator<update_custom_permission_evaluator>();
register_evaluator<delete_custom_permission_evaluator>();
register_evaluator<create_custom_account_authority_evaluator>();
register_evaluator<update_custom_account_authority_evaluator>();
register_evaluator<delete_custom_account_authority_evaluator>();
} }
void database::initialize_indexes() void database::initialize_indexes()
@ -284,6 +294,8 @@ void database::initialize_indexes()
tournament_details_idx->add_secondary_index<tournament_players_index>(); tournament_details_idx->add_secondary_index<tournament_players_index>();
add_index< primary_index<match_index> >(); add_index< primary_index<match_index> >();
add_index< primary_index<game_index> >(); add_index< primary_index<game_index> >();
add_index< primary_index<custom_permission_index> >();
add_index< primary_index<custom_account_authority_index> >();
//Implementation object indexes //Implementation object indexes
add_index< primary_index<transaction_index > >(); add_index< primary_index<transaction_index > >();

View file

@ -293,6 +293,25 @@ struct get_impacted_account_visitor
void operator()( const sweeps_vesting_claim_operation& op ) { void operator()( const sweeps_vesting_claim_operation& op ) {
_impacted.insert( op.account ); _impacted.insert( op.account );
} }
void operator()( const custom_permission_create_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const custom_permission_update_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const custom_permission_delete_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const custom_account_authority_create_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const custom_account_authority_update_operation& op ){
_impacted.insert( op.owner_account );
}
void operator()( const custom_account_authority_delete_operation& op ){
_impacted.insert( op.owner_account );
}
}; };
void graphene::chain::operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result ) void graphene::chain::operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result )

View file

@ -0,0 +1,4 @@
// RBAC HARDFORK Wednesday, 20-May-20 00:00:00 UTC
#ifndef HARDFORK_RBAC_TIME
#define HARDFORK_RBAC_TIME (fc::time_point_sec( 1589932800 ))
#endif

View file

@ -234,3 +234,6 @@
#define GPOS_PERIOD (60*60*24*30*6) // 6 months #define GPOS_PERIOD (60*60*24*30*6) // 6 months
#define GPOS_SUBPERIOD (60*60*24*30) // 1 month #define GPOS_SUBPERIOD (60*60*24*30) // 1 month
#define GPOS_VESTING_LOCKIN_PERIOD (60*60*24*30) // 1 month #define GPOS_VESTING_LOCKIN_PERIOD (60*60*24*30) // 1 month
#define RBAC_MIN_PERMISSION_NAME_LENGTH 3
#define RBAC_MAX_PERMISSION_NAME_LENGTH 10

View file

@ -0,0 +1,34 @@
#pragma once
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/protocol/custom_account_authority.hpp>
namespace graphene { namespace chain {
class create_custom_account_authority_evaluator : public evaluator<create_custom_account_authority_evaluator>
{
public:
typedef custom_account_authority_create_operation operation_type;
void_result do_evaluate(const custom_account_authority_create_operation& o);
object_id_type do_apply(const custom_account_authority_create_operation& o);
};
class update_custom_account_authority_evaluator : public evaluator<update_custom_account_authority_evaluator>
{
public:
typedef custom_account_authority_update_operation operation_type;
void_result do_evaluate(const custom_account_authority_update_operation& o);
object_id_type do_apply(const custom_account_authority_update_operation& o);
};
class delete_custom_account_authority_evaluator : public evaluator<delete_custom_account_authority_evaluator>
{
public:
typedef custom_account_authority_delete_operation operation_type;
void_result do_evaluate(const custom_account_authority_delete_operation& o);
object_id_type do_apply(const custom_account_authority_delete_operation& o);
};
} } // namespace graphene::chain

View file

@ -0,0 +1,55 @@
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
namespace graphene { namespace chain {
using namespace graphene::db;
/**
* @class custom_account_authority_object
* @brief Tracks the mappings between permission and operation types.
* @ingroup object
*/
class custom_account_authority_object : public abstract_object<custom_account_authority_object>
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = custom_account_authority_object_type;
custom_permission_id_type permission_id;
int operation_type;
time_point_sec valid_from;
time_point_sec valid_to;
};
struct by_id;
struct by_permission_and_op;
struct by_expiration;
using custom_account_authority_multi_index_type = multi_index_container<
custom_account_authority_object,
indexed_by<
ordered_unique< tag<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_unique< tag<by_permission_and_op>,
composite_key<custom_account_authority_object,
member<custom_account_authority_object, custom_permission_id_type, &custom_account_authority_object::permission_id>,
member<custom_account_authority_object, int, &custom_account_authority_object::operation_type>,
member<object, object_id_type, &object::id>
>
>,
ordered_unique<tag<by_expiration>,
composite_key<custom_account_authority_object,
member<custom_account_authority_object, time_point_sec, &custom_account_authority_object::valid_to>,
member<object, object_id_type, &object::id>
>
>
>
>;
using custom_account_authority_index = generic_index<custom_account_authority_object, custom_account_authority_multi_index_type>;
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::custom_account_authority_object, (graphene::db::object),
(permission_id)(operation_type)(valid_from)(valid_to) )

View file

@ -0,0 +1,34 @@
#pragma once
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/protocol/custom_permission.hpp>
namespace graphene { namespace chain {
class create_custom_permission_evaluator : public evaluator<create_custom_permission_evaluator>
{
public:
typedef custom_permission_create_operation operation_type;
void_result do_evaluate(const custom_permission_create_operation& o);
object_id_type do_apply(const custom_permission_create_operation& o);
};
class update_custom_permission_evaluator : public evaluator<update_custom_permission_evaluator>
{
public:
typedef custom_permission_update_operation operation_type;
void_result do_evaluate(const custom_permission_update_operation& o);
object_id_type do_apply(const custom_permission_update_operation& o);
};
class delete_custom_permission_evaluator : public evaluator<delete_custom_permission_evaluator>
{
public:
typedef custom_permission_delete_operation operation_type;
void_result do_evaluate(const custom_permission_delete_operation& o);
void_result do_apply(const custom_permission_delete_operation& o);
};
} } // namespace graphene::chain

View file

@ -0,0 +1,49 @@
#pragma once
#include <graphene/chain/protocol/types.hpp>
#include <graphene/db/object.hpp>
#include <graphene/db/generic_index.hpp>
namespace graphene { namespace chain {
using namespace graphene::db;
/**
* @class custom_permission_object
* @brief Tracks all the custom permission of an account.
* @ingroup object
*/
class custom_permission_object : public abstract_object<custom_permission_object>
{
public:
static const uint8_t space_id = protocol_ids;
static const uint8_t type_id = custom_permission_object_type;
// Account for which this permission is being created
account_id_type account;
// Permission name
string permission_name;
// Authority required for this permission
authority auth;
};
struct by_id;
struct by_account_and_permission;
using custom_permission_multi_index_type = multi_index_container<
custom_permission_object,
indexed_by<
ordered_unique< tag<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_unique< tag<by_account_and_permission>,
composite_key<custom_permission_object,
member<custom_permission_object, account_id_type, &custom_permission_object::account>,
member<custom_permission_object, string, &custom_permission_object::permission_name>
>
>
>
>;
using custom_permission_index = generic_index<custom_permission_object, custom_permission_multi_index_type>;
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::custom_permission_object, (graphene::db::object),
(account)(permission_name)(auth) )

View file

@ -0,0 +1,59 @@
#pragma once
#include <graphene/chain/protocol/base.hpp>
namespace graphene { namespace chain {
struct custom_account_authority_create_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
custom_permission_id_type permission_id;
int operation_type;
time_point_sec valid_from;
time_point_sec valid_to;
account_id_type owner_account;
account_id_type fee_payer()const { return owner_account; }
void validate() const;
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
struct custom_account_authority_update_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
custom_account_authority_id_type auth_id;
optional<time_point_sec> new_valid_from;
optional<time_point_sec> new_valid_to;
account_id_type owner_account;
account_id_type fee_payer()const { return owner_account; }
void validate() const;
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
struct custom_account_authority_delete_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
custom_account_authority_id_type auth_id;
account_id_type owner_account;
account_id_type fee_payer()const { return owner_account; }
void validate() const;
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
} } // namespace graphene::chain
FC_REFLECT(graphene::chain::custom_account_authority_create_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::custom_account_authority_create_operation, (fee)(permission_id)(operation_type)(valid_from)(valid_to)(owner_account) )
FC_REFLECT(graphene::chain::custom_account_authority_update_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::custom_account_authority_update_operation, (fee)(auth_id)(new_valid_from)(new_valid_to)(owner_account) )
FC_REFLECT(graphene::chain::custom_account_authority_delete_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::custom_account_authority_delete_operation, (fee)(auth_id)(owner_account) )

View file

@ -0,0 +1,56 @@
#pragma once
#include <graphene/chain/protocol/base.hpp>
namespace graphene { namespace chain {
struct custom_permission_create_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
account_id_type owner_account;
string permission_name;
authority auth;
account_id_type fee_payer()const { return owner_account; }
void validate() const;
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
struct custom_permission_update_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
custom_permission_id_type permission_id;
optional<authority> new_auth;
account_id_type owner_account;
account_id_type fee_payer()const { return owner_account; }
void validate() const;
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
struct custom_permission_delete_operation : public base_operation
{
struct fee_parameters_type { uint64_t fee = 0; };
asset fee;
custom_permission_id_type permission_id;
account_id_type owner_account;
account_id_type fee_payer()const { return owner_account; }
void validate() const;
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
};
} } // namespace graphene::chain
FC_REFLECT(graphene::chain::custom_permission_create_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::custom_permission_create_operation, (fee)(owner_account)(permission_name)(auth) )
FC_REFLECT(graphene::chain::custom_permission_update_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::custom_permission_update_operation, (fee)(permission_id)(new_auth)(owner_account) )
FC_REFLECT(graphene::chain::custom_permission_delete_operation::fee_parameters_type, (fee) )
FC_REFLECT(graphene::chain::custom_permission_delete_operation, (fee)(permission_id)(owner_account) )

View file

@ -45,6 +45,8 @@
#include <graphene/chain/protocol/event.hpp> #include <graphene/chain/protocol/event.hpp>
#include <graphene/chain/protocol/betting_market.hpp> #include <graphene/chain/protocol/betting_market.hpp>
#include <graphene/chain/protocol/tournament.hpp> #include <graphene/chain/protocol/tournament.hpp>
#include <graphene/chain/protocol/custom_permission.hpp>
#include <graphene/chain/protocol/custom_account_authority.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
@ -135,7 +137,13 @@ namespace graphene { namespace chain {
ticket_purchase_operation, ticket_purchase_operation,
lottery_reward_operation, lottery_reward_operation,
lottery_end_operation, lottery_end_operation,
sweeps_vesting_claim_operation sweeps_vesting_claim_operation,
custom_permission_create_operation,
custom_permission_update_operation,
custom_permission_delete_operation,
custom_account_authority_create_operation,
custom_account_authority_update_operation,
custom_account_authority_delete_operation
> operation; > operation;
/// @} // operations group /// @} // operations group

View file

@ -171,6 +171,8 @@ namespace graphene { namespace chain {
betting_market_group_object_type, betting_market_group_object_type,
betting_market_object_type, betting_market_object_type,
bet_object_type, bet_object_type,
custom_permission_object_type,
custom_account_authority_object_type,
OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
}; };
@ -230,6 +232,8 @@ namespace graphene { namespace chain {
class betting_market_group_object; class betting_market_group_object;
class betting_market_object; class betting_market_object;
class bet_object; class bet_object;
class custom_permission_object;
class custom_account_authority_object;
typedef object_id< protocol_ids, account_object_type, account_object> account_id_type; typedef object_id< protocol_ids, account_object_type, account_object> account_id_type;
typedef object_id< protocol_ids, asset_object_type, asset_object> asset_id_type; typedef object_id< protocol_ids, asset_object_type, asset_object> asset_id_type;
@ -256,6 +260,8 @@ namespace graphene { namespace chain {
typedef object_id< protocol_ids, betting_market_group_object_type, betting_market_group_object> betting_market_group_id_type; typedef object_id< protocol_ids, betting_market_group_object_type, betting_market_group_object> betting_market_group_id_type;
typedef object_id< protocol_ids, betting_market_object_type, betting_market_object> betting_market_id_type; typedef object_id< protocol_ids, betting_market_object_type, betting_market_object> betting_market_id_type;
typedef object_id< protocol_ids, bet_object_type, bet_object> bet_id_type; typedef object_id< protocol_ids, bet_object_type, bet_object> bet_id_type;
typedef object_id< protocol_ids, custom_permission_object_type, custom_permission_object> custom_permission_id_type;
typedef object_id< protocol_ids, custom_account_authority_object_type, custom_account_authority_object> custom_account_authority_id_type;
// implementation types // implementation types
class global_property_object; class global_property_object;
@ -436,6 +442,8 @@ FC_REFLECT_ENUM( graphene::chain::object_type,
(betting_market_group_object_type) (betting_market_group_object_type)
(betting_market_object_type) (betting_market_object_type)
(bet_object_type) (bet_object_type)
(custom_permission_object_type)
(custom_account_authority_object_type)
(OBJECT_TYPE_COUNT) (OBJECT_TYPE_COUNT)
) )
FC_REFLECT_ENUM( graphene::chain::impl_object_type, FC_REFLECT_ENUM( graphene::chain::impl_object_type,
@ -505,6 +513,8 @@ FC_REFLECT_TYPENAME( graphene::chain::fba_accumulator_id_type )
FC_REFLECT_TYPENAME( graphene::chain::betting_market_position_id_type ) FC_REFLECT_TYPENAME( graphene::chain::betting_market_position_id_type )
FC_REFLECT_TYPENAME( graphene::chain::global_betting_statistics_id_type ) FC_REFLECT_TYPENAME( graphene::chain::global_betting_statistics_id_type )
FC_REFLECT_TYPENAME( graphene::chain::tournament_details_id_type ) FC_REFLECT_TYPENAME( graphene::chain::tournament_details_id_type )
FC_REFLECT_TYPENAME( graphene::chain::custom_permission_id_type )
FC_REFLECT_TYPENAME( graphene::chain::custom_account_authority_id_type )
FC_REFLECT( graphene::chain::void_t, ) FC_REFLECT( graphene::chain::void_t, )

View file

@ -0,0 +1,39 @@
#include <graphene/chain/protocol/custom_account_authority.hpp>
#include <graphene/chain/protocol/operations.hpp>
namespace graphene { namespace chain {
void custom_account_authority_create_operation::validate()const {
FC_ASSERT(fee.amount >= 0, "Fee must not be negative");
FC_ASSERT(owner_account != GRAPHENE_TEMP_ACCOUNT
&& owner_account != GRAPHENE_COMMITTEE_ACCOUNT
&& owner_account != GRAPHENE_WITNESS_ACCOUNT
&& owner_account != GRAPHENE_RELAXED_COMMITTEE_ACCOUNT,
"Custom permissions and account auths cannot be created for special accounts");
FC_ASSERT(valid_from < valid_to, "valid_from should be earlier than valid_to");
FC_ASSERT(operation_type >= 0 && operation_type < operation::count(), "operation_type is not valid");
}
void custom_account_authority_update_operation::validate()const {
FC_ASSERT(fee.amount >= 0, "Fee must not be negative");
FC_ASSERT(owner_account != GRAPHENE_TEMP_ACCOUNT
&& owner_account != GRAPHENE_COMMITTEE_ACCOUNT
&& owner_account != GRAPHENE_WITNESS_ACCOUNT
&& owner_account != GRAPHENE_RELAXED_COMMITTEE_ACCOUNT,
"Custom permissions and account auths cannot be created for special accounts");
FC_ASSERT(new_valid_from.valid() || new_valid_to.valid(), "Something must be updated");
if (new_valid_from && new_valid_to) {
FC_ASSERT(*new_valid_from < *new_valid_to, "valid_from should be earlier than valid_to");
}
}
void custom_account_authority_delete_operation::validate()const {
FC_ASSERT(fee.amount >= 0, "Fee must not be negative");
FC_ASSERT(owner_account != GRAPHENE_TEMP_ACCOUNT
&& owner_account != GRAPHENE_COMMITTEE_ACCOUNT
&& owner_account != GRAPHENE_WITNESS_ACCOUNT
&& owner_account != GRAPHENE_RELAXED_COMMITTEE_ACCOUNT,
"Custom permissions and account auths cannot be created for special accounts");
}
} } // graphene::chain

View file

@ -0,0 +1,77 @@
#include <graphene/chain/protocol/custom_permission.hpp>
#include <graphene/chain/protocol/operations.hpp>
namespace graphene { namespace chain {
bool is_valid_permission_name( const string& name )
{ try {
const size_t len = name.size();
// RBAC_MIN_PERMISSION_NAME_LENGTH <= len minimum length check
if( len < RBAC_MIN_PERMISSION_NAME_LENGTH )
{
return false;
}
// len <= RBAC_MAX_PERMISSION_NAME_LENGTH max length check
if( len > RBAC_MAX_PERMISSION_NAME_LENGTH )
{
return false;
}
// First character should be a letter between a-z
if( !(name[0] >= 'a' && name[0] <= 'z') )
{
return false;
}
// Any character of a permission name should either be a small case letter a-z or a digit 0-9
for( const auto& ch: name)
{
if( !((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) )
{
return false;
}
}
// Don't accept active and owner permissions as we already have them by default
// This is for removing ambiguity for users, accepting them doesn't create any problems
if( name == "active" || name == "owner" )
{
return false;
}
return true;
} FC_CAPTURE_AND_RETHROW( (name) ) }
void custom_permission_create_operation::validate()const {
FC_ASSERT(fee.amount >= 0, "Fee must not be negative");
FC_ASSERT(is_valid_permission_name( permission_name ), "Invalid permission name provided");
FC_ASSERT(owner_account != GRAPHENE_TEMP_ACCOUNT
&& owner_account != GRAPHENE_COMMITTEE_ACCOUNT
&& owner_account != GRAPHENE_WITNESS_ACCOUNT
&& owner_account != GRAPHENE_RELAXED_COMMITTEE_ACCOUNT,
"Custom permissions and account auths cannot be created for special accounts");
FC_ASSERT(!auth.is_impossible(), "Impossible authority threshold auth provided");
FC_ASSERT(auth.address_auths.size() == 0, "Only account and key auths supported");
}
void custom_permission_update_operation::validate()const {
FC_ASSERT(fee.amount >= 0, "Fee must not be negative");
FC_ASSERT(owner_account != GRAPHENE_TEMP_ACCOUNT
&& owner_account != GRAPHENE_COMMITTEE_ACCOUNT
&& owner_account != GRAPHENE_WITNESS_ACCOUNT
&& owner_account != GRAPHENE_RELAXED_COMMITTEE_ACCOUNT,
"Custom permissions and account auths cannot be created for special accounts");
FC_ASSERT( new_auth.valid(), "Something must be updated");
if (new_auth) {
FC_ASSERT(!new_auth->is_impossible(), "Impossible authority threshold auth provided");
FC_ASSERT(new_auth->address_auths.size() == 0, "Only account and key auths supported");
}
}
void custom_permission_delete_operation::validate()const {
FC_ASSERT(fee.amount >= 0, "Fee must not be negative");
FC_ASSERT(owner_account != GRAPHENE_TEMP_ACCOUNT
&& owner_account != GRAPHENE_COMMITTEE_ACCOUNT
&& owner_account != GRAPHENE_WITNESS_ACCOUNT
&& owner_account != GRAPHENE_RELAXED_COMMITTEE_ACCOUNT,
"Custom permissions and account auths cannot be created for special accounts");
}
} } // graphene::chain

View file

@ -43,6 +43,8 @@
#include <graphene/chain/tournament_object.hpp> #include <graphene/chain/tournament_object.hpp>
#include <graphene/chain/match_object.hpp> #include <graphene/chain/match_object.hpp>
#include <graphene/chain/game_object.hpp> #include <graphene/chain/game_object.hpp>
#include <graphene/chain/custom_permission_object.hpp>
#include <graphene/chain/custom_account_authority_object.hpp>
#include <fc/smart_ref_impl.hpp> #include <fc/smart_ref_impl.hpp>
#include <iostream> #include <iostream>