Skip to content

Commit

Permalink
feat: enforce only Admin can call Admin systems
Browse files Browse the repository at this point in the history
  • Loading branch information
ftupas committed Jun 12, 2023
1 parent ed0d240 commit e542453
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 15 deletions.
9 changes: 7 additions & 2 deletions crates/dojo-core/src/auth/systems.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,13 @@ mod IsAuthorized {
// If system is not authorized, get World level role
let role = commands::<AuthRole>::entity(target_id.into());

// Check if system's role is Admin
role.id.into() == 'Admin'
// Check if system's role is Admin and executed by an Admin
if role.id.into() == 'Admin' {
assert(ctx.execution_role.id.into() == 'Admin', 'Unauthorized Admin call');
true
} else {
false
}
}
}

Expand Down
42 changes: 29 additions & 13 deletions crates/dojo-core/tests/src/world.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -380,9 +380,8 @@ fn test_set_entity_admin() {
}

#[test]
#[available_gas(9000000)]
#[available_gas(10000000)]
#[should_panic]
#[ignore] // TODO:: Remove once set_caller_address is working properly
fn test_admin_system_but_non_admin_caller() {
// Spawn empty world
let world = spawn_empty_world();
Expand All @@ -404,14 +403,27 @@ fn test_admin_system_but_non_admin_caller() {
world.assume_role('Admin'.into(), systems);
world.execute('GrantAuthRole'.into(), grant_role_calldata.span());

// Call Bar system
// Admin revokes its Admin role
let mut grant_role_calldata: Array<felt252> = ArrayTrait::new();
let caller: felt252 = get_caller_address().into();
grant_role_calldata.append(caller); // target_id
world.execute('RevokeAuthRole'.into(), grant_role_calldata.span());
let role = world.entity('AuthRole'.into(), QueryTrait::new_from_id(caller.into()), 0, 0);
assert(*role[0] == 0, 'role not revoked');

// Clear execution role
let systems = ArrayTrait::new();
world.clear_role(systems);

// Non-admin now Call Bar system
let mut data = ArrayTrait::new();
data.append(420);
data.append(1337);

// Non-admin tries to call Admin Bar system
starknet::testing::set_caller_address(contract_address_const::<0x1337>());
world.execute('Bar'.into(), data.span());
// Non-admin assume Bar system that has Admin role
let mut systems = ArrayTrait::<ShortString>::new();
systems.append('Bar'.into());
world.assume_role('Bar'.into(), systems);
}

#[test]
Expand Down Expand Up @@ -735,7 +747,6 @@ fn test_assume_admin_role_by_admin() {
#[test]
#[available_gas(5000000)]
#[should_panic]
#[ignore] // TODO:: Remove once set_caller_address is working properly
fn test_assume_admin_role_by_non_admin() {
// Spawn empty world
let world = spawn_empty_world();
Expand All @@ -746,13 +757,18 @@ fn test_assume_admin_role_by_non_admin() {
// Initialize world
world.initialize(route);

// Assume Admin role by Non-admin
let mut systems = ArrayTrait::<ShortString>::new();
starknet::testing::set_caller_address(starknet::contract_address_const::<0x420>());
world.assume_role(World::ADMIN.into(), systems);
// Admin revokes its Admin role
let mut grant_role_calldata: Array<felt252> = ArrayTrait::new();
let caller: felt252 = get_caller_address().into();
grant_role_calldata.append(caller); // target_id
world.execute('RevokeAuthRole'.into(), grant_role_calldata.span());
let role = world.entity('AuthRole'.into(), QueryTrait::new_from_id(caller.into()), 0, 0);
assert(*role[0] == 0, 'role not revoked');

// Check that role is assumed
assert(world.execution_role() == World::ADMIN.into(), 'role not assumed');
// Non-admin assume Bar system that has Admin role
// Should panic since caller is not admin anymore
let mut systems = ArrayTrait::<ShortString>::new();
world.assume_role('Bar'.into(), systems);
}

// Utils
Expand Down

0 comments on commit e542453

Please sign in to comment.