use anyhow::Result;
use async_trait::async_trait;
use russh::keys::ssh_key::PublicKey;
use crate::shared::auth_types::{AuthResult, UserInfo};
#[async_trait]
pub trait AuthProvider: Send + Sync {
async fn verify_publickey(&self, username: &str, key: &PublicKey) -> Result<AuthResult>;
async fn verify_password(&self, username: &str, password: &str) -> Result<AuthResult>;
async fn get_user_info(&self, username: &str) -> Result<Option<UserInfo>>;
async fn user_exists(&self, username: &str) -> Result<bool>;
}
#[cfg(test)]
mod tests {
use super::*;
struct RejectAllProvider;
#[async_trait]
impl AuthProvider for RejectAllProvider {
async fn verify_publickey(&self, _username: &str, _key: &PublicKey) -> Result<AuthResult> {
Ok(AuthResult::Reject)
}
async fn verify_password(&self, _username: &str, _password: &str) -> Result<AuthResult> {
Ok(AuthResult::Reject)
}
async fn get_user_info(&self, _username: &str) -> Result<Option<UserInfo>> {
Ok(None)
}
async fn user_exists(&self, _username: &str) -> Result<bool> {
Ok(false)
}
}
struct AcceptAllProvider;
#[async_trait]
impl AuthProvider for AcceptAllProvider {
async fn verify_publickey(&self, _username: &str, _key: &PublicKey) -> Result<AuthResult> {
Ok(AuthResult::Accept)
}
async fn verify_password(&self, _username: &str, _password: &str) -> Result<AuthResult> {
Ok(AuthResult::Accept)
}
async fn get_user_info(&self, username: &str) -> Result<Option<UserInfo>> {
Ok(Some(UserInfo::new(username)))
}
async fn user_exists(&self, _username: &str) -> Result<bool> {
Ok(true)
}
}
#[tokio::test]
async fn test_reject_all_provider() {
let provider = RejectAllProvider;
let result = provider.verify_password("test", "pass").await.unwrap();
assert!(result.is_rejected());
let exists = provider.user_exists("test").await.unwrap();
assert!(!exists);
let info = provider.get_user_info("test").await.unwrap();
assert!(info.is_none());
}
#[tokio::test]
async fn test_accept_all_provider() {
let provider = AcceptAllProvider;
let result = provider.verify_password("test", "pass").await.unwrap();
assert!(result.is_accepted());
let exists = provider.user_exists("test").await.unwrap();
assert!(exists);
let info = provider.get_user_info("test").await.unwrap();
assert!(info.is_some());
assert_eq!(info.unwrap().username, "test");
}
}