Updated models and entities
This commit is contained in:
parent
31c52a7771
commit
02d090dd6a
@ -1,5 +1,3 @@
|
||||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2
|
||||
|
||||
use chacha20poly1305::{aead::Aead, AeadCore, ChaCha20Poly1305, KeyInit};
|
||||
use futures::{Stream, TryStreamExt};
|
||||
use pbkdf2::pbkdf2_hmac_array;
|
||||
@ -33,6 +31,7 @@ struct Cipher {
|
||||
|
||||
impl Cipher {
|
||||
/// Creates a new cipher from a master password and the salt
|
||||
#[inline]
|
||||
fn new(password: &[u8], salt: &[u8]) -> Self {
|
||||
let key = pbkdf2_hmac_array::<Sha256, 32>(password, salt, 480000);
|
||||
|
||||
@ -42,6 +41,7 @@ impl Cipher {
|
||||
}
|
||||
|
||||
/// Encrypts the value with the current cipher. The 12 byte nonce is appended to the result
|
||||
#[inline]
|
||||
pub fn encrypt(&self, value: &[u8]) -> crate::Result<Vec<u8>> {
|
||||
let nonce = ChaCha20Poly1305::generate_nonce(&mut OsRng);
|
||||
let mut result = self.chacha.encrypt(&nonce, value)?;
|
||||
@ -50,6 +50,7 @@ impl Cipher {
|
||||
}
|
||||
|
||||
/// Decrypts the value with the current cipher. The 12 byte nonce is expected to be at the end of the value
|
||||
#[inline]
|
||||
fn decrypt(&self, value: &[u8]) -> crate::Result<Vec<u8>> {
|
||||
let (data, nonce) = value.split_at(value.len() - 12);
|
||||
self.chacha.decrypt(nonce.into(), data).map_err(Into::into)
|
||||
@ -58,6 +59,7 @@ impl Cipher {
|
||||
|
||||
impl ActiveModel {
|
||||
/// Encryptes the provided data by the master password and creates the ActiveModel with all fields set to Set variant
|
||||
#[inline]
|
||||
pub fn from_unencrypted(
|
||||
user_id: u64,
|
||||
name: String,
|
||||
@ -82,6 +84,7 @@ impl ActiveModel {
|
||||
|
||||
impl Model {
|
||||
/// Returns the decrypted login and password of the account
|
||||
#[inline]
|
||||
pub fn decrypt(&self, master_pass: &str) -> crate::Result<(String, String)> {
|
||||
let cipher = Cipher::new(master_pass.as_bytes(), &self.salt);
|
||||
let login = String::from_utf8(cipher.decrypt(&self.enc_login)?)?;
|
||||
@ -92,6 +95,7 @@ impl Model {
|
||||
|
||||
impl Entity {
|
||||
/// Gets all user's account from DB
|
||||
#[inline]
|
||||
pub async fn get_all(
|
||||
user_id: u64,
|
||||
db: &DatabaseConnection,
|
||||
@ -104,6 +108,7 @@ impl Entity {
|
||||
}
|
||||
|
||||
/// Gets a list of account names of a user
|
||||
#[inline]
|
||||
pub async fn get_names(
|
||||
user_id: u64,
|
||||
db: &DatabaseConnection,
|
||||
@ -121,6 +126,7 @@ impl Entity {
|
||||
}
|
||||
|
||||
/// Checks if the account exists
|
||||
#[inline]
|
||||
pub async fn exists(
|
||||
user_id: u64,
|
||||
account_name: impl Into<String>,
|
||||
@ -136,6 +142,7 @@ impl Entity {
|
||||
}
|
||||
|
||||
/// Gets the account from the DB
|
||||
#[inline]
|
||||
pub async fn get(
|
||||
user_id: u64,
|
||||
account_name: impl Into<String>,
|
||||
@ -148,6 +155,7 @@ impl Entity {
|
||||
}
|
||||
|
||||
/// Deletes all the user's accounts from DB
|
||||
#[inline]
|
||||
pub async fn delete_all(user_id: u64, db: &DatabaseConnection) -> crate::Result<()> {
|
||||
Self::delete_many()
|
||||
.filter(Column::UserId.eq(user_id))
|
||||
|
@ -1,5 +1,3 @@
|
||||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2
|
||||
|
||||
use rand::{rngs::OsRng, RngCore};
|
||||
use scrypt::{scrypt, Params};
|
||||
use sea_orm::{entity::prelude::*, ActiveValue::Set, QuerySelect};
|
||||
@ -22,6 +20,7 @@ pub enum Relation {}
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
||||
/// Hashes the password with Scrypt with the given salt
|
||||
#[inline]
|
||||
fn hash_password(password: &[u8], salt: &[u8]) -> crate::Result<Vec<u8>> {
|
||||
let params = Params::new(14, Params::RECOMMENDED_R, Params::RECOMMENDED_P, 64)?;
|
||||
let mut password_hash = vec![0; 64];
|
||||
@ -31,6 +30,7 @@ fn hash_password(password: &[u8], salt: &[u8]) -> crate::Result<Vec<u8>> {
|
||||
|
||||
impl ActiveModel {
|
||||
/// Hashes the password and creates an ActiveModel with all fields set to Set variant
|
||||
#[inline]
|
||||
pub fn from_unencrypted(user_id: u64, password: &str) -> crate::Result<Self> {
|
||||
let mut salt = vec![0; 64];
|
||||
OsRng.fill_bytes(&mut salt);
|
||||
@ -45,6 +45,7 @@ impl ActiveModel {
|
||||
|
||||
impl Entity {
|
||||
/// Verifies the provided master password against the one from DB
|
||||
#[inline]
|
||||
pub async fn verify_master_pass(
|
||||
user_id: u64,
|
||||
master_pass: String,
|
||||
@ -61,6 +62,7 @@ impl Entity {
|
||||
}
|
||||
|
||||
/// Checks if the master password for the user exists
|
||||
#[inline]
|
||||
pub async fn exists(user_id: u64, db: &DatabaseConnection) -> crate::Result<bool> {
|
||||
let id = Self::find_by_id(user_id)
|
||||
.select_only()
|
||||
|
@ -1,6 +1,5 @@
|
||||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2
|
||||
|
||||
pub mod prelude;
|
||||
//! Entities to work with the database
|
||||
|
||||
pub mod account;
|
||||
pub mod master_pass;
|
||||
pub mod prelude;
|
||||
|
@ -1,4 +1,4 @@
|
||||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.2
|
||||
|
||||
pub use super::account::Entity as Account;
|
||||
pub use super::master_pass::Entity as MasterPass;
|
||||
pub use super::account::{self, Entity as Account};
|
||||
pub use super::master_pass::{self, Entity as MasterPass};
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
entity::{master_pass, prelude::*},
|
||||
entity::prelude::*,
|
||||
errors::NoUserInfo,
|
||||
handlers::{markups::deletion_markup, utils::package_handler, MainDialogue, State},
|
||||
};
|
||||
|
@ -5,12 +5,11 @@ mod models;
|
||||
|
||||
use anyhow::{Error, Result};
|
||||
use dotenv::dotenv;
|
||||
use futures::future::BoxFuture as PinnedFuture;
|
||||
use handlers::get_dispatcher;
|
||||
use migration::{Migrator, MigratorTrait};
|
||||
use sea_orm::Database;
|
||||
use std::{env, future::Future, pin::Pin};
|
||||
|
||||
type PinnedFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
|
||||
use std::env;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
|
@ -1,4 +1,6 @@
|
||||
use crate::entity::account;
|
||||
//! Models to export and import the accounts
|
||||
|
||||
use crate::entity::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
@ -10,24 +12,30 @@ pub struct DecryptedAccount {
|
||||
|
||||
impl DecryptedAccount {
|
||||
/// Constructs DecryptedAccount by decrypting the provided account
|
||||
#[inline]
|
||||
pub fn from_account(account: account::Model, master_pass: &str) -> crate::Result<Self> {
|
||||
let name = account.name.clone();
|
||||
let (login, password) = account.decrypt(master_pass)?;
|
||||
Ok(Self {
|
||||
name,
|
||||
name: account.name,
|
||||
login,
|
||||
password,
|
||||
})
|
||||
}
|
||||
|
||||
/// Constructs ActiveModel with eath field Set by encrypting `self`
|
||||
#[inline]
|
||||
pub fn into_account(
|
||||
self,
|
||||
user_id: u64,
|
||||
master_pass: &str,
|
||||
) -> crate::Result<account::ActiveModel> {
|
||||
let (name, login, password) = (self.name, self.login, self.password);
|
||||
account::ActiveModel::from_unencrypted(user_id, name, &login, &password, master_pass)
|
||||
account::ActiveModel::from_unencrypted(
|
||||
user_id,
|
||||
self.name,
|
||||
&self.login,
|
||||
&self.password,
|
||||
master_pass,
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns true if the account's fields are valid
|
||||
|
Loading…
Reference in New Issue
Block a user