pallet_permission0/ext/
namespace_impl.rs1use crate::{
2 generate_permission_id, permission::NamespaceScope, update_permission_indices, Config, Error,
3 Event, Pallet, PermissionContract, PermissionDuration, PermissionId, PermissionScope,
4 Permissions, PermissionsByGrantor, RevocationTerms,
5};
6use pallet_permission0_api::Permission0NamespacesApi;
7use pallet_torus0_api::{NamespacePath, NamespacePathInner, Torus0Api};
8use polkadot_sdk::{
9 frame_support::ensure,
10 frame_system::{self, ensure_signed},
11 polkadot_sdk_frame::prelude::OriginFor,
12 sp_runtime::{BoundedBTreeSet, DispatchError},
13 sp_std::collections::btree_set::BTreeSet,
14};
15
16impl<T: Config> Permission0NamespacesApi<T::AccountId, NamespacePath> for Pallet<T> {
17 fn is_delegating_namespace(grantor: &T::AccountId, path: &NamespacePath) -> bool {
18 PermissionsByGrantor::<T>::get(grantor).iter().any(|id| {
19 Permissions::<T>::get(id)
20 .filter(|permission| {
21 if let PermissionScope::Namespace(scope) = &permission.scope {
22 for p in &scope.paths {
23 if p == path || path.is_parent_of(p) {
24 return true;
25 }
26 }
27 }
28
29 false
30 })
31 .is_some()
32 })
33 }
34}
35
36pub fn grant_namespace_permission_impl<T: Config>(
37 grantor: OriginFor<T>,
38 grantee: T::AccountId,
39 paths: BoundedBTreeSet<NamespacePathInner, T::MaxNamespacesPerPermission>,
40 duration: PermissionDuration<T>,
41 revocation: RevocationTerms<T>,
42) -> Result<PermissionId, DispatchError> {
43 let grantor = ensure_signed(grantor)?;
44
45 let paths = paths
46 .into_iter()
47 .map(|path| {
48 let path =
49 NamespacePath::new_agent(&path).map_err(|_| Error::<T>::NamespacePathIsInvalid)?;
50 ensure!(
51 T::Torus::namespace_exists(&grantor, &path),
52 Error::<T>::NamespaceDoesNotExist
53 );
54
55 Ok(path)
56 })
57 .collect::<Result<BTreeSet<NamespacePath>, DispatchError>>()?;
58 let paths = paths
59 .try_into()
60 .map_err(|_| Error::<T>::NamespacePathIsInvalid)?;
61
62 let scope = PermissionScope::Namespace(NamespaceScope { paths });
63 let permission_id = generate_permission_id::<T>(&grantor, &grantee, &scope)?;
64
65 let contract = PermissionContract {
66 grantor,
67 grantee,
68 scope,
69 duration,
70 revocation,
71 enforcement: crate::EnforcementAuthority::None,
72 last_execution: None,
73 execution_count: 0,
74 parent: None,
76 created_at: <frame_system::Pallet<T>>::block_number(),
77 };
78
79 Permissions::<T>::insert(permission_id, &contract);
80 update_permission_indices::<T>(&contract.grantor, &contract.grantee, permission_id)?;
81
82 <Pallet<T>>::deposit_event(Event::PermissionGranted {
83 grantor: contract.grantor,
84 grantee: contract.grantee,
85 permission_id,
86 });
87
88 Ok(permission_id)
89}