diff options
Diffstat (limited to 'server/src/models')
-rw-r--r-- | server/src/models/auth.rs | 63 | ||||
-rw-r--r-- | server/src/models/mod.rs | 1 | ||||
-rw-r--r-- | server/src/models/user.rs | 22 |
3 files changed, 85 insertions, 1 deletions
diff --git a/server/src/models/auth.rs b/server/src/models/auth.rs new file mode 100644 index 0000000..03b198b --- /dev/null +++ b/server/src/models/auth.rs @@ -0,0 +1,63 @@ +use crate::errors::AppError; +use chrono::{Duration, Local}; +use jsonwebtoken::{encode, DecodingKey, EncodingKey, Header, Validation}; +use once_cell::sync::Lazy; +use serde::{Deserialize, Serialize}; + +struct Keys { + encoding: EncodingKey, + decoding: DecodingKey, +} + +#[derive(Serialize, Deserialize)] +pub struct Claims { + user_id: i32, + exp: usize, +} + +#[derive(Serialize)] +pub struct AuthBody { + access_token: String, + token_type: String, +} + +static KEYS: Lazy<Keys> = Lazy::new(|| { + let secret = std::env::var("JWT_SECRET").expect("JWT_SECRET must be set"); + Keys::new(secret.as_bytes()) +}); + +impl Keys { + fn new(secret: &[u8]) -> Self { + Self { + encoding: EncodingKey::from_secret(secret), + decoding: DecodingKey::from_secret(secret), + } + } +} + +impl Claims { + pub fn new(user_id: i32) -> Self { + let expiration = Local::now() + Duration::days(2); + + Self { + user_id, + exp: expiration.timestamp() as usize, + } + } + + pub fn get_token(&self) -> Result<String, AppError> { + let token = encode(&Header::default(), &self, &KEYS.encoding) + .map_err(|_| AppError::TokenCreation)?; + + Ok(token) + } +} + +impl AuthBody { + pub fn new(access_token: String) -> Self { + Self { + access_token, + token_type: "Bearer".to_string(), + } + } +} diff --git a/server/src/models/mod.rs b/server/src/models/mod.rs index 22d12a3..f9bae3d 100644 --- a/server/src/models/mod.rs +++ b/server/src/models/mod.rs @@ -1 +1,2 @@ +pub mod auth; pub mod user; diff --git a/server/src/models/user.rs b/server/src/models/user.rs index 964f04a..38ec121 100644 --- a/server/src/models/user.rs +++ b/server/src/models/user.rs @@ -16,7 +16,7 @@ pub struct User { #[derive(Deserialize, Serialize)] pub struct UserList { - id: i32, + pub id: i32, email: String, is_staff: Option<bool>, } @@ -61,6 +61,26 @@ impl User { Ok(rec) } + pub async fn find(user: User) -> Result<UserList, AppError> { + let pool = unsafe { get_client() }; + + let crypted_password = sha256::digest(user.password); + + let rec = sqlx::query_as!( + UserList, + r#" + SELECT id, email, is_staff FROM "users" + WHERE email = $1 AND password = $2 + "#, + user.email, + crypted_password + ) + .fetch_one(pool) + .await?; + + Ok(rec) + } + pub async fn list() -> Result<Vec<UserList>, AppError> { let pool = unsafe { get_client() }; let rows = sqlx::query_as!(UserList, r#"SELECT id, email, is_staff FROM users"#) |