fix: username and community title validation
This commit is contained in:
parent
a4d7f44aa3
commit
efb259764e
7 changed files with 79 additions and 25 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3324,6 +3324,7 @@ dependencies = [
|
||||||
"md-5",
|
"md-5",
|
||||||
"pathbufd",
|
"pathbufd",
|
||||||
"redis",
|
"redis",
|
||||||
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
@ -167,7 +167,7 @@ pub fn save_buffer(path: &str, bytes: Vec<u8>, format: image::ImageFormat) -> st
|
||||||
const WEBP_ENCODE_QUALITY: f32 = 85.0;
|
const WEBP_ENCODE_QUALITY: f32 = 85.0;
|
||||||
|
|
||||||
/// Create a WEBP image buffer given an input of `bytes`.
|
/// Create a WEBP image buffer given an input of `bytes`.
|
||||||
pub fn save_webp_buffer(path: &str, bytes: Vec<u8>) -> std::io::Result<()> {
|
pub fn save_webp_buffer(path: &str, bytes: Vec<u8>, quality: Option<f32>) -> std::io::Result<()> {
|
||||||
let img = match image::load_from_memory(&bytes) {
|
let img = match image::load_from_memory(&bytes) {
|
||||||
Ok(i) => i,
|
Ok(i) => i,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
@ -188,7 +188,10 @@ pub fn save_webp_buffer(path: &str, bytes: Vec<u8>) -> std::io::Result<()> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mem = encoder.encode(WEBP_ENCODE_QUALITY);
|
let mem = encoder.encode(match quality {
|
||||||
|
Some(q) => q,
|
||||||
|
None => WEBP_ENCODE_QUALITY,
|
||||||
|
});
|
||||||
|
|
||||||
if std::fs::write(path, &*mem).is_err() {
|
if std::fs::write(path, &*mem).is_err() {
|
||||||
return Err(std::io::Error::new(
|
return Err(std::io::Error::new(
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
use std::fs::exists;
|
use std::fs::exists;
|
||||||
|
|
||||||
use image::ImageFormat;
|
|
||||||
use pathbufd::PathBufD;
|
use pathbufd::PathBufD;
|
||||||
use crate::{
|
use crate::{
|
||||||
get_user_from_token,
|
get_user_from_token,
|
||||||
image::{save_buffer, Image},
|
image::{save_webp_buffer, Image},
|
||||||
routes::api::v1::{auth::images::read_image, UpdateEmojiName},
|
routes::api::v1::{auth::images::read_image, UpdateEmojiName},
|
||||||
State,
|
State,
|
||||||
};
|
};
|
||||||
|
@ -146,11 +144,9 @@ pub async fn create_request(
|
||||||
return Json(Error::MiscError(e.to_string()).into());
|
return Json(Error::MiscError(e.to_string()).into());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Err(e) = save_buffer(
|
if let Err(e) =
|
||||||
&upload.path(&data.0).to_string(),
|
save_webp_buffer(&upload.path(&data.0).to_string(), img.0.to_vec(), None)
|
||||||
img.0.to_vec(),
|
{
|
||||||
ImageFormat::WebP,
|
|
||||||
) {
|
|
||||||
return Json(Error::MiscError(e.to_string()).into());
|
return Json(Error::MiscError(e.to_string()).into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,8 @@ pub async fn create_request(
|
||||||
Err(e) => return Json(e.into()),
|
Err(e) => return Json(e.into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(e) = save_webp_buffer(&upload.path(&data.0).to_string(), image.to_vec())
|
if let Err(e) =
|
||||||
|
save_webp_buffer(&upload.path(&data.0).to_string(), image.to_vec(), None)
|
||||||
{
|
{
|
||||||
return Json(Error::MiscError(e.to_string()).into());
|
return Json(Error::MiscError(e.to_string()).into());
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,3 +34,4 @@ tokio-postgres = { version = "0.7.13", optional = true }
|
||||||
bb8-postgres = { version = "0.9.0", optional = true }
|
bb8-postgres = { version = "0.9.0", optional = true }
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
emojis = "0.6.4"
|
emojis = "0.6.4"
|
||||||
|
regex = "1.11.1"
|
||||||
|
|
|
@ -128,14 +128,15 @@ impl DataManager {
|
||||||
return Err(Error::MiscError("This username cannot be used".to_string()));
|
return Err(Error::MiscError("This username cannot be used".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if data.username.contains(" ") {
|
let regex = regex::RegexBuilder::new(r"[^\w_\-\.!]+")
|
||||||
return Err(Error::MiscError("Name cannot contain spaces".to_string()));
|
.multi_line(true)
|
||||||
} else if data.username.contains("%") {
|
.build()
|
||||||
return Err(Error::MiscError("Name cannot contain \"%\"".to_string()));
|
.unwrap();
|
||||||
} else if data.username.contains("?") {
|
|
||||||
return Err(Error::MiscError("Name cannot contain \"?\"".to_string()));
|
if regex.captures(&data.username).is_some() {
|
||||||
} else if data.username.contains("&") {
|
return Err(Error::MiscError(
|
||||||
return Err(Error::MiscError("Name cannot contain \"&\"".to_string()));
|
"This username contains invalid characters".to_string(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure username isn't taken
|
// make sure username isn't taken
|
||||||
|
@ -436,6 +437,29 @@ impl DataManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_user_username(&self, id: usize, to: String, user: User) -> Result<()> {
|
pub async fn update_user_username(&self, id: usize, to: String, user: User) -> Result<()> {
|
||||||
|
// check value
|
||||||
|
if to.len() < 2 {
|
||||||
|
return Err(Error::DataTooShort("username".to_string()));
|
||||||
|
} else if to.len() > 32 {
|
||||||
|
return Err(Error::DataTooLong("username".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.0.banned_usernames.contains(&to) {
|
||||||
|
return Err(Error::MiscError("This username cannot be used".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let regex = regex::RegexBuilder::new(r"[^\w_\-\.!]+")
|
||||||
|
.multi_line(true)
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if regex.captures(&to).is_some() {
|
||||||
|
return Err(Error::MiscError(
|
||||||
|
"This username contains invalid characters".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...
|
||||||
let conn = match self.connect().await {
|
let conn = match self.connect().await {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||||
|
|
|
@ -209,16 +209,21 @@ impl DataManager {
|
||||||
return Err(Error::DataTooLong("title".to_string()));
|
return Err(Error::DataTooLong("title".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !data.title.is_ascii() | data.title.contains(" ") {
|
|
||||||
return Err(Error::MiscError(
|
|
||||||
"Title contains characters which aren't allowed".to_string(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.0.banned_usernames.contains(&data.title) {
|
if self.0.banned_usernames.contains(&data.title) {
|
||||||
return Err(Error::MiscError("This title cannot be used".to_string()));
|
return Err(Error::MiscError("This title cannot be used".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let regex = regex::RegexBuilder::new(r"[^\w_\-\.!]+")
|
||||||
|
.multi_line(true)
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if regex.captures(&data.title).is_some() {
|
||||||
|
return Err(Error::MiscError(
|
||||||
|
"This title contains invalid characters".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
// check number of communities
|
// check number of communities
|
||||||
let owner = self.get_user_by_id(data.owner).await?;
|
let owner = self.get_user_by_id(data.owner).await?;
|
||||||
|
|
||||||
|
@ -382,6 +387,29 @@ impl DataManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_community_title(&self, id: usize, user: User, title: &str) -> Result<()> {
|
pub async fn update_community_title(&self, id: usize, user: User, title: &str) -> Result<()> {
|
||||||
|
// check values
|
||||||
|
if title.len() < 2 {
|
||||||
|
return Err(Error::DataTooShort("title".to_string()));
|
||||||
|
} else if title.len() > 32 {
|
||||||
|
return Err(Error::DataTooLong("title".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.0.banned_usernames.contains(&title.to_string()) {
|
||||||
|
return Err(Error::MiscError("This title cannot be used".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let regex = regex::RegexBuilder::new(r"[^\w_\-\.!]+")
|
||||||
|
.multi_line(true)
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if regex.captures(&title).is_some() {
|
||||||
|
return Err(Error::MiscError(
|
||||||
|
"This title contains invalid characters".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...
|
||||||
let y = self.get_community_by_id(id).await?;
|
let y = self.get_community_by_id(id).await?;
|
||||||
|
|
||||||
if user.id != y.owner {
|
if user.id != y.owner {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue