claude_code_toolkit/providers/mod.rs
1//! External service provider integrations for credential synchronization.
2//!
3//! This module contains provider implementations for various external services
4//! like GitHub, following the Repository Pattern and Dependency Injection principles.
5//! Providers handle secure credential synchronization, API interactions, and
6//! service-specific configuration management.
7//!
8//! ## Supported Providers
9//!
10//! - [`github`] - GitHub API integration for repository and organization sync
11//! - [`registry`] - Provider registry management and factory patterns
12//!
13//! ## Provider Architecture
14//!
15//! The provider system uses several design patterns:
16//!
17//! - **Factory Pattern**: [`ProviderFactory`] creates providers dynamically
18//! - **Repository Pattern**: Providers implement [`SecretProvider`] trait
19//! - **Dependency Injection**: Providers receive configuration via constructor
20//!
21//! ## Usage Examples
22//!
23//! ### Using the Provider Factory
24//!
25//! ```rust,no_run
26//! use claude_code_toolkit::providers::ProviderFactory;
27//! use std::collections::HashMap;
28//!
29//! #[tokio::main]
30//! async fn main() -> claude_code_toolkit::Result<()> {
31//! let factory = ProviderFactory::new();
32//!
33//! // List available providers
34//! let providers = factory.available_providers();
35//! println!("Available providers: {:?}", providers);
36//!
37//! // Create a GitHub provider
38//! let mut config = HashMap::new();
39//! config.insert("token".to_string(), "your-github-token".to_string());
40//! config.insert("org".to_string(), "your-org".to_string());
41//!
42//! let provider = factory.create("github", &config)?;
43//! // Use provider for operations...
44//!
45//! Ok(())
46//! }
47//! ```
48//!
49//! ### Direct Provider Usage
50//!
51//! ```rust,no_run
52//! use claude_code_toolkit::providers::github::GitHubProvider;
53//! use std::collections::HashMap;
54//!
55//! #[tokio::main]
56//! async fn main() -> claude_code_toolkit::Result<()> {
57//! let mut config = HashMap::new();
58//! config.insert("token".to_string(), "your-token".to_string());
59//!
60//! let provider = GitHubProvider::new(config)?;
61//!
62//! // Use provider for operations...
63//!
64//! Ok(())
65//! }
66//! ```
67//!
68//! ## Configuration Requirements
69//!
70//! Each provider has specific configuration requirements:
71//!
72//! ### GitHub Provider
73//! - **Required**: `token` (GitHub personal access token)
74//! - **Optional**: `org` (default organization), `base_url` (GitHub Enterprise URL)
75//!
76//! ## Security Considerations
77//!
78//! - All API tokens are stored securely and never logged
79//! - Network communications use HTTPS with certificate validation
80//! - Sensitive configuration is validated before use
81//! - Rate limiting and retry logic prevent API abuse
82
83pub mod github;
84pub mod registry;
85
86use crate::error::Result;
87use crate::traits::SecretProvider;
88use std::collections::HashMap;
89
90/// Provider factory following Factory Pattern
91pub struct ProviderFactory {
92 creators: HashMap<String, Box<dyn ProviderCreator>>,
93}
94
95impl ProviderFactory {
96 pub fn new() -> Self {
97 let mut factory = Self {
98 creators: HashMap::new(),
99 };
100
101 // Register built-in providers
102 factory.register("github", Box::new(github::GitHubProviderCreator));
103
104 factory
105 }
106
107 pub fn register(&mut self, name: &str, creator: Box<dyn ProviderCreator>) {
108 self.creators.insert(name.to_string(), creator);
109 }
110
111 pub fn create(
112 &self,
113 name: &str,
114 config: &HashMap<String, String>
115 ) -> Result<Box<dyn SecretProvider>> {
116 let creator = self.creators
117 .get(name)
118 .ok_or_else(|| {
119 crate::error::ClaudeCodeError::Generic(format!("Unknown provider: {}", name))
120 })?;
121
122 creator.create(config)
123 }
124
125 pub fn available_providers(&self) -> Vec<&str> {
126 self.creators
127 .keys()
128 .map(|s| s.as_str())
129 .collect()
130 }
131}
132
133impl Default for ProviderFactory {
134 fn default() -> Self {
135 Self::new()
136 }
137}
138
139/// Provider creator trait for Factory Pattern
140pub trait ProviderCreator: Send + Sync {
141 fn create(&self, config: &HashMap<String, String>) -> Result<Box<dyn SecretProvider>>;
142 fn provider_type(&self) -> &str;
143 fn required_config(&self) -> Vec<&str>;
144 fn optional_config(&self) -> Vec<&str> {
145 Vec::new()
146 }
147}
148
149/// Base provider implementation with common functionality
150pub struct BaseProvider {
151 pub name: String,
152 pub config: HashMap<String, String>,
153}
154
155impl BaseProvider {
156 pub fn new(name: &str, config: HashMap<String, String>) -> Self {
157 Self {
158 name: name.to_string(),
159 config,
160 }
161 }
162
163 pub fn get_config(&self, key: &str) -> Option<&String> {
164 self.config.get(key)
165 }
166
167 pub fn require_config(&self, key: &str) -> Result<&String> {
168 self
169 .get_config(key)
170 .ok_or_else(|| {
171 crate::error::ClaudeCodeError::Generic(format!("Missing required config: {}", key))
172 })
173 }
174}