1use crate::{
2 Error, ThisError, access::AccessError, cdk::api::canister_self, ops::runtime::env::EnvOps,
3};
4
5#[derive(Debug, ThisError)]
10pub enum EnvAccessError {
11 #[error("this endpoint is only available on the prime subnet")]
12 NotPrimeSubnet,
13
14 #[error("this endpoint is only available on prime root")]
15 NotPrimeRoot,
16
17 #[error("operation must be called from the root canister")]
18 NotRoot,
19
20 #[error("operation cannot be called from the root canister")]
21 IsRoot,
22}
23
24impl From<EnvAccessError> for Error {
25 fn from(err: EnvAccessError) -> Self {
26 AccessError::Env(err).into()
27 }
28}
29
30#[allow(clippy::unused_async)]
35pub async fn is_prime_root() -> Result<(), AccessError> {
36 if EnvOps::is_prime_root() {
37 Ok(())
38 } else {
39 Err(EnvAccessError::NotPrimeRoot.into())
40 }
41}
42
43#[allow(clippy::unused_async)]
44pub async fn is_prime_subnet() -> Result<(), AccessError> {
45 if EnvOps::is_prime_subnet() {
46 Ok(())
47 } else {
48 Err(EnvAccessError::NotPrimeSubnet.into())
49 }
50}
51
52pub(crate) fn require_root() -> Result<(), Error> {
54 let root_pid = EnvOps::root_pid()?;
55
56 if root_pid == canister_self() {
57 Ok(())
58 } else {
59 Err(EnvAccessError::NotRoot.into())
60 }
61}
62
63pub(crate) fn deny_root() -> Result<(), Error> {
65 let root_pid = EnvOps::root_pid()?;
66
67 if root_pid == canister_self() {
68 Err(EnvAccessError::IsRoot.into())
69 } else {
70 Ok(())
71 }
72}