use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum AuthConfigStatus {
Enabled,
Disabled,
}
impl AuthConfigStatus {
pub fn as_str(self) -> &'static str {
match self {
Self::Enabled => "ENABLED",
Self::Disabled => "DISABLED",
}
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct AuthConfigListParams {
#[serde(skip_serializing_if = "Option::is_none")]
pub is_composio_managed: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub toolkit_slug: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub show_disabled: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub search: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cursor: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthConfigListResponse {
pub items: Vec<AuthConfigInfo>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_cursor: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub total_pages: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub current_page: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub total_items: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthConfigInfo {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub uuid: Option<String>,
#[serde(rename = "type")]
pub config_type: String,
pub toolkit: ToolkitInfo,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub auth_scheme: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub credentials: Option<serde_json::Value>,
pub status: String,
pub created_at: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub no_of_connections: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tool_access_config: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolkitInfo {
pub slug: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthConfigCreateParams {
pub toolkit: String,
pub options: AuthConfigOptions,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum AuthConfigOptions {
#[serde(rename = "custom")]
Custom {
auth_scheme: String,
credentials: serde_json::Value,
#[serde(skip_serializing_if = "Option::is_none")]
restrict_to_following_tools: Option<Vec<String>>,
},
#[serde(rename = "default")]
Default {
#[serde(skip_serializing_if = "Option::is_none")]
scopes: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
user_scopes: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
restrict_to_following_tools: Option<Vec<String>>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthConfigCreateResponse {
pub auth_config: AuthConfig,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthConfig {
pub id: String,
pub toolkit: ToolkitInfo,
pub auth_scheme: String,
pub is_composio_managed: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub restrict_to_following_tools: Option<Vec<String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthConfigRetrieveResponse {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub uuid: Option<String>,
#[serde(rename = "type")]
pub config_type: String,
pub toolkit: ToolkitInfo,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
pub auth_scheme: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub credentials: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub proxy_config: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub expected_input_fields: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub shared_credentials: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum AuthConfigUpdateParams {
#[serde(rename = "custom")]
Custom {
#[serde(skip_serializing_if = "Option::is_none")]
credentials: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
proxy_config: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
tool_access_config: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
shared_credentials: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
is_enabled_for_tool_router: Option<bool>,
},
#[serde(rename = "default")]
Default {
#[serde(skip_serializing_if = "Option::is_none")]
credentials: Option<DefaultCredentials>,
#[serde(skip_serializing_if = "Option::is_none")]
is_enabled_for_tool_router: Option<bool>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DefaultCredentials {
#[serde(skip_serializing_if = "Option::is_none")]
pub scopes: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub user_scopes: Option<Vec<String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthConfigUpdateResponse {
pub success: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub auth_config: Option<AuthConfigInfo>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthConfigDeleteResponse {
pub success: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthConfigStatusUpdateResponse {
pub success: bool,
pub status: String,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_auth_config_list_params_default() {
let params = AuthConfigListParams::default();
assert!(params.is_composio_managed.is_none());
assert!(params.toolkit_slug.is_none());
}
#[test]
fn test_auth_config_options_custom_serialization() {
let options = AuthConfigOptions::Custom {
auth_scheme: "OAUTH2".to_string(),
credentials: serde_json::json!({"client_id": "test"}),
restrict_to_following_tools: None,
};
let json = serde_json::to_string(&options).unwrap();
assert!(json.contains("custom"));
assert!(json.contains("OAUTH2"));
}
#[test]
fn test_auth_config_status_serialization() {
let enabled = AuthConfigStatus::Enabled;
let json = serde_json::to_string(&enabled).unwrap();
assert_eq!(json, "\"ENABLED\"");
assert_eq!(enabled.as_str(), "ENABLED");
}
#[test]
fn test_auth_config_update_response_deserialization() {
let payload = r#"{"success":true}"#;
let response: AuthConfigUpdateResponse = serde_json::from_str(payload).unwrap();
assert!(response.success);
}
#[test]
fn test_auth_config_delete_response_deserialization() {
let payload = r#"{"success":true,"message":"deleted"}"#;
let response: AuthConfigDeleteResponse = serde_json::from_str(payload).unwrap();
assert!(response.success);
assert_eq!(response.message.as_deref(), Some("deleted"));
}
#[test]
fn test_auth_config_status_update_response_deserialization() {
let payload = r#"{"success":true,"status":"DISABLED"}"#;
let response: AuthConfigStatusUpdateResponse = serde_json::from_str(payload).unwrap();
assert!(response.success);
assert_eq!(response.status, "DISABLED");
}
#[test]
fn test_auth_config_options_default_serialization() {
let options = AuthConfigOptions::Default {
scopes: Some(vec!["repo".to_string()]),
user_scopes: None,
restrict_to_following_tools: None,
};
let json = serde_json::to_string(&options).unwrap();
assert!(json.contains("default"));
assert!(json.contains("repo"));
}
}