cw_auth_types/
sessions.rs1use std::str::FromStr;
2
3use actions::SessionActionName;
4use saa_schema::saa_type;
5use smart_account_auth::{cosmwasm_std::Env, ensure, msgs::{AllowedActions, ActionDerivation}, CredentialId, CredentialRecord, Expiration};
6use strum::IntoEnumIterator;
7use crate::errors::SessionError;
8
9
10pub mod queries;
11pub mod actions;
12
13type GranteeInfo = CredentialRecord;
14
15#[saa_type]
16pub struct SessionInfo {
17 pub grantee : GranteeInfo,
18 pub granter : Option<CredentialId>,
19 pub expiration : Option<Expiration>,
20}
21
22
23
24
25impl SessionInfo {
26 pub fn checked_params(
27 &self,
28 env: &Env,
29 actions: Option<&AllowedActions>
30 ) -> Result<(CredentialId, CredentialRecord, Expiration, AllowedActions), SessionError> {
31 let granter = self.granter.clone().unwrap_or_default();
32 let (id, info) = self.grantee.clone();
33 ensure!(!id.is_empty(), SessionError::InvalidGrantee);
34 let expiration = self.expiration.clone().unwrap_or_default();
35 ensure!(!expiration.is_expired(&env.block), SessionError::Expired);
36 if let Some(granter) = &self.granter {
37 ensure!(!granter.is_empty() && *granter != id, SessionError::InvalidGranter);
38 }
39 let actions : AllowedActions = match actions {
40 Some(actions) => {
41 if let AllowedActions::Include(ref actions) = actions {
42 ensure!(actions.len() > 0, SessionError::EmptyCreateActions);
43
44 let validity_ok = actions
45 .iter()
46 .enumerate()
47 .all(|(i, action)| {
48 let ok = !action.result.is_empty()
49 && actions
50 .into_iter()
51 .skip(i + 1)
52 .filter(|action2| action == *action2)
53 .count() == 0;
54 ok
55 });
56 ensure!(validity_ok, SessionError::InvalidActions);
57
58 let no_inner_sessions = actions
59 .iter()
60 .all(|action| {
61 match action.method {
62 ActionDerivation::Json => !action.result.contains("\"session_actions\"") &&
63 !action.result.contains("\"session_info\""),
64
65 _ => !is_session_action_name(action.result.as_str())
66
67 }
68 });
69
70 ensure!(no_inner_sessions, SessionError::InnerSessionAction);
71 }
72 actions.clone()
73 },
74 None => AllowedActions::All {},
75 };
76 Ok((granter, (id, info), expiration, actions))
77 }
78}
79
80
81
82pub(crate) fn is_session_action_name(name: &str) -> bool {
83 SessionActionName::iter()
84 .any(|action| {
85 if action.as_ref() == name {
86 return true;
87 }
88 if let Ok(act) = SessionActionName::from_str(name) {
89 return action == act;
90 }
91 false
92 })
93}