sqlserver_mcp_catalog/auth/strategies/
sql_server.rs1use async_trait::async_trait;
13
14use super::super::auth_strategy::{AuthConfig, AuthStrategy, Credentials};
15use super::super::errors::AuthError;
16
17#[derive(Debug, Default)]
18pub struct SqlServerAuthStrategy;
19
20#[async_trait]
21impl AuthStrategy for SqlServerAuthStrategy {
22 async fn authenticate(&self, config: &AuthConfig) -> anyhow::Result<Credentials> {
23 let username = config
24 .get("username")
25 .ok_or_else(|| AuthError::MissingCredentials("username, password".to_string()))?;
26 let password = config
27 .get("password")
28 .ok_or_else(|| AuthError::MissingCredentials("username, password".to_string()))?;
29
30 let mut credentials = Credentials::new();
31 credentials.insert("username".to_string(), username.clone());
32 credentials.insert("password".to_string(), password.clone());
33 Ok(credentials)
34 }
35
36 fn validate_credentials(&self, credentials: &Credentials) -> bool {
37 credentials
38 .get("username")
39 .is_some_and(|username| !username.is_empty())
40 && credentials
41 .get("password")
42 .is_some_and(|password| !password.is_empty())
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 fn config(username: &str, password: &str) -> AuthConfig {
51 AuthConfig::from([
52 ("username".to_string(), username.to_string()),
53 ("password".to_string(), password.to_string()),
54 ])
55 }
56
57 #[tokio::test]
58 async fn carries_username_and_password_through_unchanged() {
59 let strategy = SqlServerAuthStrategy;
60 let credentials = strategy
61 .authenticate(&config("sa", "s3cr3t"))
62 .await
63 .unwrap();
64 assert_eq!(credentials.get("username").unwrap(), "sa");
65 assert_eq!(credentials.get("password").unwrap(), "s3cr3t");
66 }
67
68 #[tokio::test]
69 async fn rejects_a_config_missing_either_field() {
70 let strategy = SqlServerAuthStrategy;
71 assert!(strategy.authenticate(&AuthConfig::new()).await.is_err());
72 }
73
74 #[test]
75 fn validates_credentials_carrying_both_fields() {
76 let strategy = SqlServerAuthStrategy;
77 assert!(strategy.validate_credentials(&config("sa", "s3cr3t")));
78 assert!(!strategy.validate_credentials(&Credentials::new()));
79 }
80}