Updated GetUsers to provide better inforamtion about invalid accounts to a user
This commit is contained in:
parent
d7a049f211
commit
be76b09427
50
Cargo.lock
generated
50
Cargo.lock
generated
@ -57,9 +57,9 @@ checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "allocator-api2"
|
name = "allocator-api2"
|
||||||
version = "0.2.14"
|
version = "0.2.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c4f263788a35611fba42eb41ff811c5d0360c58b97402570312a350736e2542e"
|
checksum = "56fc6cf8dc8c4158eed8649f9b8b0ea1518eb62b544fe9490d66fa0b349eafe9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "android-tzdata"
|
name = "android-tzdata"
|
||||||
@ -97,9 +97,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
version = "0.7.3"
|
version = "0.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8868f09ff8cea88b079da74ae569d9b8c62a23c68c746240b704ee6f7525c89c"
|
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-stream"
|
name = "async-stream"
|
||||||
@ -383,9 +383,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpufeatures"
|
name = "cpufeatures"
|
||||||
version = "0.2.7"
|
version = "0.2.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58"
|
checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
@ -930,7 +930,7 @@ checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"http",
|
"http",
|
||||||
"hyper",
|
"hyper",
|
||||||
"rustls 0.21.1",
|
"rustls 0.21.2",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-rustls 0.24.1",
|
"tokio-rustls 0.24.1",
|
||||||
]
|
]
|
||||||
@ -1351,6 +1351,7 @@ dependencies = [
|
|||||||
"teloxide",
|
"teloxide",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"trim-in-place",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1675,7 +1676,7 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustls 0.21.1",
|
"rustls 0.21.2",
|
||||||
"rustls-pemfile",
|
"rustls-pemfile",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@ -1758,9 +1759,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust_decimal"
|
name = "rust_decimal"
|
||||||
version = "1.29.1"
|
version = "1.30.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "26bd36b60561ee1fb5ec2817f198b6fd09fa571c897a5e86d1487cfc2b096dfc"
|
checksum = "d0446843641c69436765a35a5a77088e28c2e6a12da93e84aa3ab1cd4aa5a042"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"borsh",
|
"borsh",
|
||||||
@ -1811,9 +1812,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.21.1"
|
version = "0.21.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e"
|
checksum = "e32ca28af694bc1bbf399c33a516dbdf1c90090b8ab23c2bc24f834aa2247f5f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"ring",
|
"ring",
|
||||||
@ -2067,9 +2068,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.96"
|
version = "1.0.97"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
|
checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
@ -2113,9 +2114,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha2"
|
name = "sha2"
|
||||||
version = "0.10.6"
|
version = "0.10.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
|
checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cpufeatures",
|
"cpufeatures",
|
||||||
@ -2552,7 +2553,7 @@ version = "0.24.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
|
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustls 0.21.1",
|
"rustls 0.21.2",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2611,9 +2612,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-attributes"
|
name = "tracing-attributes"
|
||||||
version = "0.1.24"
|
version = "0.1.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74"
|
checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -2644,6 +2645,12 @@ dependencies = [
|
|||||||
"tracing-core",
|
"tracing-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "trim-in-place"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "try-lock"
|
name = "try-lock"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
@ -2750,11 +2757,10 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "want"
|
name = "want"
|
||||||
version = "0.3.0"
|
version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
|
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
|
||||||
"try-lock",
|
"try-lock",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -29,3 +29,4 @@ serde_json = "1.0.96"
|
|||||||
teloxide = { version = "0.12.2", features = ["macros", "ctrlc_handler", "rustls", "throttle"], default-features = false }
|
teloxide = { version = "0.12.2", features = ["macros", "ctrlc_handler", "rustls", "throttle"], default-features = false }
|
||||||
thiserror = "1.0.40"
|
thiserror = "1.0.40"
|
||||||
tokio = { version = "1.28.1", features = ["macros", "rt-multi-thread"] }
|
tokio = { version = "1.28.1", features = ["macros", "rt-multi-thread"] }
|
||||||
|
trim-in-place = "0.1.7"
|
||||||
|
@ -45,9 +45,13 @@ impl DecryptedAccount {
|
|||||||
/// Returns true if the account's fields are valid
|
/// Returns true if the account's fields are valid
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn validate(&self) -> bool {
|
pub fn validate(&self) -> bool {
|
||||||
[&self.name, &self.login, &self.password]
|
[
|
||||||
|
self.name.as_str(),
|
||||||
|
self.login.as_str(),
|
||||||
|
self.password.as_str(),
|
||||||
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.all(|field| validate_field(field))
|
.all(validate_field)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,91 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
errors::HandlerUsed, markups::deletion_markup, models::User, utils::delete_optional,
|
errors::HandlerUsed,
|
||||||
|
markups::deletion_markup,
|
||||||
|
models::{DecryptedAccount, User},
|
||||||
|
utils::delete_optional,
|
||||||
MainDialogue,
|
MainDialogue,
|
||||||
};
|
};
|
||||||
use futures::TryStreamExt;
|
use futures::TryStreamExt;
|
||||||
|
use itertools::Itertools;
|
||||||
use sea_orm::prelude::*;
|
use sea_orm::prelude::*;
|
||||||
use teloxide::{adaptors::Throttle, net::Download, prelude::*};
|
use std::fmt::Write;
|
||||||
|
use teloxide::{adaptors::Throttle, net::Download, prelude::*, types::Document};
|
||||||
use tokio::task::spawn_blocking;
|
use tokio::task::spawn_blocking;
|
||||||
|
use trim_in_place::TrimInPlace;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
async fn download_file(bot: &Throttle<Bot>, document: &Document) -> crate::Result<Vec<u8>> {
|
||||||
|
let path = bot.get_file(document.file.id.as_str()).await?.path;
|
||||||
|
let mut data = Vec::with_capacity(document.file.size as usize);
|
||||||
|
bot.download_file_stream(&path)
|
||||||
|
.try_for_each(|bytes| {
|
||||||
|
data.extend(bytes);
|
||||||
|
async { Ok(()) }
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
Ok(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn process_accounts(accounts: &mut [DecryptedAccount]) -> crate::Result<Result<(), String>> {
|
||||||
|
for account in accounts.iter_mut() {
|
||||||
|
account.name.trim_in_place();
|
||||||
|
account.login.trim_in_place();
|
||||||
|
account.password.trim_in_place();
|
||||||
|
}
|
||||||
|
|
||||||
|
accounts.sort_unstable_by(|a, b| a.name.cmp(&b.name));
|
||||||
|
|
||||||
|
let mut duplicates = Vec::new();
|
||||||
|
let mut invalid = Vec::new();
|
||||||
|
|
||||||
|
accounts
|
||||||
|
.iter()
|
||||||
|
.dedup_by_with_count(|a, b| a.name == b.name)
|
||||||
|
.for_each(|(count, account)| {
|
||||||
|
if count != 1 {
|
||||||
|
duplicates.push(account.name.as_str());
|
||||||
|
} else if !account.validate() {
|
||||||
|
invalid.push(account.name.as_str());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if duplicates.is_empty() && invalid.is_empty() {
|
||||||
|
return Ok(Ok(()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut error_text = "Your accounts have the following problems:".to_owned();
|
||||||
|
|
||||||
|
if !duplicates.is_empty() {
|
||||||
|
write!(
|
||||||
|
error_text,
|
||||||
|
"\n\nDuplicate names:\n{:?}",
|
||||||
|
duplicates.into_iter().format("\n")
|
||||||
|
)?
|
||||||
|
}
|
||||||
|
|
||||||
|
if !invalid.is_empty() {
|
||||||
|
write!(
|
||||||
|
error_text,
|
||||||
|
"\n\nInvalid account fields:\n{:?}",
|
||||||
|
invalid.into_iter().format("\n")
|
||||||
|
)?
|
||||||
|
}
|
||||||
|
|
||||||
|
error_text.push_str("\n\nFix these problems and send the file again");
|
||||||
|
|
||||||
|
Ok(Err(error_text))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn user_from_vec(vector: Vec<u8>) -> crate::Result<Result<User, String>> {
|
||||||
|
let mut user: User = serde_json::from_slice(&vector)?;
|
||||||
|
drop(vector);
|
||||||
|
match process_accounts(&mut user.accounts)? {
|
||||||
|
Ok(()) => Ok(Ok(user)),
|
||||||
|
Err(error_text) => Ok(Err(error_text)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Function to handle GetUser state. It doesn't actually validate anything
|
/// Function to handle GetUser state. It doesn't actually validate anything
|
||||||
pub async fn get_user(
|
pub async fn get_user(
|
||||||
@ -56,17 +136,15 @@ pub async fn get_user(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let file = bot.get_file(&document.file.id).await?;
|
let data = download_file(&bot, document).await?;
|
||||||
let mut data = Vec::with_capacity(document.file.size as usize);
|
|
||||||
bot.download_file_stream(&file.path)
|
|
||||||
.try_for_each(|bytes| {
|
|
||||||
data.extend(bytes);
|
|
||||||
async { Ok(()) }
|
|
||||||
})
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let user: User = match spawn_blocking(move || serde_json::from_slice(&data)).await? {
|
let user = match spawn_blocking(move || user_from_vec(data)).await? {
|
||||||
Ok(user) => user,
|
Ok(Ok(user)) => user,
|
||||||
|
Ok(Err(error_text)) => {
|
||||||
|
let msg = bot.send_message(msg.chat.id, error_text).await?;
|
||||||
|
handler.previous = Some(msg);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let msg = bot
|
let msg = bot
|
||||||
.send_message(msg.chat.id, "Error parsing the json file. Try again")
|
.send_message(msg.chat.id, "Error parsing the json file. Try again")
|
||||||
|
@ -17,7 +17,10 @@ pub async fn delete_optional(bot: &Throttle<Bot>, msg: Option<&Message>) {
|
|||||||
/// Returns true if the field is valid
|
/// Returns true if the field is valid
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn validate_field(field: &str) -> bool {
|
pub fn validate_field(field: &str) -> bool {
|
||||||
|
if field.is_empty() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
field
|
field
|
||||||
.chars()
|
.chars()
|
||||||
.all(|char| char != '`' && char != '\\' && char != '\n')
|
.all(|char| !['`', '\\', '\n', '\t'].contains(&char))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user