Made cryptography and entity modules
Coupling was rising so it just makes sense
This commit is contained in:
parent
9af37f78b2
commit
5871943c01
109
Cargo.lock
generated
109
Cargo.lock
generated
@ -94,9 +94,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.2.0"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
@ -281,6 +281,25 @@ version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
|
||||
dependencies = [
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.3.11"
|
||||
@ -307,24 +326,6 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cryptography"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bitflags 2.5.0",
|
||||
"chacha20poly1305",
|
||||
"entity",
|
||||
"once_cell",
|
||||
"pbkdf2",
|
||||
"rand",
|
||||
"scrypt",
|
||||
"serde",
|
||||
"sha2",
|
||||
"subtle",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.13.4"
|
||||
@ -429,15 +430,6 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "entity"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"hex",
|
||||
"sqlx",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
@ -1053,9 +1045,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.44"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9"
|
||||
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
@ -1064,9 +1056,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.18"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"libm",
|
||||
@ -1096,6 +1088,9 @@ name = "once_cell"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
dependencies = [
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
@ -1140,17 +1135,24 @@ dependencies = [
|
||||
"anyhow",
|
||||
"arrayvec",
|
||||
"base64 0.22.1",
|
||||
"cryptography",
|
||||
"bitflags 2.5.0",
|
||||
"chacha20poly1305",
|
||||
"derive_more",
|
||||
"dotenvy",
|
||||
"entity",
|
||||
"futures",
|
||||
"hex",
|
||||
"itertools 0.12.1",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"pbkdf2",
|
||||
"rand",
|
||||
"scrypt",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"sha2",
|
||||
"sqlx",
|
||||
"subtle",
|
||||
"teloxide",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
@ -1184,6 +1186,8 @@ checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"hmac",
|
||||
"password-hash",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1349,6 +1353,26 @@ dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
|
||||
dependencies = [
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rc-box"
|
||||
version = "1.2.0"
|
||||
@ -1872,6 +1896,7 @@ dependencies = [
|
||||
"sha2",
|
||||
"sqlx-core",
|
||||
"sqlx-mysql",
|
||||
"sqlx-sqlite",
|
||||
"syn 1.0.109",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
@ -1974,6 +1999,7 @@ dependencies = [
|
||||
"libsqlite3-sys",
|
||||
"log",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"sqlx-core",
|
||||
"tracing",
|
||||
"url",
|
||||
@ -2244,16 +2270,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.10"
|
||||
version = "0.7.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
|
||||
checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2757,18 +2782,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.32"
|
||||
version = "0.7.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
|
||||
checksum = "087eca3c1eaf8c47b94d02790dd086cd594b912d2043d4de4bfdd466b3befb7c"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.32"
|
||||
version = "0.7.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
||||
checksum = "6f4b6c273f496d8fd4eaf18853e6b448760225dc030ff2c485a786859aea6393"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
28
Cargo.toml
28
Cargo.toml
@ -10,36 +10,44 @@ debug = 1
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
|
||||
[workspace]
|
||||
members = [".", "entity", "cryptography"]
|
||||
|
||||
[workspace.lints.clippy]
|
||||
[lints.clippy]
|
||||
pedantic = "warn"
|
||||
all = "warn"
|
||||
nursery = "warn"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
ahash = "0.8"
|
||||
anyhow = { version = "1", features = ["backtrace"] }
|
||||
arrayvec = "0.7"
|
||||
base64 = "0.22"
|
||||
cryptography = { version = "0.1", path = "cryptography" }
|
||||
bitflags = "2"
|
||||
chacha20poly1305 = { version = "0.10", features = ["std"] }
|
||||
derive_more = { version = "0.99", default-features = false, features = [
|
||||
"deref",
|
||||
"display",
|
||||
] }
|
||||
dotenvy = "0.15"
|
||||
entity = { version = "0.1", path = "entity" }
|
||||
futures = "0.3"
|
||||
hex = "0.4"
|
||||
itertools = "0.12"
|
||||
once_cell = { version = "1", features = ["parking_lot"] }
|
||||
parking_lot = "0.12"
|
||||
pbkdf2 = { version = "0.12", features = ["parallel"] }
|
||||
rand = { version = "0.8", default-features = false, features = [
|
||||
"std_rng",
|
||||
"std",
|
||||
] }
|
||||
scrypt = { version = "0.11", default-features = false, features = ["std"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
serde_yaml = "0.9"
|
||||
sha2 = "0.10"
|
||||
sqlx = { version = "0.7", features = [
|
||||
"mysql",
|
||||
"runtime-tokio-rustls",
|
||||
"macros",
|
||||
"migrate",
|
||||
] }
|
||||
subtle = "2"
|
||||
teloxide = { version = "0.12", features = [
|
||||
"macros",
|
||||
"ctrlc_handler",
|
||||
|
@ -1,26 +0,0 @@
|
||||
[package]
|
||||
name = "cryptography"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
sha2 = "0.10"
|
||||
scrypt = { version = "0.11", default-features = false, features = ["std"] }
|
||||
pbkdf2 = "0.12"
|
||||
thiserror = "1"
|
||||
entity = { version = "0.1", path = "../entity" }
|
||||
chacha20poly1305 = { version = "0.10", features = ["std"] }
|
||||
rand = { version = "0.8", default-features = false, features = [
|
||||
"std_rng",
|
||||
"std",
|
||||
] }
|
||||
bitflags = "2"
|
||||
arrayvec = "0.7"
|
||||
subtle = "2"
|
||||
once_cell = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
@ -1,19 +0,0 @@
|
||||
use super::hashing::HashedBytes;
|
||||
use entity::master_pass;
|
||||
|
||||
pub trait FromUnencryptedExt {
|
||||
fn from_unencrypted(user_id: u64, password: &str) -> master_pass::MasterPass;
|
||||
}
|
||||
|
||||
impl FromUnencryptedExt for master_pass::MasterPass {
|
||||
/// Hashes the password and creates an `ActiveModel` with all fields set to Set variant
|
||||
#[inline]
|
||||
fn from_unencrypted(user_id: u64, password: &str) -> Self {
|
||||
let hash = HashedBytes::new(password.as_bytes());
|
||||
Self {
|
||||
user_id,
|
||||
password_hash: hash.hash.to_vec(),
|
||||
salt: hash.salt.to_vec(),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
pub use crate::{
|
||||
account::Decrypted as DecryptedAccount, master_pass::FromUnencryptedExt as _, validate_field,
|
||||
};
|
@ -1,19 +0,0 @@
|
||||
[package]
|
||||
name = "entity"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3"
|
||||
sqlx = { version = "0.7", features = [
|
||||
"mysql",
|
||||
"runtime-tokio-rustls",
|
||||
"macros",
|
||||
"migrate",
|
||||
], default-features = false }
|
||||
hex = "0.4"
|
@ -1 +0,0 @@
|
||||
pub use crate::{account::Account, master_pass::MasterPass, Pool};
|
@ -10,9 +10,11 @@ crate::export_handlers!(
|
||||
change_locale
|
||||
);
|
||||
|
||||
use crate::{errors::InvalidCommand, handle_error, locales::LocaleTypeExt};
|
||||
use crate::{
|
||||
entity::locale::LocaleType, errors::handle_error, errors::InvalidCommand,
|
||||
locales::LocaleTypeExt,
|
||||
};
|
||||
use base64::{engine::general_purpose::STANDARD_NO_PAD as B64_ENGINE, Engine as _};
|
||||
use entity::locale::LocaleType;
|
||||
use std::str::FromStr;
|
||||
use teloxide::types::CallbackQuery;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::entity::account::Account;
|
||||
use chacha20poly1305::{AeadCore, AeadInPlace, ChaCha20Poly1305, KeyInit};
|
||||
use entity::account::Account;
|
||||
use pbkdf2::pbkdf2_hmac_array;
|
||||
use rand::{rngs::OsRng, RngCore};
|
||||
use sha2::Sha256;
|
||||
@ -36,9 +36,9 @@ impl Cipher {
|
||||
/// Returns an error if the tag doesn't match the ciphertext
|
||||
#[inline]
|
||||
#[allow(clippy::missing_panics_doc)]
|
||||
pub fn decrypt(&self, value: &mut Vec<u8>) -> crate::Result<()> {
|
||||
pub fn decrypt(&self, value: &mut Vec<u8>) -> super::Result<()> {
|
||||
if value.len() <= 12 {
|
||||
return Err(crate::Error::InvalidInputLength);
|
||||
return Err(super::Error::InvalidInputLength);
|
||||
}
|
||||
let nonce: [u8; 12] = value[value.len() - 12..].try_into().unwrap();
|
||||
value.truncate(value.len() - 12);
|
||||
@ -63,7 +63,7 @@ impl Decrypted {
|
||||
///
|
||||
/// Returns an error if the tag doesn't match the ciphertext or if the decrypted data isn't valid UTF-8
|
||||
#[inline]
|
||||
pub fn from_account(mut account: Account, master_pass: &str) -> crate::Result<Self> {
|
||||
pub fn from_account(mut account: Account, master_pass: &str) -> super::Result<Self> {
|
||||
let cipher = Cipher::new(master_pass.as_bytes(), &account.salt);
|
||||
cipher.decrypt(&mut account.enc_login)?;
|
||||
cipher.decrypt(&mut account.enc_password)?;
|
||||
@ -125,7 +125,7 @@ mod tests {
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn cipher_test() -> crate::Result<()> {
|
||||
fn cipher_test() -> crate::cryptography::Result<()> {
|
||||
const ORIGINAL: &[u8] = b"Data to protect";
|
||||
let mut data = ORIGINAL.to_owned();
|
||||
|
||||
@ -138,7 +138,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn account_encryption() -> crate::Result<()> {
|
||||
fn account_encryption() -> crate::cryptography::Result<()> {
|
||||
let original = Decrypted {
|
||||
name: "Account Name".to_owned(),
|
||||
login: "StrongLogin@mail.com".to_owned(),
|
||||
@ -157,7 +157,7 @@ mod tests {
|
||||
|
||||
assert!(matches!(
|
||||
CIPHER.decrypt(&mut bytes),
|
||||
Err(crate::Error::InvalidInputLength)
|
||||
Err(crate::cryptography::Error::InvalidInputLength)
|
||||
));
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
use entity::master_pass::MasterPass;
|
||||
use crate::entity::master_pass::MasterPass;
|
||||
use once_cell::sync::Lazy;
|
||||
use rand::{rngs::OsRng, RngCore};
|
||||
use scrypt::{scrypt, Params};
|
@ -2,15 +2,13 @@
|
||||
|
||||
pub mod account;
|
||||
pub mod hashing;
|
||||
pub mod master_pass;
|
||||
pub mod passwords;
|
||||
pub mod prelude;
|
||||
|
||||
/// Returns true if the field is valid
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn validate_field(field: &str) -> bool {
|
||||
if !(1..255).contains(&field.len()) {
|
||||
if field.len() > 255 {
|
||||
return false;
|
||||
}
|
||||
field
|
||||
@ -24,7 +22,7 @@ pub enum Error {
|
||||
InvalidInputLength,
|
||||
|
||||
#[error(transparent)]
|
||||
ChaChaError(#[from] chacha20poly1305::Error),
|
||||
ChaCha(#[from] chacha20poly1305::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
InvalidUTF8(#[from] std::string::FromUtf8Error),
|
@ -103,7 +103,7 @@ pub fn check_master_pass(password: &str) -> PasswordValidity {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::passwords::CHARS;
|
||||
use super::CHARS;
|
||||
|
||||
#[test]
|
||||
fn chars_must_be_ascii() {
|
@ -14,7 +14,7 @@ pub struct Account {
|
||||
impl Account {
|
||||
// Inserts the account into DB
|
||||
#[inline]
|
||||
pub async fn insert(&self, pool: &Pool) -> crate::Result<()> {
|
||||
pub async fn insert(&self, pool: &Pool) -> super::Result<()> {
|
||||
query!(
|
||||
"INSERT INTO account VALUES (?, ?, ?, ?, ?)",
|
||||
self.user_id,
|
||||
@ -30,7 +30,7 @@ impl Account {
|
||||
|
||||
/// Gets all user's account from DB
|
||||
#[inline]
|
||||
pub fn get_all(user_id: u64, pool: &Pool) -> impl Stream<Item = crate::Result<Self>> + '_ {
|
||||
pub fn get_all(user_id: u64, pool: &Pool) -> impl Stream<Item = super::Result<Self>> + '_ {
|
||||
query_as("SELECT * FROM account WHERE user_id = ?")
|
||||
.bind(user_id)
|
||||
.fetch(pool)
|
||||
@ -38,7 +38,7 @@ impl Account {
|
||||
|
||||
/// Streams the names of the user accounts
|
||||
#[inline]
|
||||
pub fn get_names(user_id: u64, pool: &Pool) -> impl Stream<Item = crate::Result<String>> + '_ {
|
||||
pub fn get_names(user_id: u64, pool: &Pool) -> impl Stream<Item = super::Result<String>> + '_ {
|
||||
query_as::<_, (String,)>("SELECT name FROM account WHERE user_id = ? ORDER BY name")
|
||||
.bind(user_id)
|
||||
.fetch(pool)
|
||||
@ -47,7 +47,7 @@ impl Account {
|
||||
|
||||
/// Checks if the account exists
|
||||
#[inline]
|
||||
pub async fn exists(user_id: u64, account_name: &str, pool: &Pool) -> crate::Result<bool> {
|
||||
pub async fn exists(user_id: u64, account_name: &str, pool: &Pool) -> super::Result<bool> {
|
||||
query_as::<_, (bool,)>(
|
||||
"SELECT EXISTS(SELECT * FROM account WHERE user_id = ? AND name = ? LIMIT 1) as value",
|
||||
)
|
||||
@ -60,7 +60,7 @@ impl Account {
|
||||
|
||||
/// Gets the account from the DB
|
||||
#[inline]
|
||||
pub async fn get(user_id: u64, account_name: &str, pool: &Pool) -> crate::Result<Option<Self>> {
|
||||
pub async fn get(user_id: u64, account_name: &str, pool: &Pool) -> super::Result<Option<Self>> {
|
||||
query_as("SELECT * FROM account WHERE user_id = ? AND name = ?")
|
||||
.bind(user_id)
|
||||
.bind(account_name)
|
||||
@ -70,7 +70,7 @@ impl Account {
|
||||
|
||||
// Deletes the account from DB
|
||||
#[inline]
|
||||
pub async fn delete(user_id: u64, name: &str, pool: &Pool) -> crate::Result<()> {
|
||||
pub async fn delete(user_id: u64, name: &str, pool: &Pool) -> super::Result<()> {
|
||||
query!(
|
||||
"DELETE FROM account WHERE user_id = ? AND name = ?",
|
||||
user_id,
|
||||
@ -86,7 +86,7 @@ impl Account {
|
||||
pub async fn delete_all(
|
||||
user_id: u64,
|
||||
pool: impl Executor<'_, Database = MySql>,
|
||||
) -> crate::Result<()> {
|
||||
) -> super::Result<()> {
|
||||
query!("DELETE FROM account WHERE user_id = ?", user_id)
|
||||
.execute(pool)
|
||||
.await
|
||||
@ -99,7 +99,7 @@ impl Account {
|
||||
user_id: u64,
|
||||
hash: &[u8],
|
||||
pool: &Pool,
|
||||
) -> crate::Result<Option<String>> {
|
||||
) -> super::Result<Option<String>> {
|
||||
let hash = hex::encode(hash);
|
||||
let name = query_as::<_, (String,)>(
|
||||
"SELECT `name` FROM `account` WHERE SHA2(`name`, 256) = ? AND `user_id` = ?;",
|
||||
@ -113,7 +113,7 @@ impl Account {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn get_salt(user_id: u64, name: &str, pool: &Pool) -> crate::Result<Option<Vec<u8>>> {
|
||||
pub async fn get_salt(user_id: u64, name: &str, pool: &Pool) -> super::Result<Option<Vec<u8>>> {
|
||||
let salt =
|
||||
query_as::<_, (Vec<u8>,)>("SELECT salt FROM account WHERE user_id = ? AND name = ?")
|
||||
.bind(user_id)
|
||||
@ -130,7 +130,7 @@ impl Account {
|
||||
original_name: &str,
|
||||
new_name: &str,
|
||||
pool: &Pool,
|
||||
) -> crate::Result<bool> {
|
||||
) -> super::Result<bool> {
|
||||
query!(
|
||||
"UPDATE account SET name = ? WHERE user_id = ? AND name = ?",
|
||||
new_name,
|
||||
@ -148,7 +148,7 @@ impl Account {
|
||||
name: &str,
|
||||
login: Vec<u8>,
|
||||
pool: &Pool,
|
||||
) -> crate::Result<bool> {
|
||||
) -> super::Result<bool> {
|
||||
query!(
|
||||
"UPDATE account SET enc_login = ? WHERE user_id = ? AND name = ?",
|
||||
login,
|
||||
@ -166,7 +166,7 @@ impl Account {
|
||||
name: &str,
|
||||
password: Vec<u8>,
|
||||
pool: &Pool,
|
||||
) -> crate::Result<bool> {
|
||||
) -> super::Result<bool> {
|
||||
query!(
|
||||
"UPDATE account SET enc_password = ? WHERE user_id = ? AND name = ?",
|
||||
password,
|
@ -28,7 +28,7 @@ impl From<LocaleType> for u8 {
|
||||
}
|
||||
|
||||
impl LocaleType {
|
||||
pub async fn get_from_db(user_id: u64, db: &Pool) -> crate::Result<Option<Self>> {
|
||||
pub async fn get_from_db(user_id: u64, db: &Pool) -> super::Result<Option<Self>> {
|
||||
let result: Option<(u8,)> = query_as("SELECT locale FROM master_pass WHERE user_id = ?")
|
||||
.bind(user_id)
|
||||
.fetch_optional(db)
|
||||
@ -36,7 +36,7 @@ impl LocaleType {
|
||||
Ok(result.and_then(|val| val.0.try_into().ok()))
|
||||
}
|
||||
|
||||
pub async fn update(self, user_id: u64, db: &Pool) -> crate::Result<bool> {
|
||||
pub async fn update(self, user_id: u64, db: &Pool) -> super::Result<bool> {
|
||||
let result: QueryResult = query!(
|
||||
"UPDATE master_pass SET locale = ? WHERE user_id = ?",
|
||||
u8::from(self),
|
@ -1,4 +1,4 @@
|
||||
use crate::{locale::LocaleType, Pool};
|
||||
use super::{locale::LocaleType, Pool};
|
||||
use sqlx::{prelude::FromRow, query, query_as, Executor, MySql};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, FromRow, Eq)]
|
||||
@ -11,7 +11,7 @@ pub struct MasterPass {
|
||||
impl MasterPass {
|
||||
// Inserts the master password into DB
|
||||
#[inline]
|
||||
pub async fn insert(&self, pool: &Pool, locale: LocaleType) -> crate::Result<()> {
|
||||
pub async fn insert(&self, pool: &Pool, locale: LocaleType) -> super::Result<()> {
|
||||
let locale: u8 = locale.into();
|
||||
query!(
|
||||
"INSERT INTO master_pass VALUES (?, ?, ?, ?)",
|
||||
@ -27,7 +27,7 @@ impl MasterPass {
|
||||
|
||||
/// Gets the master password from the database
|
||||
#[inline]
|
||||
pub async fn get(user_id: u64, pool: &Pool) -> crate::Result<Option<Self>> {
|
||||
pub async fn get(user_id: u64, pool: &Pool) -> super::Result<Option<Self>> {
|
||||
query_as("SELECT user_id, salt, password_hash FROM master_pass WHERE user_id = ?")
|
||||
.bind(user_id)
|
||||
.fetch_optional(pool)
|
||||
@ -36,7 +36,7 @@ impl MasterPass {
|
||||
|
||||
/// Checks if the master password for the user exists
|
||||
#[inline]
|
||||
pub async fn exists(user_id: u64, pool: &Pool) -> crate::Result<bool> {
|
||||
pub async fn exists(user_id: u64, pool: &Pool) -> super::Result<bool> {
|
||||
query_as::<_, (bool,)>(
|
||||
"SELECT EXISTS(SELECT * FROM master_pass WHERE user_id = ? LIMIT 1) as value",
|
||||
)
|
||||
@ -50,7 +50,7 @@ impl MasterPass {
|
||||
pub async fn remove(
|
||||
user_id: u64,
|
||||
pool: impl Executor<'_, Database = MySql>,
|
||||
) -> crate::Result<()> {
|
||||
) -> super::Result<()> {
|
||||
query!("DELETE FROM master_pass WHERE user_id = ?", user_id)
|
||||
.execute(pool)
|
||||
.await
|
@ -4,7 +4,6 @@
|
||||
pub mod account;
|
||||
pub mod locale;
|
||||
pub mod master_pass;
|
||||
pub mod prelude;
|
||||
|
||||
pub use sqlx::{mysql::MySqlPool as Pool, Result};
|
||||
|
37
src/main.rs
37
src/main.rs
@ -1,7 +1,9 @@
|
||||
mod callbacks;
|
||||
mod commands;
|
||||
mod cryptography;
|
||||
mod default;
|
||||
mod delete_mesage_handler;
|
||||
mod entity;
|
||||
mod errors;
|
||||
mod filter_user_info;
|
||||
mod locales;
|
||||
@ -13,18 +15,25 @@ mod prelude;
|
||||
mod state;
|
||||
|
||||
use anyhow::{Error, Result};
|
||||
use dotenvy::dotenv;
|
||||
use prelude::*;
|
||||
use std::{env, sync::Arc};
|
||||
use teloxide::{adaptors::throttle::Limits, dispatching::dialogue::InMemStorage, filter_command};
|
||||
|
||||
use crate::callbacks::CallbackCommand;
|
||||
|
||||
fn get_dispatcher(
|
||||
token: String,
|
||||
db: Pool,
|
||||
) -> Dispatcher<Throttle<Bot>, crate::Error, teloxide::dispatching::DefaultKey> {
|
||||
use dptree::{case, deps};
|
||||
db: prelude::Pool,
|
||||
) -> teloxide::prelude::Dispatcher<
|
||||
teloxide::adaptors::Throttle<teloxide::Bot>,
|
||||
crate::Error,
|
||||
teloxide::dispatching::DefaultKey,
|
||||
> {
|
||||
use callbacks::CallbackCommand;
|
||||
use commands::Command;
|
||||
use state::State;
|
||||
use teloxide::{
|
||||
adaptors::throttle::Limits,
|
||||
dispatching::dialogue::InMemStorage,
|
||||
dptree::{case, deps},
|
||||
filter_command,
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
let bot = Bot::new(token).throttle(Limits::default());
|
||||
|
||||
@ -73,28 +82,30 @@ fn get_dispatcher(
|
||||
.branch(case![CallbackCommand::ChangeLocale(locale)].endpoint(callbacks::change_locale));
|
||||
|
||||
let handler = dptree::entry()
|
||||
.map_async(Locale::from_update)
|
||||
.map_async(locales::Locale::from_update)
|
||||
.enter_dialogue::<Update, InMemStorage<State>, State>()
|
||||
.branch(message_handler)
|
||||
.branch(callback_handler);
|
||||
|
||||
Dispatcher::builder(bot, handler)
|
||||
.dependencies(deps![db, InMemStorage::<State>::new()])
|
||||
.error_handler(Arc::from(errors::ErrorHandler))
|
||||
.error_handler(std::sync::Arc::from(errors::ErrorHandler))
|
||||
.enable_ctrlc_handler()
|
||||
.build()
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let _ = dotenv();
|
||||
use std::env;
|
||||
|
||||
let _ = dotenvy::dotenv();
|
||||
errors::init_logger();
|
||||
|
||||
locales::LocaleStore::init();
|
||||
|
||||
let token = env::var("TOKEN").expect("expected TOKEN in the enviroment");
|
||||
let database_url = env::var("DATABASE_URL").expect("expected DATABASE_URL in the enviroment");
|
||||
let pool = Pool::connect(&database_url).await?;
|
||||
let pool = entity::Pool::connect(&database_url).await?;
|
||||
|
||||
entity::migrate(&pool).await?;
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
pub use crate::{
|
||||
commands::Command,
|
||||
pub(crate) use crate::cryptography::{
|
||||
self, account::Decrypted as DecryptedAccount, validate_field,
|
||||
};
|
||||
pub(crate) use crate::entity::{self, account::Account, master_pass::MasterPass, Pool};
|
||||
pub(crate) use crate::{
|
||||
errors::{handle_error, NoUserInfo},
|
||||
first_handler, handler,
|
||||
locales::{Locale, LocaleRef},
|
||||
locales::LocaleRef,
|
||||
markups::*,
|
||||
models::*,
|
||||
state::{Handler, MainDialogue, MessageIds, PackagedHandler, State},
|
||||
};
|
||||
pub use cryptography::prelude::*;
|
||||
pub use entity::{prelude::*, Pool};
|
||||
pub use futures::{StreamExt, TryStreamExt};
|
||||
pub use teloxide::{adaptors::Throttle, prelude::*};
|
||||
pub(crate) use futures::{StreamExt, TryStreamExt};
|
||||
pub(crate) use teloxide::{adaptors::Throttle, prelude::*};
|
||||
|
Loading…
Reference in New Issue
Block a user