From 5b4ba8d80a2ebdffe188b1af89d395b2cb37be8e Mon Sep 17 00:00:00 2001 From: lifegpc Date: Tue, 27 Sep 2022 04:23:39 +0000 Subject: [PATCH] Update --- src/db/sqlite/db.rs | 37 +++++++++++++++++++++++++++++++++++++ src/db/traits.rs | 15 +++++++++++++++ src/server/auth/mod.rs | 8 ++++++++ src/server/auth/user.rs | 27 +++++++++++++++++---------- 4 files changed, 77 insertions(+), 10 deletions(-) diff --git a/src/db/sqlite/db.rs b/src/db/sqlite/db.rs index 827d0da..cae245f 100644 --- a/src/db/sqlite/db.rs +++ b/src/db/sqlite/db.rs @@ -102,6 +102,20 @@ impl PixivDownloaderSqlite { tx.commit()?; Ok(()) } + + fn _add_user( + tx: &Transaction, + name: &str, + username: &str, + password: &[u8], + is_admin: bool, + ) -> Result<(), SqliteError> { + tx.execute( + "INSERT INTO users (name, username, password, is_admin) VALUES (?, ?, ?, ?);", + (name, username, password, is_admin), + )?; + Ok(()) + } /// Check if the database needed create all tables. async fn _check_database(&self) -> Result { let tables = self._get_exists_table().await?; @@ -387,6 +401,29 @@ impl PixivDownloaderDb for PixivDownloaderSqlite { Ok(self.get_user(0).await?.expect("Root user not found:")) } + #[cfg(feature = "server")] + async fn add_user( + &self, + name: &str, + username: &str, + password: &[u8], + is_admin: bool, + ) -> Result { + if self.get_user_by_username(username).await?.is_some() { + return Err(SqliteError::UserNameAlreadyExists.into()); + } + { + let mut db = self.db.lock().await; + let tx = db.transaction()?; + Self::_add_user(&tx, name, username, password, is_admin)?; + tx.commit()?; + } + Ok(self + .get_user_by_username(username) + .await? + .expect("User not found:")) + } + #[cfg(feature = "server")] async fn get_token(&self, id: u64) -> Result, PixivDownloaderDbError> { Ok(self.get_token(id).await?) diff --git a/src/db/traits.rs b/src/db/traits.rs index 2876ccd..54ebe2a 100644 --- a/src/db/traits.rs +++ b/src/db/traits.rs @@ -24,6 +24,21 @@ pub trait PixivDownloaderDb { password: &[u8], ) -> Result; #[cfg(feature = "server")] + /// Add a new user to database. + /// * `name` - User name + /// * `username` - Unique user name + /// * `password` - Hashed password + /// * `is_admin` - Whether the user is an admin + /// # Note + /// If username already exists, this function must be failed. + async fn add_user( + &self, + name: &str, + username: &str, + password: &[u8], + is_admin: bool, + ) -> Result; + #[cfg(feature = "server")] /// Get token by ID /// * `id` - The token ID async fn get_token(&self, id: u64) -> Result, PixivDownloaderDbError>; diff --git a/src/server/auth/mod.rs b/src/server/auth/mod.rs index 3c24b2c..7ff187a 100644 --- a/src/server/auth/mod.rs +++ b/src/server/auth/mod.rs @@ -5,3 +5,11 @@ pub mod user; pub use pubkey::{AuthPubkeyContext, AuthPubkeyRoute, RSAKey}; pub use status::{AuthStatusContext, AuthStatusRoute}; pub use user::{AuthUserContext, AuthUserRoute}; + +const PASSWORD_SALT: [u8; 64] = [ + 14, 169, 19, 53, 220, 112, 183, 235, 112, 165, 131, 132, 68, 29, 167, 65, 150, 219, 121, 212, + 121, 47, 132, 195, 216, 119, 172, 134, 208, 11, 2, 80, 105, 176, 45, 194, 78, 84, 16, 169, 228, + 25, 195, 207, 144, 204, 171, 95, 8, 113, 93, 40, 41, 116, 80, 126, 253, 142, 245, 147, 148, + 136, 121, 220, +]; +const PASSWORD_ITER: usize = 10000; diff --git a/src/server/auth/user.rs b/src/server/auth/user.rs index 1987cc9..fed1782 100644 --- a/src/server/auth/user.rs +++ b/src/server/auth/user.rs @@ -1,16 +1,10 @@ use super::super::preclude::*; +use super::{PASSWORD_ITER, PASSWORD_SALT}; use crate::ext::json::ToJson2; use crate::ext::try_err::{TryErr, TryErr3}; use crate::gettext; use openssl::{hash::MessageDigest, pkcs5::pbkdf2_hmac}; -const SALT: [u8; 64] = [ - 14, 169, 19, 53, 220, 112, 183, 235, 112, 165, 131, 132, 68, 29, 167, 65, 150, 219, 121, 212, - 121, 47, 132, 195, 216, 119, 172, 134, 208, 11, 2, 80, 105, 176, 45, 194, 78, 84, 16, 169, 228, - 25, 195, 207, 144, 204, 171, 95, 8, 113, 93, 40, 41, 116, 80, 126, 253, 142, 245, 147, 148, - 136, 121, 220, -]; - #[derive(Clone, Debug)] /// Action to perform on a user. pub enum AuthUserAction { @@ -89,8 +83,8 @@ impl AuthUserContext { let mut hashed_password = [0; 64]; pbkdf2_hmac( &password, - &SALT, - 2048, + &PASSWORD_SALT, + PASSWORD_ITER, MessageDigest::sha512(), &mut hashed_password, ) @@ -138,7 +132,18 @@ impl AuthUserContext { )?; Ok(user.to_json2()) } - None => Ok(json::object! {}), + None => { + let user = self + .ctx + .db + .add_user(name, username, &hashed_password, is_admin) + .await + .try_err3( + 12, + gettext("Failed to add user to database:"), + )?; + Ok(user.to_json2()) + } } } } @@ -191,6 +196,8 @@ impl ResponseJsonFor for AuthUserContext { builder.status((-err.code) as u16) } else if err.code < 0 { builder.status(500) + } else if err.code > 0 { + builder.status(400) } else { builder }