use dashmap::DashMap;
use std::os::raw::c_int;
use std::sync::LazyLock;
use valkey_module::alloc::ValkeyAlloc;
use valkey_module::server_events::ClientChangeSubevent;
use valkey_module::{
valkey_module, CommandFilterCtx, Context, RedisModuleCommandFilterCtx, Status, ValkeyError,
ValkeyString, AUTH_HANDLED, AUTH_NOT_HANDLED, VALKEYMODULE_CMDFILTER_NOSELF,
};
use valkey_module_macros::client_changed_event_handler;
static CLIENT_ID_USERNAME_MAP: LazyLock<DashMap<u64, String>> = LazyLock::new(|| DashMap::new());
#[client_changed_event_handler]
fn client_changed_event_handler(ctx: &Context, client_event: ClientChangeSubevent) {
match client_event {
ClientChangeSubevent::Connected => {
let username = "default".to_string();
let client_id = ctx.get_client_id();
CLIENT_ID_USERNAME_MAP.insert(client_id, username);
}
ClientChangeSubevent::Disconnected => {
let client_id = ctx.get_client_id();
CLIENT_ID_USERNAME_MAP.remove(&client_id);
}
}
}
fn auth_callback(
ctx: &Context,
username: ValkeyString,
_password: ValkeyString,
) -> Result<c_int, ValkeyError> {
let _username_before_auth = match ctx.get_client_username() {
Ok(tmp) => tmp.to_string(),
Err(_err) => "default".to_string(),
};
if ctx.authenticate_client_with_acl_user(&username) == Status::Ok {
let client_id = ctx.get_client_id();
CLIENT_ID_USERNAME_MAP.insert(client_id, username.to_string());
return Ok(AUTH_HANDLED);
}
Ok(AUTH_NOT_HANDLED)
}
fn filter1_fn(ctx: *mut RedisModuleCommandFilterCtx) {
let cf_ctx = CommandFilterCtx::new(ctx);
let client_id = cf_ctx.get_client_id();
let _username = match CLIENT_ID_USERNAME_MAP.get(&client_id) {
Some(tmp) => tmp.clone(),
None => "default".to_string(),
};
}
fn filter2_fn(_ctx: *mut RedisModuleCommandFilterCtx) {
}
valkey_module! {
name: "filter2",
version: 1,
allocator: (ValkeyAlloc, ValkeyAlloc),
data_types: [],
auth: [auth_callback],
commands: [
],
filters: [
[filter1_fn, VALKEYMODULE_CMDFILTER_NOSELF],
[filter2_fn, VALKEYMODULE_CMDFILTER_NOSELF]
]
}