1use crate::ryz::err::res;
2use crate::ryz::res::Res;
3use crate::ryz::time::{utc, Time};
4use hmac::{Hmac, Mac};
5use jwt::VerifyWithKey;
6use jwt::{SignWithKey, ToBase64};
7use serde::Deserialize;
8use serde::Serialize;
9use sha2::Sha256;
10
11#[derive(Serialize, Deserialize, Debug)]
12pub struct UserTokenPayload {
13 pub user_id: i32,
14 pub created: Time,
19}
20
21impl Expire for UserTokenPayload {
22 fn get_created(&self) -> Res<Time> {
23 Ok(*&self.created)
24 }
25}
26
27pub trait Expire {
28 fn get_created(&self) -> Res<Time>;
29
30 fn check_exp(&self, delta: Time) -> Res<Time> {
34 let created = *&self.get_created().unwrap();
35 let exp = created + delta;
36 if exp < utc() {
37 return res("exp_err", "expired token");
38 }
39 Ok(exp)
40 }
41}
42
43pub fn new_token(
44 payload: &(impl ToBase64 + Expire + Serialize),
45 secret: &[u8],
46) -> Res<String> {
47 let encoded_secret: Hmac<Sha256> =
48 Hmac::new_from_slice(secret.into()).unwrap();
49 Ok(payload.sign_with_key(&encoded_secret).unwrap())
50}
51
52pub fn verify_token<T>(token: &String, secret: &[u8]) -> Res<T>
53where
54 T: ToBase64 + Expire + for<'a> Deserialize<'a>,
55{
56 let encoded_secret: Hmac<Sha256> = Hmac::new_from_slice(secret).unwrap();
57 let payload: T = token.verify_with_key(&encoded_secret).unwrap();
58 payload.check_exp(Time::from(60 * 60 * 24 * 365))?;
59 Ok(payload)
60}
61
62pub fn new_rt(user_id: i32) -> Res<String> {
63 let payload = UserTokenPayload {
64 user_id: user_id,
65 created: utc(),
66 };
67 new_token(&payload, b"weloveauth")
68}
69
70pub fn new_at(user_id: i32) -> Res<String> {
71 let payload = UserTokenPayload {
72 user_id: user_id,
73 created: utc(),
74 };
75 new_token(&payload, b"helloworld")
76}
77
78pub fn verify_rt(rt: &String) -> Res<UserTokenPayload> {
79 verify_token(rt, b"weloveauth")
80}