oasis_runtime_sdk/modules/access/
mod.rs

1//! Method access control module.
2use once_cell::unsync::Lazy;
3use thiserror::Error;
4
5use crate::{
6    context::Context,
7    module::{self, Module as _},
8    modules, sdk_derive,
9    state::CurrentState,
10    types::transaction,
11};
12
13#[cfg(test)]
14mod test;
15pub mod types;
16
17/// Unique module name.
18const MODULE_NAME: &str = "access";
19
20/// Errors emitted by the access module.
21#[derive(Error, Debug, oasis_runtime_sdk_macros::Error)]
22pub enum Error {
23    #[error("caller is not authorized to call method")]
24    #[sdk_error(code = 1)]
25    NotAuthorized,
26}
27
28/// Module configuration.
29#[allow(clippy::declare_interior_mutable_const)]
30pub trait Config: 'static {
31    /// To filter methods by caller address, add them to this mapping.
32    ///
33    /// If the mapping is empty, no method is filtered.
34    const METHOD_AUTHORIZATIONS: Lazy<types::Authorization> = Lazy::new(types::Authorization::new);
35}
36
37/// The method access control module.
38pub struct Module<Cfg: Config> {
39    _cfg: std::marker::PhantomData<Cfg>,
40}
41
42#[sdk_derive(Module)]
43impl<Cfg: Config> Module<Cfg> {
44    const NAME: &'static str = MODULE_NAME;
45    const VERSION: u32 = 1;
46    type Error = Error;
47    type Event = ();
48    type Parameters = ();
49    type Genesis = ();
50}
51
52impl<Cfg: Config> module::TransactionHandler for Module<Cfg> {
53    fn before_authorized_call_dispatch<C: Context>(
54        _ctx: &C,
55        call: &transaction::Call,
56    ) -> Result<(), modules::core::Error> {
57        let tx_caller_address = CurrentState::with_env(|env| env.tx_caller_address());
58        #[allow(clippy::borrow_interior_mutable_const)]
59        if Cfg::METHOD_AUTHORIZATIONS.is_authorized(&call.method, &tx_caller_address) {
60            Ok(())
61        } else {
62            Err(modules::core::Error::InvalidArgument(
63                Error::NotAuthorized.into(),
64            ))
65        }
66    }
67}
68
69impl<Cfg: Config> module::BlockHandler for Module<Cfg> {}
70
71impl<Cfg: Config> module::InvariantHandler for Module<Cfg> {}