Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
Ref #123: Implement updateauth, deleteauth
Browse files Browse the repository at this point in the history
Though not strictly part of issue 123, this is a necessary step in order
to complete #123. Rename UpdatePermission->updateauth and
DeletePermission->deleteauth, and implement them.

At this point, I think #123 is fully implemented and ready for testing.
  • Loading branch information
nathanielhourt committed Aug 3, 2017
1 parent 6748f26 commit 677869e
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 4 deletions.
64 changes: 63 additions & 1 deletion libraries/native_contract/eos_contract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,71 @@ void apply_eos_setproxy(apply_context& context) {
*/
}

void apply_eos_updateauth(apply_context& context) {
auto update = context.msg.as<types::updateauth>();
EOS_ASSERT(!update.permission.empty(), message_validate_exception, "Cannot create authority with empty name");
EOS_ASSERT(validate(update.authority), message_validate_exception,
"Invalid authority: ${auth}", ("auth", update.authority));
if (update.permission == "active")
EOS_ASSERT(update.parent == "owner", message_validate_exception, "Cannot change active authority's parent");
if (update.permission == "owner")
EOS_ASSERT(update.parent.empty(), message_validate_exception, "Cannot change owner authority's parent");

auto& db = context.mutable_db;
context.require_authorization(update.account);

db.get<account_object, by_name>(update.account);
auto& parent = db.get<permission_object, by_owner>(boost::make_tuple(update.account, update.parent));
for (auto accountPermission : update.authority.accounts) {
db.get<account_object, by_name>(accountPermission.permission.account);
db.get<permission_object, by_owner>(boost::make_tuple(accountPermission.permission.account,
accountPermission.permission.permission));
}

const auto& permission = db.find<permission_object, by_owner>(boost::make_tuple(update.account, update.permission));
if (permission) {
db.modify(*permission, [&update, parent = parent.id](permission_object& po) {
po.auth = update.authority;
po.parent = parent;
});
} else {
db.create<permission_object>([&update, parent = parent.id](permission_object& po) {
po.name = update.permission;
po.owner = update.account;
po.auth = update.authority;
po.parent = parent;
});
}
}

void apply_eos_deleteauth(apply_context& context) {
auto remove = context.msg.as<types::deleteauth>();
EOS_ASSERT(remove.permission != "active", message_validate_exception, "Cannot delete active authority");
EOS_ASSERT(remove.permission != "owner", message_validate_exception, "Cannot delete owner authority");

auto& db = context.mutable_db;
context.require_authorization(remove.account);
const auto& permission = db.get<permission_object, by_owner>(boost::make_tuple(remove.account, remove.permission));

{ // Check for children
const auto& index = db.get_index<permission_index, by_parent>();
auto range = index.equal_range(permission.id);
EOS_ASSERT(range.first == range.second, message_precondition_exception,
"Cannot delete an authority which has children. Delete the children first");
}

{ // Check for links to this permission
const auto& index = db.get_index<permission_link_index, by_permission_name>();
auto range = index.equal_range(boost::make_tuple(remove.account, remove.permission));
EOS_ASSERT(range.first == range.second, message_precondition_exception,
"Cannot delete a linked authority. Unlink the authority first");
}

db.remove(permission);
}

void apply_eos_linkauth(apply_context& context) {
auto requirement = context.msg.as<types::linkauth>();

EOS_ASSERT(!requirement.requirement.empty(), message_validate_exception, "Required permission cannot be empty");

context.require_authorization(requirement.account);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ void apply_eos_okproducer(chain::apply_context&);
void apply_eos_setproducer(chain::apply_context&);
void apply_eos_setproxy(chain::apply_context&);
void apply_eos_setcode(chain::apply_context&);
void apply_eos_updateauth(chain::apply_context&);
void apply_eos_deleteauth(chain::apply_context&);
void apply_eos_linkauth(chain::apply_context&);
void apply_eos_unlinkauth(chain::apply_context&);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ void native_contract_chain_initializer::register_types(chain_controller& chain,
SET_APP_HANDLER( eos, eos, setproducer );
SET_APP_HANDLER( eos, eos, setproxy );
SET_APP_HANDLER( eos, eos, setcode );
SET_APP_HANDLER( eos, eos, updateauth );
SET_APP_HANDLER( eos, eos, deleteauth );
SET_APP_HANDLER( eos, eos, linkauth );
SET_APP_HANDLER( eos, eos, unlinkauth );
}
Expand Down
6 changes: 3 additions & 3 deletions libraries/types/types.eos
Original file line number Diff line number Diff line change
Expand Up @@ -116,17 +116,17 @@ struct setproxy
proxy AccountName # The account to cast votes with stakeholder's stake weight


struct UpdatePermission
struct updateauth
account AccountName
permission PermissionName
parent PermissionName
authority Authority

struct DeletePermission
struct deleteauth
account AccountName
permission PermissionName

struct linkauth
struct linkauth # Specify a particular required permission for account to approve specified message type
account AccountName # The account to require permissions for
code AccountName # The contract to require permissions to invoke
type FuncName
Expand Down

0 comments on commit 677869e

Please sign in to comment.