llm_orchestrator_auth/
lib.rs1pub mod api_keys;
68pub mod jwt;
69pub mod middleware;
70pub mod models;
71pub mod rbac;
72
73pub use api_keys::{ApiKeyManager, ApiKeyStore, InMemoryApiKeyStore};
75pub use jwt::JwtAuth;
76pub use middleware::AuthMiddleware;
77pub use models::{
78 ApiKey, ApiKeyInfo, AuthContext, AuthError, AuthResult, AuthType, Claims, Permission,
79 RolePolicy,
80};
81pub use rbac::RbacEngine;
82
83pub const VERSION: &str = env!("CARGO_PKG_VERSION");
85
86#[cfg(test)]
87mod integration_tests {
88 use super::*;
89 use std::sync::Arc;
90
91 #[tokio::test]
92 async fn test_full_jwt_flow() {
93 let jwt_auth = Arc::new(JwtAuth::new(
95 b"test-secret-key-at-least-32-bytes-long".to_vec(),
96 ));
97 let api_key_store = Arc::new(InMemoryApiKeyStore::new());
98 let api_key_manager = Arc::new(ApiKeyManager::new(api_key_store));
99 let rbac = Arc::new(RbacEngine::new());
100 let auth = AuthMiddleware::new(jwt_auth.clone(), api_key_manager, rbac);
101
102 let token = jwt_auth
104 .generate_token("user123", vec!["developer".to_string()])
105 .unwrap();
106
107 let auth_header = format!("Bearer {}", token);
109 let ctx = auth.authenticate(Some(&auth_header)).await.unwrap();
110
111 assert_eq!(ctx.user_id, "user123");
113 assert_eq!(ctx.roles, vec!["developer"]);
114 assert!(ctx.has_permission(&Permission::WorkflowWrite));
115
116 assert!(auth
118 .authorize(&ctx, &Permission::WorkflowWrite)
119 .is_ok());
120 }
121
122 #[tokio::test]
123 async fn test_full_api_key_flow() {
124 let jwt_auth = Arc::new(JwtAuth::new(
126 b"test-secret-key-at-least-32-bytes-long".to_vec(),
127 ));
128 let api_key_store = Arc::new(InMemoryApiKeyStore::new());
129 let api_key_manager = Arc::new(ApiKeyManager::new(api_key_store));
130 let rbac = Arc::new(RbacEngine::new());
131 let auth = AuthMiddleware::new(jwt_auth, api_key_manager.clone(), rbac);
132
133 let api_key = api_key_manager
135 .create_key(
136 "user456",
137 vec!["workflow:read".to_string(), "workflow:execute".to_string()],
138 Some("My Test Key".to_string()),
139 Some(30),
140 )
141 .await
142 .unwrap();
143
144 let auth_header = format!("ApiKey {}", api_key.key);
146 let ctx = auth.authenticate(Some(&auth_header)).await.unwrap();
147
148 assert_eq!(ctx.user_id, "user456");
150 assert!(ctx.has_permission(&Permission::WorkflowRead));
151 assert!(ctx.has_permission(&Permission::WorkflowExecute));
152 assert!(!ctx.has_permission(&Permission::WorkflowWrite));
153
154 let keys = api_key_manager.list_keys("user456").await.unwrap();
156 assert_eq!(keys.len(), 1);
157 assert_eq!(keys[0].name, Some("My Test Key".to_string()));
158
159 api_key_manager.revoke_key(&api_key.id).await.unwrap();
161
162 let result = auth.authenticate(Some(&auth_header)).await;
164 assert!(matches!(result, Err(AuthError::ApiKeyNotFound)));
165 }
166
167 #[tokio::test]
168 async fn test_refresh_token_flow() {
169 let jwt_auth = JwtAuth::new(b"test-secret-key-at-least-32-bytes-long".to_vec());
171
172 let refresh_token = jwt_auth.generate_refresh_token("user789").unwrap();
174
175 let user_id = jwt_auth.verify_refresh_token(&refresh_token).unwrap();
177 assert_eq!(user_id, "user789");
178
179 let access_token = jwt_auth
181 .refresh_access_token(&refresh_token, vec!["executor".to_string()])
182 .unwrap();
183
184 let claims = jwt_auth.verify_token(&access_token).unwrap();
186 assert_eq!(claims.sub, "user789");
187 assert_eq!(claims.roles, vec!["executor"]);
188 }
189
190 #[tokio::test]
191 async fn test_rbac_permission_checks() {
192 let rbac = RbacEngine::new();
193
194 assert!(rbac.check_permission(&["viewer".to_string()], &Permission::WorkflowRead));
196 assert!(!rbac.check_permission(&["viewer".to_string()], &Permission::WorkflowWrite));
197
198 assert!(rbac.check_permission(
200 &["executor".to_string()],
201 &Permission::WorkflowExecute
202 ));
203
204 assert!(rbac.check_permission(
206 &["developer".to_string()],
207 &Permission::WorkflowWrite
208 ));
209
210 for permission in Permission::all() {
212 assert!(rbac.check_permission(&["admin".to_string()], &permission));
213 }
214 }
215
216 #[tokio::test]
217 async fn test_multiple_roles() {
218 let jwt_auth = Arc::new(JwtAuth::new(
219 b"test-secret-key-at-least-32-bytes-long".to_vec(),
220 ));
221 let rbac = Arc::new(RbacEngine::new());
222
223 let token = jwt_auth
225 .generate_token(
226 "user123",
227 vec!["viewer".to_string(), "executor".to_string()],
228 )
229 .unwrap();
230
231 let claims = jwt_auth.verify_token(&token).unwrap();
232
233 let permissions = rbac.compute_permissions(&claims.roles);
235
236 assert!(permissions.contains(&Permission::WorkflowRead));
238 assert!(permissions.contains(&Permission::WorkflowExecute));
239 assert!(permissions.contains(&Permission::ExecutionRead));
240 }
241}