Skip to content

Commit

Permalink
Add fn acl_get_super_admins to trait AccessControllable (Near-One#29)
Browse files Browse the repository at this point in the history
* Add `AccessControllable::acl_get_super_admins`

* Add `test_acl_get_super_admins`
  • Loading branch information
mooori authored Oct 24, 2022
1 parent daf706e commit 5579de4
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 1 deletion.
8 changes: 8 additions & 0 deletions near-plugins-derive/src/access_controllable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,14 @@ pub fn access_controllable(attrs: TokenStream, item: TokenStream) -> TokenStream
self.#acl_field.has_any_role(roles, &account_id)
}

fn acl_get_super_admins(&self, skip: u64, limit: u64) -> Vec<::near_sdk::AccountId> {
let permission = <#bitflags_type>::from_bits(
<#role_type>::acl_super_admin_permission()
)
.unwrap_or_else(|| ::near_sdk::env::panic_str(#ERR_PARSE_BITFLAG));
self.#acl_field.get_bearers(permission, skip, limit)
}

fn acl_get_admins(&self, role: String, skip: u64, limit: u64) -> Vec<::near_sdk::AccountId> {
let role: #role_type = ::std::convert::TryFrom::try_from(role.as_str()).unwrap_or_else(|_| ::near_sdk::env::panic_str(#ERR_PARSE_ROLE));
let permission = <#bitflags_type>::from_bits(role.acl_admin_permission())
Expand Down
6 changes: 5 additions & 1 deletion near-plugins/src/access_controllable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ pub trait AccessControllable {
/// Returns whether `account_id` has been granted any of the `roles`.
fn acl_has_any_role(&self, roles: Vec<String>, account_id: AccountId) -> bool;

/// Enables paginated retrieval of admins of `role`. It returns upt to
/// Enables paginated retrieval of super-admins. It returns up to `limit`
/// super-admins and skips the first `skip` super-admins.
fn acl_get_super_admins(&self, skip: u64, limit: u64) -> Vec<AccountId>;

/// Enables paginated retrieval of admins of `role`. It returns up to
/// `limit` admins and skips the first `skip` admins.
fn acl_get_admins(&self, role: String, skip: u64, limit: u64) -> Vec<AccountId>;

Expand Down
70 changes: 70 additions & 0 deletions near-plugins/tests/access_controllable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,76 @@ async fn test_acl_init_super_admin_is_private() -> anyhow::Result<()> {
Ok(())
}

#[tokio::test]
async fn test_acl_get_super_admins() -> anyhow::Result<()> {
let setup = Setup::new().await?;

let super_admin_ids = vec![
setup.new_super_admin_account().await?,
setup.new_super_admin_account().await?,
setup.new_super_admin_account().await?,
]
.iter()
.map(|account| account.id().clone())
.collect::<Vec<_>>();

// Behaves as expected for limit = 0.
let actual = setup
.contract
.acl_get_super_admins(setup.account.clone().into(), 0, 0)
.await?;
assert_eq!(actual, vec![],);

// Skip outside of the number of existing super-admins.
let n = u64::try_from(super_admin_ids.len()).unwrap();
let actual = setup
.contract
.acl_get_super_admins(setup.account.clone().into(), n, 1)
.await?;
assert_eq!(actual, vec![],);

// Retrieve super-admins with step size 1.
for i in 0..3 {
let actual = setup
.contract
.acl_get_super_admins(setup.account.clone().into(), i, 1)
.await?;
let i = usize::try_from(i).unwrap();
let expected = super_admin_ids[i..i + 1].to_vec();
assert_eq!(actual, expected, "Mismatch at position {}", i,);
}

// Retrieve super-admins with step size 2.
let actual = setup
.contract
.acl_get_super_admins(setup.account.clone().into(), 0, 2)
.await?;
let expected = super_admin_ids[0..2].to_vec();
assert_eq!(actual, expected);
let actual = setup
.contract
.acl_get_super_admins(setup.account.clone().into(), 2, 2)
.await?;
let expected = vec![super_admin_ids[2].clone()];
assert_eq!(actual, expected);

// Retrieve all super-admins at once.
let actual = setup
.contract
.acl_get_super_admins(setup.account.clone().into(), 0, 3)
.await?;
assert_eq!(actual, super_admin_ids);

// Limit larger than the number of existing super-admins.
let actual = setup
.contract
.acl_get_super_admins(setup.account.clone().into(), 0, 4)
.await?;
assert_eq!(actual, super_admin_ids);

Ok(())
}

#[tokio::test]
async fn test_acl_get_admins() -> anyhow::Result<()> {
let setup = Setup::new().await?;
Expand Down
21 changes: 21 additions & 0 deletions near-plugins/tests/common/access_controllable_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,27 @@ impl AccessControllableContract {
.await
}

pub async fn acl_get_super_admins(
&self,
caller: Caller,
skip: u64,
limit: u64,
) -> anyhow::Result<Vec<AccountId>> {
let res = self
.account(caller)
.call(self.contract.id(), "acl_get_super_admins")
.args_json(json!({
"skip": skip,
"limit": limit,
}))
.max_gas()
.transact()
.await?
.into_result()?
.json::<Vec<AccountId>>()?;
Ok(res)
}

pub async fn acl_get_admins(
&self,
caller: Caller,
Expand Down

0 comments on commit 5579de4

Please sign in to comment.