Skip to content

Commit

Permalink
feat: add Acl introspection of role variants (Near-One#75)
Browse files Browse the repository at this point in the history
* Add `AccessControlRole::acl_role_variants`

* Add `AccessControllable::acl_role_variants`

* Make acl_role_variants available in view calls

* Add test
  • Loading branch information
mooori authored Jan 26, 2023
1 parent 1cf0aa6 commit 1fcc95c
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 0 deletions.
6 changes: 6 additions & 0 deletions near-plugins-derive/src/access_control_role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ pub fn derive_access_control_role(input: TokenStream) -> TokenStream {
}

impl AccessControlRole for #ident {
fn acl_role_variants() -> Vec<&'static str> {
vec![
#(#variant_names,)*
]
}

fn acl_super_admin_permission() -> u128 {
// See module documentation.
1 // corresponds to safe_leftshift(1, 0)
Expand Down
4 changes: 4 additions & 0 deletions near-plugins-derive/src/access_controllable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,10 @@ pub fn access_controllable(attrs: TokenStream, item: TokenStream) -> TokenStream
self.#acl_field.init_super_admin(&account_id)
}

fn acl_role_variants(&self) -> Vec<&'static str> {
<#role_type>::acl_role_variants()
}

fn acl_is_super_admin(&self, account_id: ::near_sdk::AccountId) -> bool {
self.#acl_field.is_super_admin(&account_id)
}
Expand Down
3 changes: 3 additions & 0 deletions near-plugins/src/access_control_role.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
/// Represents permissions for the [`AccessControllable`](crate::AccessControllable) plugin.
pub trait AccessControlRole {
/// Returns the names of all role variants.
fn acl_role_variants() -> Vec<&'static str>;

/// Returns the bitflag corresponding to the super admin permission.
fn acl_super_admin_permission() -> u128;

Expand Down
17 changes: 17 additions & 0 deletions near-plugins/src/access_controllable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,23 @@ pub trait AccessControllable {
/// ```
fn acl_storage_prefix() -> &'static [u8];

/// Returns the names of all variants of the enum that represents roles.
///
/// In the default implementation provided by this crate, this enum is defined by contract
/// developers using the plugin and passed as an attribute to the `access_controllable` macro.
///
/// A vector containing _all_ variant names is returned since the default implementation limits
/// the number of variants to [`near_plugins_derive::access_control_role::MAX_ROLE_VARIANTS`].
/// This allows for a simpler user experience compared to the iterator based approach of
/// [`Self::acl_get_admins`], for example. For custom implmentations of this it is advised to
/// limit the number of role variants as well.
///
/// Event though it might not be used, this method takes paramter `&self` to be [available in
/// view calls].
///
/// [available in view calls]: https://stackoverflow.com/q/66715815
fn acl_role_variants(&self) -> Vec<&'static str>;

/// Adds `account_id` as super-admin __without__ checking any permissions in
/// case there are no super-admins. If there is already a super-admin, it
/// has no effect. This function can be used to add a super-admin during
Expand Down
8 changes: 8 additions & 0 deletions near-plugins/tests/access_controllable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,14 @@ async fn test_acl_initialization_in_constructor() -> anyhow::Result<()> {
Ok(())
}

#[tokio::test]
async fn test_acl_role_variants() -> anyhow::Result<()> {
let setup = Setup::new().await?;
let variants = setup.contract.acl_role_variants(&setup.account).await?;
assert_eq!(variants, ALL_ROLES);
Ok(())
}

#[tokio::test]
async fn test_acl_is_super_admin() -> anyhow::Result<()> {
let Setup {
Expand Down
8 changes: 8 additions & 0 deletions near-plugins/tests/common/access_controllable_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ impl AccessControllableContract {
&self.contract
}

pub async fn acl_role_variants(&self, caller: &Account) -> anyhow::Result<Vec<String>> {
let res = caller
.call(self.contract.id(), "acl_role_variants")
.view()
.await?;
Ok(res.json::<Vec<String>>()?)
}

pub async fn acl_is_super_admin(
&self,
caller: &Account,
Expand Down

0 comments on commit 1fcc95c

Please sign in to comment.