Skip to main content
Glama
mod.rs4.22 kB
use std::collections::HashMap; use axum::{ Router, extract::rejection::JsonRejection, http::StatusCode, response::IntoResponse, routing::{ delete, get, post, put, }, }; use dal::{ PublicKey, SecretId, }; use serde::Deserialize; use sodiumoxide::crypto::sealedbox; use thiserror::Error; use utoipa::ToSchema; use crate::AppState; pub mod create_secret; pub mod delete_secret; pub mod get_secrets; pub mod update_secret; #[remain::sorted] #[derive(Debug, Error)] pub enum SecretsError { #[error("can't delete a secret with components connected: {0}")] CantDeleteSecret(SecretId), #[error("keypair error: {0}")] KeyPair(#[from] dal::KeyPairError), #[error("changes not permitted on HEAD change set")] NotPermittedOnHead, #[error("secret error: {0}")] Secret(#[from] dal::SecretError), #[error("secret definition view error: {0}")] SecretDefinitionView(#[from] dal::SecretDefinitionViewError), #[error("secret not found: {0}")] SecretNotFound(SecretId), #[error("definition not found for secret: {0}")] SecretWithInvalidDefinition(SecretId), #[error("transactions error: {0}")] Transactions(#[from] dal::TransactionsError), #[error("validation error: {0}")] Validation(String), #[error("ws event error: {0}")] WsEvent(#[from] dal::WsEventError), } pub type SecretsResult<T> = Result<T, SecretsError>; #[derive(Deserialize, ToSchema)] pub struct SecretV1RequestPath { #[schema(value_type = String)] pub secret_id: SecretId, } impl IntoResponse for SecretsError { fn into_response(self) -> axum::response::Response { use crate::service::v1::common::ErrorIntoResponse; self.to_api_response() } } impl From<JsonRejection> for SecretsError { fn from(rejection: JsonRejection) -> Self { match rejection { JsonRejection::JsonDataError(_) => { SecretsError::Validation(format!("Invalid JSON data format: {rejection}")) } JsonRejection::JsonSyntaxError(_) => { SecretsError::Validation(format!("Invalid JSON syntax: {rejection}")) } JsonRejection::MissingJsonContentType(_) => SecretsError::Validation( "Request must have Content-Type: application/json header".to_string(), ), _ => SecretsError::Validation(format!("JSON validation error: {rejection}")), } } } impl crate::service::v1::common::ErrorIntoResponse for SecretsError { fn status_and_message(&self) -> (StatusCode, String) { match self { SecretsError::Secret(dal::SecretError::SecretNotFound(_)) => { (StatusCode::NOT_FOUND, self.to_string()) } SecretsError::SecretNotFound(_) => (StatusCode::NOT_FOUND, self.to_string()), SecretsError::NotPermittedOnHead => (StatusCode::BAD_REQUEST, self.to_string()), SecretsError::SecretWithInvalidDefinition(_) => { (StatusCode::NOT_FOUND, self.to_string()) } SecretsError::CantDeleteSecret(_) => (StatusCode::CONFLICT, self.to_string()), SecretsError::Validation(_) => (StatusCode::UNPROCESSABLE_ENTITY, self.to_string()), _ => (StatusCode::INTERNAL_SERVER_ERROR, self.to_string()), } } } pub fn routes() -> Router<AppState> { Router::new() .route("/", get(get_secrets::get_secrets)) .route("/", post(create_secret::create_secret)) .nest( "/:secret_id", Router::new() .route("/", delete(delete_secret::delete_secret)) .route("/", put(update_secret::update_secret)), ) } pub async fn encrypt_message(message: HashMap<String, String>, public_key: &PublicKey) -> Vec<u8> { sodiumoxide::init().expect("Failed to initialize sodiumoxide"); let box_public_key = public_key.public_key(); let serialized = serialize_message(&message); sealedbox::seal(&serialized, box_public_key) } fn serialize_message(message: &HashMap<String, String>) -> Vec<u8> { serde_json::to_vec(message).expect("Failed to serialize message") }

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