use std::sync::Arc;
use cheetah_string::CheetahString;
use rocketmq_auth::AllowAllAuthenticationStrategy;
use rocketmq_auth::AuthFailureKind;
use rocketmq_auth::AuthOperation;
use rocketmq_auth::AuthServiceError;
use rocketmq_auth::AuthenticationFuture;
use rocketmq_auth::AuthenticationStrategy;
use rocketmq_auth::DefaultAuthenticationContext;
async fn example_allow_all_strategy() {
println!("=== Example 1: AllowAllAuthenticationStrategy ===");
let strategy = AllowAllAuthenticationStrategy::new();
let mut context = DefaultAuthenticationContext::new();
context.set_username(CheetahString::from("testuser"));
match strategy.authenticate(&context).await {
Ok(()) => println!("[OK] Authentication succeeded (as expected)"),
Err(e) => println!("[FAIL] Authentication failed: {}", e),
}
println!();
}
async fn example_dynamic_dispatch() {
println!("=== Example 2: Dynamic Dispatch ===");
let strategies: Vec<Arc<dyn AuthenticationStrategy>> = vec![
Arc::new(AllowAllAuthenticationStrategy::new()),
];
let context = DefaultAuthenticationContext::new();
for (i, strategy) in strategies.iter().enumerate() {
match strategy.authenticate(&context).await {
Ok(()) => println!("[OK] Strategy {} succeeded", i + 1),
Err(e) => println!("[FAIL] Strategy {} failed: {}", i + 1, e),
}
}
println!();
}
struct CustomAuthenticationStrategy {
allowed_users: Vec<String>,
}
impl CustomAuthenticationStrategy {
fn new(allowed_users: Vec<String>) -> Self {
Self { allowed_users }
}
}
impl AuthenticationStrategy for CustomAuthenticationStrategy {
fn authenticate<'a>(&'a self, context: &'a dyn rocketmq_auth::AuthenticationContext) -> AuthenticationFuture<'a> {
Box::pin(async move {
let ctx = context
.as_any()
.downcast_ref::<DefaultAuthenticationContext>()
.ok_or_else(|| AuthServiceError::new(AuthOperation::BuildContext, AuthFailureKind::InvalidInput))?;
if let Some(username) = ctx.username() {
if self.allowed_users.contains(&username.to_string()) {
return Ok(());
}
return Err(AuthServiceError::new(
AuthOperation::Authenticate,
AuthFailureKind::Unauthenticated,
));
}
Err(AuthServiceError::new(
AuthOperation::Authenticate,
AuthFailureKind::Unauthenticated,
))
})
}
}
async fn example_custom_strategy() {
println!("=== Example 3: Custom Authentication Strategy ===");
let strategy =
CustomAuthenticationStrategy::new(vec!["alice".to_string(), "bob".to_string(), "charlie".to_string()]);
let mut context1 = DefaultAuthenticationContext::new();
context1.set_username(CheetahString::from("alice"));
match strategy.authenticate(&context1).await {
Ok(()) => println!("[OK] User 'alice' authenticated successfully"),
Err(e) => println!("[FAIL] User 'alice' failed: {}", e),
}
let mut context2 = DefaultAuthenticationContext::new();
context2.set_username(CheetahString::from("eve"));
match strategy.authenticate(&context2).await {
Ok(()) => println!("[OK] User 'eve' authenticated successfully"),
Err(e) => println!("[FAIL] User 'eve' failed: {}", e),
}
let context3 = DefaultAuthenticationContext::new();
match strategy.authenticate(&context3).await {
Ok(()) => println!("[OK] Empty username authenticated successfully"),
Err(e) => println!("[FAIL] Empty username failed: {}", e),
}
println!();
}
async fn example_strategy_composition() {
println!("=== Example 4: Strategy Composition ===");
let strategies: Vec<Arc<dyn AuthenticationStrategy>> = vec![
Arc::new(AllowAllAuthenticationStrategy::new()),
Arc::new(CustomAuthenticationStrategy::new(vec!["admin".to_string()])),
];
let mut context = DefaultAuthenticationContext::new();
context.set_username(CheetahString::from("admin"));
let mut authenticated = false;
for strategy in &strategies {
if strategy.authenticate(&context).await.is_ok() {
authenticated = true;
println!("[OK] Authenticated using a strategy");
break;
}
}
if !authenticated {
println!("[FAIL] All strategies failed");
}
println!();
}
#[tokio::main]
async fn main() {
println!("RocketMQ Rust - Authentication Strategy Examples\n");
example_allow_all_strategy().await;
example_dynamic_dispatch().await;
example_custom_strategy().await;
example_strategy_composition().await;
println!("All examples completed!");
}