1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use redis::AsyncCommands;
use redis::Client;
use redis::RedisResult;
const EXPIRATION: usize = 24 * 60 * 60;
fn gen_session_key(tenant: &str, token: &str) -> String {
let clean_info = |info: &str| info.replace('$', "-").replace(':', "_");
base64::encode(format!(
"{}$SESSION:{}",
clean_info(tenant),
clean_info(token)
))
}
pub async fn get_session(client: &Client, tenant: &str, token: &str) -> RedisResult<String> {
let key = gen_session_key(tenant, token);
let mut conn = client.get_async_connection().await?;
conn.get(key).await
}
pub fn save_session(client: &Client, tenant: &str, token: &str, json: &str) -> RedisResult<()> {
let key = gen_session_key(tenant, token);
let mut conn = client.get_connection()?;
redis::transaction(&mut conn, &[key.clone()], |conn, pipe| {
pipe.set(key.clone(), json)
.expire(key.clone(), EXPIRATION)
.query(conn)
})
}
pub async fn remove_session(client: &Client, tenant: &str, token: &str) -> RedisResult<()> {
let key = gen_session_key(tenant, token);
let mut conn = client.get_async_connection().await?;
conn.del(key).await
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test(flavor = "multi_thread", worker_threads = 3)]
async fn save_then_remove() {
let server = "localhost:6379";
let token = "save_then_remove";
let json = "{\"foo\": \"bar\"}";
let tenant = "teste";
let client = crate::build_client(server).unwrap();
remove_session(&client, tenant, token).await.unwrap();
remove_session(&client, tenant, token).await.unwrap();
remove_session(&client, tenant, token).await.unwrap();
assert!(get_session(&client, tenant, token).await.is_err());
let _ = save_session(&client, tenant, token, json).unwrap();
let json_return = get_session(&client, tenant, token).await.unwrap();
assert_eq!(json, json_return);
let _ = remove_session(&client, tenant, token).await.unwrap();
}
}