Validate wallet address when creating new user

This commit is contained in:
silverpill 2022-01-31 19:10:51 +00:00
parent dfc9902092
commit 333f90e293
4 changed files with 39 additions and 12 deletions

View file

@ -4,12 +4,19 @@ use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uuid::Uuid; use uuid::Uuid;
use crate::errors::ValidationError;
use crate::models::profiles::types::{ use crate::models::profiles::types::{
DbActorProfile, DbActorProfile,
ExtraField, ExtraField,
ProfileUpdateData, ProfileUpdateData,
}; };
use crate::models::users::types::{User, UserCreateData}; use crate::models::profiles::validators::validate_username;
use crate::models::users::types::{
validate_local_username,
validate_wallet_address,
User,
UserCreateData,
};
use crate::utils::files::{FileError, save_validated_b64_file, get_file_url}; use crate::utils::files::{FileError, save_validated_b64_file, get_file_url};
#[derive(Serialize)] #[derive(Serialize)]
@ -106,6 +113,16 @@ pub struct AccountCreateData {
} }
impl AccountCreateData { impl AccountCreateData {
pub fn clean(&self) -> Result<(), ValidationError> {
validate_username(&self.username)?;
validate_local_username(&self.username)?;
if let Some(wallet_address) = self.wallet_address.as_ref() {
validate_wallet_address(wallet_address)?;
};
Ok(())
}
pub fn into_user_data( pub fn into_user_data(
self, self,
password_hash: String, password_hash: String,

View file

@ -40,7 +40,6 @@ use crate::models::users::queries::{
is_valid_invite_code, is_valid_invite_code,
create_user, create_user,
}; };
use crate::models::users::types::UserCreateData;
use crate::utils::crypto::{ use crate::utils::crypto::{
hash_password, hash_password,
generate_private_key, generate_private_key,
@ -62,7 +61,7 @@ pub async fn create_account(
) -> Result<HttpResponse, HttpError> { ) -> Result<HttpResponse, HttpError> {
let db_client = &mut **get_database_client(&db_pool).await?; let db_client = &mut **get_database_client(&db_pool).await?;
// Validate // Validate
UserCreateData::clean(&account_data.username)?; account_data.clean()?;
if !config.registrations_open { if !config.registrations_open {
let invite_code = account_data.invite_code.as_ref() let invite_code = account_data.invite_code.as_ref()
.ok_or(ValidationError("invite code is required"))?; .ok_or(ValidationError("invite code is required"))?;

View file

@ -31,6 +31,7 @@ async fn token_view(
"ethereum" => { "ethereum" => {
let wallet_address = request_data.wallet_address.as_ref() let wallet_address = request_data.wallet_address.as_ref()
.ok_or(ValidationError("wallet address is required"))?; .ok_or(ValidationError("wallet address is required"))?;
// Wallet address must be in lowercase
get_user_by_wallet_address(db_client, wallet_address).await? get_user_by_wallet_address(db_client, wallet_address).await?
}, },
_ => { _ => {

View file

@ -5,7 +5,6 @@ use uuid::Uuid;
use crate::errors::ValidationError; use crate::errors::ValidationError;
use crate::models::profiles::types::DbActorProfile; use crate::models::profiles::types::DbActorProfile;
use crate::models::profiles::validators::validate_username;
#[derive(FromSql)] #[derive(FromSql)]
#[postgres(name = "user_account")] #[postgres(name = "user_account")]
@ -54,7 +53,7 @@ pub struct UserCreateData {
pub invite_code: Option<String>, pub invite_code: Option<String>,
} }
fn validate_local_username(username: &str) -> Result<(), ValidationError> { pub fn validate_local_username(username: &str) -> Result<(), ValidationError> {
// The username regexp should not allow domain names and IP addresses // The username regexp should not allow domain names and IP addresses
let username_regexp = Regex::new(r"^[a-z0-9_]+$").unwrap(); let username_regexp = Regex::new(r"^[a-z0-9_]+$").unwrap();
if !username_regexp.is_match(username) { if !username_regexp.is_match(username) {
@ -63,13 +62,14 @@ fn validate_local_username(username: &str) -> Result<(), ValidationError> {
Ok(()) Ok(())
} }
impl UserCreateData { /// Verifies that wallet address is valid ethereum address
/// Validate and clean. pub fn validate_wallet_address(wallet_address: &str) -> Result<(), ValidationError> {
pub fn clean(username: &str) -> Result<(), ValidationError> { // Address should be lowercase
validate_username(username)?; let address_regexp = Regex::new(r"^0x[a-f0-9]{40}$").unwrap();
validate_local_username(username)?; if !address_regexp.is_match(wallet_address) {
Ok(()) return Err(ValidationError("address is not lowercase"));
} };
Ok(())
} }
#[cfg(test)] #[cfg(test)]
@ -83,4 +83,14 @@ mod tests {
let result_2 = validate_local_username("name&"); let result_2 = validate_local_username("name&");
assert_eq!(result_2.is_ok(), false); assert_eq!(result_2.is_ok(), false);
} }
#[test]
fn test_validate_wallet_address() {
let result_1 = validate_wallet_address("0xab5801a7d398351b8be11c439e05c5b3259aec9b");
assert_eq!(result_1.is_ok(), true);
let result_2 = validate_wallet_address("ab5801a7d398351b8be11c439e05c5b3259aec9b");
assert_eq!(result_2.is_ok(), false);
let result_3 = validate_wallet_address("0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B");
assert_eq!(result_3.is_ok(), false);
}
} }