Updated models and entities
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user