use std::sync::Arc;
use cheetah_string::CheetahString;
use rocketmq_auth::authentication::context::default_authentication_context::DefaultAuthenticationContext;
use rocketmq_auth::authentication::strategy::AllowAllAuthenticationStrategy;
use rocketmq_auth::authentication::strategy::AuthenticationStrategy;
use rocketmq_error::AuthError;
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) {
Ok(()) => println!("[OK] Authentication succeeded (as expected)"),
Err(e) => println!("[FAIL] Authentication failed: {}", e),
}
println!();
}
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) {
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(
&self,
context: &dyn rocketmq_auth::authorization::context::authentication_context::AuthenticationContext,
) -> Result<(), AuthError> {
let ctx = context
.as_any()
.downcast_ref::<DefaultAuthenticationContext>()
.ok_or_else(|| AuthError::Other("Invalid context type".into()))?;
if let Some(username) = ctx.username() {
if self.allowed_users.contains(&username.to_string()) {
return Ok(());
}
return Err(AuthError::AuthenticationFailed(format!(
"User '{}' is not in the allowed list",
username
)));
}
Err(AuthError::InvalidCredential("Missing username".into()))
}
}
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) {
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) {
Ok(()) => println!("[OK] User 'eve' authenticated successfully"),
Err(e) => println!("[FAIL] User 'eve' failed: {}", e),
}
let context3 = DefaultAuthenticationContext::new();
match strategy.authenticate(&context3) {
Ok(()) => println!("[OK] Empty username authenticated successfully"),
Err(e) => println!("[FAIL] Empty username failed: {}", e),
}
println!();
}
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).is_ok() {
authenticated = true;
println!("[OK] Authenticated using a strategy");
break;
}
}
if !authenticated {
println!("[FAIL] All strategies failed");
}
println!();
}
fn main() {
println!("RocketMQ Rust - Authentication Strategy Examples\n");
example_allow_all_strategy();
example_dynamic_dispatch();
example_custom_strategy();
example_strategy_composition();
println!("All examples completed!");
}