Skip to content

Commit 7bf0051

Browse files
committed
added functionality to deauth and close client using ctx (#206)
* added functioanlity to deauth and close client using ctx Signed-off-by: sachinvmurthy <[email protected]> * addressed comments for deauthenticate_and_close_client Signed-off-by: sachinvmurthy <[email protected]> * added abstraction for config get calls via context Signed-off-by: sachinvmurthy <[email protected]> * addressed comments Signed-off-by: sachinvmurthy <[email protected]> --------- Signed-off-by: sachinvmurthy <[email protected]>
1 parent 4285c58 commit 7bf0051

File tree

3 files changed

+68
-4
lines changed

3 files changed

+68
-4
lines changed

examples/client.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,33 @@ fn get_client_ip(ctx: &Context, _args: Vec<ValkeyString>) -> ValkeyResult {
7979
Ok(ctx.get_client_ip()?.into())
8080
}
8181

82+
fn deauth_client_by_id(ctx: &Context, args: Vec<ValkeyString>) -> ValkeyResult {
83+
if args.len() != 2 {
84+
return Err(ValkeyError::WrongArity);
85+
}
86+
let mut args = args.into_iter().skip(1);
87+
let client_id_str: ValkeyString = args.next_arg()?;
88+
let client_id: u64 = client_id_str.parse_integer()?.try_into().unwrap();
89+
let resp = ctx.deauthenticate_and_close_client_by_id(client_id);
90+
match resp {
91+
Ok(msg) => Ok(ValkeyValue::from(msg)),
92+
Err(err) => Err(err),
93+
}
94+
}
95+
96+
fn config_get(ctx: &Context, args: Vec<ValkeyString>) -> ValkeyResult {
97+
if args.len() != 2 {
98+
return Err(ValkeyError::WrongArity);
99+
}
100+
let mut args = args.into_iter().skip(1);
101+
let config_name: ValkeyString = args.next_arg()?;
102+
let config_value = ctx.config_get(config_name.to_string());
103+
match config_value {
104+
Ok(value) => Ok(ValkeyValue::from(value.to_string())),
105+
Err(err) => Err(err),
106+
}
107+
}
108+
82109
valkey_module! {
83110
name: "client",
84111
version: 1,
@@ -92,5 +119,7 @@ valkey_module! {
92119
["client.cert", get_client_cert, "", 0, 0, 0],
93120
["client.info", get_client_info, "", 0, 0, 0],
94121
["client.ip", get_client_ip, "", 0, 0, 0],
122+
["client.deauth", deauth_client_by_id, "", 0, 0, 0],
123+
["client.config_get", config_get, "", 0, 0, 0],
95124
]
96125
}

src/context/client.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use crate::{
2-
Context, RedisModuleClientInfo, RedisModule_GetClientCertificate, RedisModule_GetClientId,
3-
RedisModule_GetClientInfoById, RedisModule_GetClientNameById,
4-
RedisModule_GetClientUserNameById, RedisModule_SetClientNameById, Status, ValkeyError,
5-
ValkeyResult, ValkeyString,
2+
Context, RedisModuleClientInfo, RedisModule_DeauthenticateAndCloseClient,
3+
RedisModule_GetClientCertificate, RedisModule_GetClientId, RedisModule_GetClientInfoById,
4+
RedisModule_GetClientNameById, RedisModule_GetClientUserNameById,
5+
RedisModule_SetClientNameById, Status, ValkeyError, ValkeyResult, ValkeyString, ValkeyValue,
6+
VALKEYMODULE_OK,
67
};
78
use std::ffi::CStr;
89
use std::os::raw::c_void;
@@ -120,4 +121,27 @@ impl Context {
120121
pub fn get_client_ip(&self) -> ValkeyResult<String> {
121122
self.get_client_ip_by_id(self.get_client_id())
122123
}
124+
pub fn deauthenticate_and_close_client_by_id(&self, client_id: u64) -> ValkeyResult<ValkeyString> {
125+
match unsafe { RedisModule_DeauthenticateAndCloseClient.unwrap()(self.ctx, client_id) } {
126+
result if result as isize == VALKEYMODULE_OK => Ok(ValkeyString::create(None, "OK")),
127+
_ => Err(ValkeyError::Str(
128+
"Failed to deauthenticate and close client",
129+
)),
130+
}
131+
}
132+
133+
pub fn deauthenticate_and_close_client(&self) -> ValkeyResult<String> {
134+
self.deauthenticate_and_close_client_by_id(self.get_client_id())
135+
.map(|valkey_str| valkey_str.to_string())
136+
}
137+
138+
pub fn config_get(&self, config: String) -> ValkeyResult<ValkeyString> {
139+
match self.call("CONFIG", &["GET", &config])? {
140+
ValkeyValue::Array(array) if array.len() == 2 => match &array[1] {
141+
ValkeyValue::SimpleString(val) => Ok(ValkeyString::create(None, val.clone())),
142+
_ => Err(ValkeyError::Str("Config value is not a string")),
143+
},
144+
_ => Err(ValkeyError::Str("Unexpected CONFIG GET response")),
145+
}
146+
}
123147
}

tests/integration.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,6 +1213,17 @@ fn test_client() -> Result<()> {
12131213
.query(&mut con)
12141214
.with_context(|| "failed execute client.ip")?;
12151215
assert_eq!(resp, "127.0.0.1");
1216+
// Test client.deauth
1217+
let resp: String = redis::cmd("client.deauth")
1218+
.arg(0)
1219+
.query(&mut con)
1220+
.with_context(|| "failed execute client.deauth")?;
1221+
assert_eq!(resp, "Failed to deauthenticate and close client");
1222+
let resp: String = redis::cmd("client.config_get")
1223+
.arg("maxmemory-policy")
1224+
.query(&mut con)
1225+
.with_context(|| "failed execute client.config_get")?;
1226+
assert_eq!(resp, "noeviction");
12161227
Ok(())
12171228
}
12181229

0 commit comments

Comments
 (0)