diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index 2aee274d..ecb407be 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -184,6 +184,14 @@ class database_api_impl : public std::enable_shared_from_this // gpos gpos_info get_gpos_info(const account_id_type account) const; + // rbac + vector get_custom_permissions(const account_id_type account) const; + fc::optional get_custom_permission_by_name(const account_id_type account, const string& permission_name) const; + vector get_custom_account_authorities(const account_id_type account) const; + vector get_custom_account_authorities_by_permission_id(const custom_permission_id_type permission_id) const; + vector get_custom_account_authorities_by_permission_name(const account_id_type account, const string& permission_name) const; + vector get_active_custom_account_authorities_by_operation(const account_id_type account, int operation_type) const; + //private: const account_object* get_account_from_string( const std::string& name_or_id, bool throw_if_not_found = true ) const; @@ -2305,6 +2313,118 @@ graphene::app::gpos_info database_api_impl::get_gpos_info(const account_id_type return result; } +////////////////////////////////////////////////////////////////////// +// // +// RBAC methods // +// // +////////////////////////////////////////////////////////////////////// + +vector database_api::get_custom_permissions(const account_id_type account) const +{ + return my->get_custom_permissions(account); +} + +vector database_api_impl::get_custom_permissions(const account_id_type account) const +{ + const auto& pindex = _db.get_index_type().indices().get(); + auto prange = pindex.equal_range(boost::make_tuple(account)); + vector custom_permissions; + for(const custom_permission_object& pobj : boost::make_iterator_range(prange.first, prange.second)) + { + custom_permissions.push_back(pobj); + } + return custom_permissions; +} + +fc::optional database_api::get_custom_permission_by_name(const account_id_type account, const string& permission_name) const +{ + return my->get_custom_permission_by_name(account, permission_name); +} + +fc::optional database_api_impl::get_custom_permission_by_name(const account_id_type account, const string& permission_name) const +{ + const auto& pindex = _db.get_index_type().indices().get(); + auto prange = pindex.equal_range(boost::make_tuple(account, permission_name)); + for(const custom_permission_object& pobj : boost::make_iterator_range(prange.first, prange.second)) + { + return pobj; + } + return {}; +} + +vector database_api::get_custom_account_authorities(const account_id_type account) const +{ + return my->get_custom_account_authorities(account); +} + +vector database_api_impl::get_custom_account_authorities(const account_id_type account) const +{ + const auto& pindex = _db.get_index_type().indices().get(); + const auto& cindex = _db.get_index_type().indices().get(); + vector custom_account_auths; + auto prange = pindex.equal_range(boost::make_tuple(account)); + for(const custom_permission_object& pobj : boost::make_iterator_range(prange.first, prange.second)) + { + auto crange = cindex.equal_range(boost::make_tuple(pobj.id)); + for(const custom_account_authority_object& cobj : boost::make_iterator_range(crange.first, crange.second)) + { + custom_account_auths.push_back(cobj); + } + } + return custom_account_auths; +} + +vector database_api::get_custom_account_authorities_by_permission_id(const custom_permission_id_type permission_id) const +{ + return my->get_custom_account_authorities_by_permission_id(permission_id); +} + +vector database_api_impl::get_custom_account_authorities_by_permission_id(const custom_permission_id_type permission_id) const +{ + const auto& cindex = _db.get_index_type().indices().get(); + vector custom_account_auths; + auto crange = cindex.equal_range(boost::make_tuple(permission_id)); + for(const custom_account_authority_object& cobj : boost::make_iterator_range(crange.first, crange.second)) + { + custom_account_auths.push_back(cobj); + } + return custom_account_auths; +} + +vector database_api::get_custom_account_authorities_by_permission_name(const account_id_type account, const string& permission_name) const +{ + return my->get_custom_account_authorities_by_permission_name(account, permission_name); +} + +vector database_api_impl::get_custom_account_authorities_by_permission_name(const account_id_type account, const string& permission_name) const +{ + vector custom_account_auths; + fc::optional pobj = get_custom_permission_by_name(account, permission_name); + if(!pobj) + { + return custom_account_auths; + } + const auto& cindex = _db.get_index_type().indices().get(); + auto crange = cindex.equal_range(boost::make_tuple(pobj->id)); + for(const custom_account_authority_object& cobj : boost::make_iterator_range(crange.first, crange.second)) + { + custom_account_auths.push_back(cobj); + } + return custom_account_auths; +} + +vector database_api::get_active_custom_account_authorities_by_operation(const account_id_type account, int operation_type) const +{ + return my->get_active_custom_account_authorities_by_operation(account, operation_type); +} + +vector database_api_impl::get_active_custom_account_authorities_by_operation(const account_id_type account, int operation_type) const +{ + operation op; + op.set_which(operation_type); + return _db.get_account_custom_authorities(account, op); +} + ////////////////////////////////////////////////////////////////////// // // // Private methods // diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index dc8aba52..2c3d9974 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -48,6 +48,9 @@ #include #include +#include +#include + #include #include @@ -709,6 +712,18 @@ class database_api */ gpos_info get_gpos_info(const account_id_type account) const; + ////////// + // RBAC // + ////////// + /** + * @return account and custom permissions/account-authorities info + */ + vector get_custom_permissions(const account_id_type account) const; + fc::optional get_custom_permission_by_name(const account_id_type account, const string& permission_name) const; + vector get_custom_account_authorities(const account_id_type account) const; + vector get_custom_account_authorities_by_permission_id(const custom_permission_id_type permission_id) const; + vector get_custom_account_authorities_by_permission_name(const account_id_type account, const string& permission_name) const; + vector get_active_custom_account_authorities_by_operation(const account_id_type account, int operation_type) const; private: @@ -848,4 +863,12 @@ FC_API(graphene::app::database_api, // gpos (get_gpos_info) + + //rbac + (get_custom_permissions) + (get_custom_permission_by_name) + (get_custom_account_authorities) + (get_custom_account_authorities_by_permission_id) + (get_custom_account_authorities_by_permission_name) + (get_active_custom_account_authorities_by_operation) ) diff --git a/libraries/chain/custom_account_authority_evaluator.cpp b/libraries/chain/custom_account_authority_evaluator.cpp index 651698c8..cce68775 100644 --- a/libraries/chain/custom_account_authority_evaluator.cpp +++ b/libraries/chain/custom_account_authority_evaluator.cpp @@ -84,15 +84,11 @@ void_result update_custom_account_authority_evaluator::do_evaluate(const custom_ 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; } diff --git a/libraries/wallet/include/graphene/wallet/wallet.hpp b/libraries/wallet/include/graphene/wallet/wallet.hpp index 7f4c7859..517749d6 100644 --- a/libraries/wallet/include/graphene/wallet/wallet.hpp +++ b/libraries/wallet/include/graphene/wallet/wallet.hpp @@ -1895,6 +1895,38 @@ class wallet_api bool is_gpos, bool broadcast); + signed_transaction create_custom_permission(string owner, + string permission_name, + authority auth, + bool broadcast = true); + signed_transaction update_custom_permission(string owner, + custom_permission_id_type permission_id, + fc::optional new_auth, + bool broadcast = true); + signed_transaction delete_custom_permission(string owner, + custom_permission_id_type permission_id, + bool broadcast = true); + signed_transaction create_custom_account_authority(string owner, + custom_permission_id_type permission_id, + int operation_type, + fc::time_point_sec valid_from, + fc::time_point_sec valid_to, + bool broadcast = true); + signed_transaction update_custom_account_authority(string owner, + custom_account_authority_id_type auth_id, + fc::optional new_valid_from, + fc::optional new_valid_to, + bool broadcast = true); + signed_transaction delete_custom_account_authority(string owner, + custom_account_authority_id_type auth_id, + bool broadcast = true); + vector get_custom_permissions(string owner) const; + fc::optional get_custom_permission_by_name(string owner, string permission_name) const; + vector get_custom_account_authorities(string owner) const; + vector get_custom_account_authorities_by_permission_id(custom_permission_id_type permission_id) const; + vector get_custom_account_authorities_by_permission_name(string owner, string permission_name) const; + vector get_active_custom_account_authorities_by_operation(string owner, int operation_type) const; + void dbg_make_uia(string creator, string symbol); void dbg_make_mia(string creator, string symbol); void dbg_push_blocks( std::string src_filename, uint32_t count ); @@ -2157,4 +2189,16 @@ FC_API( graphene::wallet::wallet_api, (get_all_matched_bets_for_bettor) (buy_ticket) (quit) + (create_custom_permission) + (update_custom_permission) + (delete_custom_permission) + (create_custom_account_authority) + (update_custom_account_authority) + (delete_custom_account_authority) + (get_custom_permissions) + (get_custom_permission_by_name) + (get_custom_account_authorities) + (get_custom_account_authorities_by_permission_id) + (get_custom_account_authorities_by_permission_name) + (get_active_custom_account_authorities_by_operation) ) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 0bbf305a..65148b16 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -3242,6 +3242,140 @@ public: return sign_transaction(tx, broadcast); } + signed_transaction create_custom_permission(string owner, + string permission_name, + authority auth, + bool broadcast) + { + custom_permission_create_operation create_op; + create_op.owner_account = get_account(owner).id; + create_op.permission_name = permission_name; + create_op.auth = auth; + + signed_transaction tx; + tx.operations.push_back(create_op); + set_operation_fees(tx, get_global_properties().parameters.current_fees); + tx.validate(); + return sign_transaction(tx, broadcast); + } + + signed_transaction update_custom_permission(string owner, + custom_permission_id_type permission_id, + fc::optional new_auth, + bool broadcast) + { + custom_permission_update_operation update_op; + update_op.owner_account = get_account(owner).id; + update_op.permission_id = permission_id; + update_op.new_auth = new_auth; + + signed_transaction tx; + tx.operations.push_back(update_op); + set_operation_fees(tx, get_global_properties().parameters.current_fees); + tx.validate(); + return sign_transaction(tx, broadcast); + } + + signed_transaction delete_custom_permission(string owner, + custom_permission_id_type permission_id, + bool broadcast) + { + custom_permission_delete_operation delete_op; + delete_op.owner_account = get_account(owner).id; + delete_op.permission_id = permission_id; + + signed_transaction tx; + tx.operations.push_back(delete_op); + set_operation_fees(tx, get_global_properties().parameters.current_fees); + tx.validate(); + return sign_transaction(tx, broadcast); + } + + signed_transaction create_custom_account_authority(string owner, + custom_permission_id_type permission_id, + int operation_type, + fc::time_point_sec valid_from, + fc::time_point_sec valid_to, + bool broadcast) + { + custom_account_authority_create_operation create_op; + create_op.owner_account = get_account(owner).id; + create_op.permission_id = permission_id; + create_op.operation_type = operation_type; + create_op.valid_from = valid_from; + create_op.valid_to = valid_to; + + signed_transaction tx; + tx.operations.push_back(create_op); + set_operation_fees(tx, get_global_properties().parameters.current_fees); + tx.validate(); + return sign_transaction(tx, broadcast); + } + + signed_transaction update_custom_account_authority(string owner, + custom_account_authority_id_type auth_id, + fc::optional new_valid_from, + fc::optional new_valid_to, + bool broadcast) + { + custom_account_authority_update_operation update_op; + update_op.owner_account = get_account(owner).id; + update_op.auth_id = auth_id; + update_op.new_valid_from = new_valid_from; + update_op.new_valid_to = new_valid_to; + + signed_transaction tx; + tx.operations.push_back(update_op); + set_operation_fees(tx, get_global_properties().parameters.current_fees); + tx.validate(); + return sign_transaction(tx, broadcast); + } + + signed_transaction delete_custom_account_authority(string owner, + custom_account_authority_id_type auth_id, + bool broadcast) + { + custom_account_authority_delete_operation delete_op; + delete_op.owner_account = get_account(owner).id; + delete_op.auth_id = auth_id; + + signed_transaction tx; + tx.operations.push_back(delete_op); + set_operation_fees(tx, get_global_properties().parameters.current_fees); + tx.validate(); + return sign_transaction(tx, broadcast); + } + + vector get_custom_permissions(string owner) const + { + return _remote_db->get_custom_permissions(get_account(owner).id); + } + + fc::optional get_custom_permission_by_name(string owner, string permission_name) const + { + return _remote_db->get_custom_permission_by_name(get_account(owner).id, permission_name); + } + + vector get_custom_account_authorities(string owner) const + { + return _remote_db->get_custom_account_authorities(get_account(owner).id); + } + + vector get_custom_account_authorities_by_permission_id(custom_permission_id_type permission_id) const + { + return _remote_db->get_custom_account_authorities_by_permission_id(permission_id); + } + + vector get_custom_account_authorities_by_permission_name(string owner, string permission_name) const + { + return _remote_db->get_custom_account_authorities_by_permission_name(get_account(owner).id, permission_name); + } + + vector get_active_custom_account_authorities_by_operation(string owner, int operation_type) const + { + return _remote_db->get_active_custom_account_authorities_by_operation(get_account(owner).id, operation_type); + } + void dbg_make_uia(string creator, string symbol) { asset_options opts; @@ -4541,8 +4675,84 @@ signed_transaction wallet_api::approve_proposal( return my->approve_proposal( fee_paying_account, proposal_id, delta, broadcast ); } +signed_transaction wallet_api::create_custom_permission(string owner, + string permission_name, + authority auth, + bool broadcast) +{ + return my->create_custom_permission(owner, permission_name, auth, broadcast); +} +signed_transaction wallet_api::update_custom_permission(string owner, + custom_permission_id_type permission_id, + fc::optional new_auth, + bool broadcast) +{ + return my->update_custom_permission(owner, permission_id, new_auth, broadcast); +} +signed_transaction wallet_api::delete_custom_permission(string owner, + custom_permission_id_type permission_id, + bool broadcast) +{ + return my->delete_custom_permission(owner, permission_id, broadcast); +} + +signed_transaction wallet_api::create_custom_account_authority(string owner, + custom_permission_id_type permission_id, + int operation_type, + fc::time_point_sec valid_from, + fc::time_point_sec valid_to, + bool broadcast) +{ + return my->create_custom_account_authority(owner, permission_id, operation_type, valid_from, valid_to, broadcast); +} + +signed_transaction wallet_api::update_custom_account_authority(string owner, + custom_account_authority_id_type auth_id, + fc::optional new_valid_from, + fc::optional new_valid_to, + bool broadcast) +{ + return my->update_custom_account_authority(owner, auth_id, new_valid_from, new_valid_to, broadcast); +} + +signed_transaction wallet_api::delete_custom_account_authority(string owner, + custom_account_authority_id_type auth_id, + bool broadcast) +{ + return my->delete_custom_account_authority(owner, auth_id, broadcast); +} + +vector wallet_api::get_custom_permissions(string owner) const +{ + return my->get_custom_permissions(owner); +} + +fc::optional wallet_api::get_custom_permission_by_name(string owner, string permission_name) const +{ + return my->get_custom_permission_by_name(owner, permission_name); +} + +vector wallet_api::get_custom_account_authorities(string owner) const +{ + return my->get_custom_account_authorities(owner); +} + +vector wallet_api::get_custom_account_authorities_by_permission_id(custom_permission_id_type permission_id) const +{ + return my->get_custom_account_authorities_by_permission_id(permission_id); +} + +vector wallet_api::get_custom_account_authorities_by_permission_name(string owner, string permission_name) const +{ + return my->get_custom_account_authorities_by_permission_name(owner, permission_name); +} + +vector wallet_api::get_active_custom_account_authorities_by_operation(string owner, int operation_type) const +{ + return my->get_active_custom_account_authorities_by_operation(owner, operation_type); +} global_property_object wallet_api::get_global_properties() const {