mirror of
https://github.com/rustmailer/bichon.git
synced 2026-08-03 07:48:34 +02:00
feat: reset the login password #126
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
use std::{path::Path, rc::Rc};
|
||||
|
||||
use native_db::{Builder, Database};
|
||||
|
||||
use crate::{
|
||||
modules::{
|
||||
database::META_MODELS,
|
||||
error::{code::ErrorCode, BichonResult},
|
||||
token::{AccessTokenModel, AccessTokenModelKey, TokenType},
|
||||
users::{UserModel, DEFAULT_ADMIN_USER_ID},
|
||||
utils::encrypt::internal_encrypt_string,
|
||||
},
|
||||
raise_error,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
|
||||
pub fn init_meta_database(path: impl AsRef<Path>) -> BichonResult<Rc<Database<'static>>> {
|
||||
let database = Builder::new()
|
||||
.set_cache_size(134217728)
|
||||
.create(&META_MODELS, path)
|
||||
.map_err(|e| {
|
||||
raise_error!(
|
||||
format!("Failed to open database: {:?}", e),
|
||||
ErrorCode::InternalError
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(Rc::new(database))
|
||||
}
|
||||
|
||||
pub fn find_admin(database: &Rc<Database<'static>>) -> BichonResult<Option<UserModel>> {
|
||||
let r_transaction = database
|
||||
.r_transaction()
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
let entity: Option<UserModel> = r_transaction
|
||||
.get()
|
||||
.primary(DEFAULT_ADMIN_USER_ID)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
return Ok(entity);
|
||||
}
|
||||
|
||||
pub fn update_admin_password(
|
||||
database: &Rc<Database<'static>>,
|
||||
password: String,
|
||||
encrypt_key: &str,
|
||||
) -> BichonResult<()> {
|
||||
let rw_transaction = database
|
||||
.rw_transaction()
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
let entity: UserModel = rw_transaction
|
||||
.get()
|
||||
.primary(DEFAULT_ADMIN_USER_ID)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
.ok_or_else(|| raise_error!("admin is not found".into(), ErrorCode::InternalError))?;
|
||||
|
||||
let mut updated = entity.clone();
|
||||
updated.password = Some(
|
||||
internal_encrypt_string(encrypt_key, &password)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?,
|
||||
);
|
||||
|
||||
rw_transaction
|
||||
.update(entity, updated)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
rw_transaction
|
||||
.commit()
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
pub fn reset_webui_token(database: &Rc<Database<'static>>) -> BichonResult<()> {
|
||||
let rw_transaction = database
|
||||
.rw_transaction()
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
|
||||
let tokens: Vec<AccessTokenModel> = rw_transaction
|
||||
.scan()
|
||||
.secondary(AccessTokenModelKey::user_id)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
.start_with(DEFAULT_ADMIN_USER_ID)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?
|
||||
.try_collect()
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
|
||||
let webui_token = tokens
|
||||
.into_iter()
|
||||
.find(|t| t.token_type == TokenType::WebUI);
|
||||
|
||||
let new_token = AccessTokenModel::new_webui_token(DEFAULT_ADMIN_USER_ID);
|
||||
match webui_token {
|
||||
Some(current) => {
|
||||
rw_transaction
|
||||
.remove(current)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
|
||||
rw_transaction
|
||||
.insert(new_token)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
}
|
||||
None => {
|
||||
rw_transaction
|
||||
.insert(new_token)
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
}
|
||||
}
|
||||
|
||||
rw_transaction
|
||||
.commit()
|
||||
.map_err(|e| raise_error!(format!("{:#?}", e), ErrorCode::InternalError))?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod meta;
|
||||
@@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::bichon_version;
|
||||
|
||||
pub mod admin;
|
||||
pub mod auth;
|
||||
pub mod eml;
|
||||
pub mod mbox;
|
||||
|
||||
@@ -16,17 +16,15 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::modules::settings::cli::Settings;
|
||||
use poem_openapi::Object;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::modules::settings::cli::Settings;
|
||||
|
||||
pub mod cli;
|
||||
pub mod dir;
|
||||
pub mod io;
|
||||
pub mod proxy;
|
||||
pub mod system;
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize, Object)]
|
||||
pub struct SystemConfigurations {
|
||||
pub bichon_log_level: String,
|
||||
|
||||
@@ -498,7 +498,6 @@ impl BichonUserV2 {
|
||||
pub async fn update(id: u64, request: UserUpdateRequest) -> BichonResult<()> {
|
||||
let _ = &request.validate().await?;
|
||||
let password_changed = request.password.is_some();
|
||||
//
|
||||
let is_default_admin = id == DEFAULT_ADMIN_USER_ID;
|
||||
|
||||
if is_default_admin {
|
||||
|
||||
@@ -72,7 +72,7 @@ pub fn decrypt_string(data: &str) -> BichonResult<String> {
|
||||
})
|
||||
}
|
||||
|
||||
fn internal_encrypt_string(
|
||||
pub fn internal_encrypt_string(
|
||||
password: &str,
|
||||
plaintext: &str,
|
||||
) -> Result<String, ring::error::Unspecified> {
|
||||
@@ -102,7 +102,7 @@ fn internal_encrypt_string(
|
||||
Ok(general_purpose::URL_SAFE.encode(&result))
|
||||
}
|
||||
|
||||
fn internal_decrypt_string(password: &str, data: &str) -> Result<String, ring::error::Unspecified> {
|
||||
pub fn internal_decrypt_string(password: &str, data: &str) -> Result<String, ring::error::Unspecified> {
|
||||
let data = general_purpose::URL_SAFE
|
||||
.decode(data)
|
||||
.map_err(|_| ring::error::Unspecified)?;
|
||||
|
||||
Reference in New Issue
Block a user