Skip to main content
Glama
mod.rs6.21 kB
use std::env; use indoc::indoc; use rand::{ Rng, distributions::Alphanumeric, thread_rng, }; use si_data_spicedb::{ Client, Error, Permission, Relationship, SpiceDBObject, SpiceDbConfig, }; const ENV_VAR_SPICEDB_URL: &str = "SI_TEST_SPICEDB_URL"; fn spicedb_config() -> SpiceDbConfig { let mut config = SpiceDbConfig::default(); #[allow(clippy::disallowed_methods)] // Used only in tests & so prefixed with `SI_TEST_` if let Ok(value) = env::var(ENV_VAR_SPICEDB_URL) { config.endpoint = value.parse().expect("failed to parse spicedb url"); } let mut rng = thread_rng(); let random_string: String = (0..12).map(|_| rng.sample(Alphanumeric) as char).collect(); config.preshared_key = random_string.into(); config } #[tokio::test] async fn write_and_read_schema() { let config = spicedb_config(); let mut client = Client::new(&config) .await .expect("failed to connect to spicedb"); let schema = indoc! {" // Plan comment definition plan {} definition user {} definition workspace { relation approver: user permission approve = approver } "}; client .write_schema(schema) .await .expect("failed to write schema"); let response = client.read_schema().await.expect("failed to read schema"); assert!( response .schema_text() .lines() .any(|line| line == "// Plan comment") ); assert!( response .schema_text() .lines() .any(|line| line == "definition plan {}") ); } #[tokio::test] async fn write_and_read_relationship() { let config = spicedb_config(); let mut client = Client::new(&config) .await .expect("failed to connect to spicedb"); let schema = indoc! {" // Plan comment definition plan {} definition user {} definition workspace { relation approver: user permission approve = approver } "}; client .write_schema(schema) .await .expect("failed to write schema"); let workspace_object = SpiceDBObject::new("workspace", "456".to_string()); let user_object = SpiceDBObject::new("user", "scott".to_string()); let mut scott_aprover_workspace = Relationship::new(workspace_object, "approver", user_object, None); let zed_token = client .create_relationships(vec![scott_aprover_workspace.clone()]) .await .expect("failed to create a relation"); scott_aprover_workspace.set_zed_token(zed_token); let resp = client .read_relationship(scott_aprover_workspace.clone()) .await .expect("failed to read relation"); assert!(resp.len() == 1); let zed_token = client .delete_relationships(vec![scott_aprover_workspace.clone()]) .await .expect("failed to delete relation"); scott_aprover_workspace.set_zed_token(zed_token); let resp = client .read_relationship(scott_aprover_workspace.clone()) .await .expect("failed to read relation"); assert!(resp.is_empty()); } #[tokio::test] async fn check_permissions() { let config = spicedb_config(); let mut client = Client::new(&config) .await .expect("failed to connect to spicedb"); let schema = indoc! {" // Plan comment definition plan {} definition user {} definition workspace { relation approver: user permission approve = approver } "}; client .write_schema(schema) .await .expect("failed to write schema"); let workspace_object = SpiceDBObject::new("workspace", "789".to_string()); let user_object = SpiceDBObject::new("user", "scott".to_string()); let user_object2 = SpiceDBObject::new("user", "fletcher".to_string()); let scott_aprover_workspace = Relationship::new( workspace_object.clone(), "approver", user_object.clone(), None, ); let zed_token = client .create_relationships(vec![scott_aprover_workspace.clone()]) .await .expect("failed to create a relation"); let perms = Permission::new( workspace_object.clone(), "approve", user_object.clone(), zed_token.clone(), ); let bad_perms = Permission::new(workspace_object, "approve", user_object2, zed_token); assert!( client .check_permissions(perms) .await .expect("failed to check permissions") ); assert!( !client .check_permissions(bad_perms) .await .expect("failed to check permissions") ); let users = client .lookup_subjects( "workspace".to_string(), "789".to_string(), "approve".to_string(), "user".to_string(), ) .await .expect("could not list subjects"); assert!(users.contains(&"scott".to_string())); assert!(!users.contains(&"fletcher".to_string())); } #[tokio::test] async fn test_client_connection_with_schema() { let config = spicedb_config(); let mut client = Client::new(&config) .await .expect("failed to connect to spicedb"); let schema = indoc! {" definition user {} "}; client .write_schema(schema) .await .expect("failed to write schema"); let result = Client::new(&config).await; assert!(result.is_ok()); } #[tokio::test] async fn test_client_connection_without_schema() { let config = spicedb_config(); let result = Client::new(&config).await; assert!(result.is_ok()); } #[tokio::test] async fn test_client_connection_failure() { let mut config = spicedb_config(); config.endpoint = "http://localhost:0".parse().expect("failed to parse URL"); let result = Client::new(&config).await; assert!(result.is_err()); match result { Err(Error::Connection(..)) => (), _ => panic!("Expected connection error"), } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server