surrealdb_core/iam/entities/
roles.rs

1use crate::iam::Error;
2use crate::sql::Ident;
3use cedar_policy::{Entity, EntityTypeName, EntityUid, RestrictedExpression};
4use revision::revisioned;
5use serde::{Deserialize, Serialize};
6use std::str::FromStr;
7
8// In the future, we will allow for custom roles. For now, provide predefined roles.
9#[revisioned(revision = 1)]
10#[derive(Hash, Copy, Clone, Default, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize)]
11#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
12#[non_exhaustive]
13pub enum Role {
14	#[default]
15	Viewer,
16	Editor,
17	Owner,
18}
19
20impl std::fmt::Display for Role {
21	fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
22		match self {
23			Self::Viewer => write!(f, "Viewer"),
24			Self::Editor => write!(f, "Editor"),
25			Self::Owner => write!(f, "Owner"),
26		}
27	}
28}
29
30impl FromStr for Role {
31	type Err = Error;
32	fn from_str(s: &str) -> Result<Self, Self::Err> {
33		match s.to_ascii_lowercase().as_str() {
34			"viewer" => Ok(Self::Viewer),
35			"editor" => Ok(Self::Editor),
36			"owner" => Ok(Self::Owner),
37			_ => Err(Error::InvalidRole(s.to_string())),
38		}
39	}
40}
41
42impl std::convert::TryFrom<&Ident> for Role {
43	type Error = Error;
44	fn try_from(id: &Ident) -> Result<Self, Self::Error> {
45		Role::from_str(id)
46	}
47}
48
49impl std::convert::From<Role> for Ident {
50	fn from(role: Role) -> Self {
51		role.to_string().into()
52	}
53}
54
55impl std::convert::From<&Role> for EntityUid {
56	fn from(role: &Role) -> Self {
57		EntityUid::from_type_name_and_id(
58			EntityTypeName::from_str("Role").unwrap(),
59			format!("{}", role).parse().unwrap(),
60		)
61	}
62}
63
64impl std::convert::From<&Role> for Entity {
65	fn from(role: &Role) -> Self {
66		Entity::new(role.into(), Default::default(), Default::default())
67	}
68}
69
70impl std::convert::From<&Role> for RestrictedExpression {
71	fn from(role: &Role) -> Self {
72		format!("{}", EntityUid::from(role)).parse().unwrap()
73	}
74}