59 lines
1.4 KiB
Rust
59 lines
1.4 KiB
Rust
|
//! # User tokens management
|
||
|
|
||
|
use crate::connections::redis_connection;
|
||
|
use crate::models::{User, UserID};
|
||
|
use crate::utils::string_utils;
|
||
|
use crate::utils::time_utils::time;
|
||
|
use std::time::Duration;
|
||
|
|
||
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||
|
struct LoginToken {
|
||
|
expire: u64,
|
||
|
hb: u64,
|
||
|
user_id: UserID,
|
||
|
}
|
||
|
|
||
|
impl LoginToken {
|
||
|
pub fn new(user: &User) -> (String, Self) {
|
||
|
let key = format!("tok-{}-{}", user.id().0, string_utils::rand_str(40));
|
||
|
|
||
|
(
|
||
|
key,
|
||
|
Self {
|
||
|
expire: time() + 3600 * 24,
|
||
|
hb: time(),
|
||
|
user_id: user.id(),
|
||
|
},
|
||
|
)
|
||
|
}
|
||
|
|
||
|
pub fn is_valid(&self) -> bool {
|
||
|
self.expire > time() && self.hb + 3600 > time()
|
||
|
}
|
||
|
|
||
|
pub fn refresh_hb(&self) -> Option<Self> {
|
||
|
if self.hb + 60 * 5 < time() {
|
||
|
let mut new = self.clone();
|
||
|
new.hb = time();
|
||
|
Some(new)
|
||
|
} else {
|
||
|
None
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn lifetime(&self) -> Duration {
|
||
|
Duration::from_secs(if self.expire <= time() {
|
||
|
0
|
||
|
} else {
|
||
|
self.expire - time()
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Generate a new login token
|
||
|
pub async fn gen_new_token(user: &User) -> anyhow::Result<String> {
|
||
|
let (key, token) = LoginToken::new(user);
|
||
|
redis_connection::set_value(&key, &token, token.lifetime()).await?;
|
||
|
Ok(key)
|
||
|
}
|