This commit is contained in:
2022-09-27 04:23:39 +00:00
committed by GitHub
parent 5497f6ffb5
commit 5b4ba8d80a
4 changed files with 77 additions and 10 deletions

View File

@@ -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<bool, SqliteError> {
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<User, PixivDownloaderDbError> {
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<Option<Token>, PixivDownloaderDbError> {
Ok(self.get_token(id).await?)

View File

@@ -24,6 +24,21 @@ pub trait PixivDownloaderDb {
password: &[u8],
) -> Result<User, PixivDownloaderDbError>;
#[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<User, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Get token by ID
/// * `id` - The token ID
async fn get_token(&self, id: u64) -> Result<Option<Token>, PixivDownloaderDbError>;

View File

@@ -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;

View File

@@ -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<Body> 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
}