oasis_runtime_sdk/modules/access/
types.rs

1//! Method access control module types.
2use std::collections::{BTreeMap, BTreeSet};
3
4use crate::types::address::Address;
5
6/// A set of addresses that can be used to define access control for a particular method.
7pub type Addresses = BTreeSet<Address>;
8
9/// A specific kind of method authorization.
10pub enum MethodAuthorization {
11    /// Only allow method calls from these addresses;
12    /// for other callers, the method call will fail.
13    AllowFrom(Addresses),
14}
15
16impl MethodAuthorization {
17    /// Helper for creating a method authorization type that
18    /// only allows callers with the given addresses.
19    pub fn allow_from<I: IntoIterator<Item = Address>>(it: I) -> Self {
20        Self::AllowFrom(BTreeSet::from_iter(it))
21    }
22
23    pub(super) fn is_authorized(&self, address: &Address) -> bool {
24        match self {
25            Self::AllowFrom(addrs) => addrs.contains(address),
26        }
27    }
28}
29
30/// A set of methods that are subject to access control.
31pub type Methods = BTreeMap<String, MethodAuthorization>;
32
33/// A specific kind of access control.
34pub enum Authorization {
35    /// Control a statically configured set of methods, each with a
36    /// statically configured set of addresses that are allowed to call it.
37    FilterOnly(Methods),
38}
39
40impl Authorization {
41    /// Return a new access control configuration.
42    pub fn new() -> Self {
43        Self::FilterOnly(BTreeMap::new())
44    }
45
46    /// Helper for creating a static access control configuration.
47    pub fn with_filtered_methods<S, I>(it: I) -> Self
48    where
49        S: AsRef<str>,
50        I: IntoIterator<Item = (S, MethodAuthorization)>,
51    {
52        Self::FilterOnly(BTreeMap::from_iter(
53            it.into_iter()
54                .map(|(name, authz)| (name.as_ref().to_string(), authz)),
55        ))
56    }
57
58    pub(super) fn is_authorized(&self, method: &str, address: &Address) -> bool {
59        match self {
60            Self::FilterOnly(meths) => meths
61                .get(method)
62                .map(|authz| authz.is_authorized(address))
63                .unwrap_or(true),
64        }
65    }
66}
67
68impl Default for Authorization {
69    fn default() -> Self {
70        Self::FilterOnly(BTreeMap::default())
71    }
72}