Improve ethereum address validation and move validator to ethereum::utils module

This commit is contained in:
silverpill 2023-02-12 18:14:05 +00:00
parent 44d013bc5e
commit 0988c0c91e
4 changed files with 46 additions and 38 deletions

View file

@ -1,11 +1,14 @@
use std::str::FromStr; use std::str::FromStr;
use regex::Regex;
use secp256k1::SecretKey; use secp256k1::SecretKey;
use web3::{ use web3::{
signing::Key, signing::Key,
types::Address, types::Address,
}; };
use crate::errors::ValidationError;
pub fn key_to_ethereum_address(private_key: &SecretKey) -> Address { pub fn key_to_ethereum_address(private_key: &SecretKey) -> Address {
private_key.address() private_key.address()
} }
@ -22,3 +25,38 @@ pub fn parse_address(address: &str) -> Result<Address, AddressError> {
pub fn address_to_string(address: Address) -> String { pub fn address_to_string(address: Address) -> String {
format!("{:#x}", address) format!("{:#x}", address)
} }
pub fn validate_ethereum_address(
wallet_address: &str,
) -> Result<(), ValidationError> {
let address_regexp = Regex::new(r"^0x[a-fA-F0-9]{40}$").unwrap();
if !address_regexp.is_match(wallet_address) {
return Err(ValidationError("invalid address"));
};
// Address should be lowercase
if wallet_address.to_lowercase() != wallet_address {
return Err(ValidationError("address is not lowercase"));
};
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_validate_ethereum_address() {
let result_1 = validate_ethereum_address("0xab5801a7d398351b8be11c439e05c5b3259aec9b");
assert_eq!(result_1.is_ok(), true);
let result_2 = validate_ethereum_address("ab5801a7d398351b8be11c439e05c5b3259aec9b");
assert_eq!(
result_2.err().unwrap().to_string(),
"invalid address",
);
let result_3 = validate_ethereum_address("0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B");
assert_eq!(
result_3.err().unwrap().to_string(),
"address is not lowercase",
);
}
}

View file

@ -13,7 +13,10 @@ use chrono::{Duration, Utc};
use crate::config::Config; use crate::config::Config;
use crate::database::{get_database_client, DatabaseError, DbPool}; use crate::database::{get_database_client, DatabaseError, DbPool};
use crate::errors::{HttpError, ValidationError}; use crate::errors::{HttpError, ValidationError};
use crate::ethereum::eip4361::verify_eip4361_signature; use crate::ethereum::{
eip4361::verify_eip4361_signature,
utils::validate_ethereum_address,
};
use crate::models::oauth::queries::{ use crate::models::oauth::queries::{
create_oauth_authorization, create_oauth_authorization,
delete_oauth_token, delete_oauth_token,
@ -25,7 +28,6 @@ use crate::models::users::queries::{
get_user_by_name, get_user_by_name,
get_user_by_login_address, get_user_by_login_address,
}; };
use crate::utils::currencies::{validate_wallet_address, Currency};
use crate::utils::passwords::verify_password; use crate::utils::passwords::verify_password;
use super::auth::get_current_user; use super::auth::get_current_user;
use super::types::{ use super::types::{
@ -138,7 +140,7 @@ async fn token_view(
// DEPRECATED // DEPRECATED
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"))?;
validate_wallet_address(&Currency::Ethereum, wallet_address)?; validate_ethereum_address(wallet_address)?;
get_user_by_login_address(db_client, wallet_address).await? get_user_by_login_address(db_client, wallet_address).await?
}, },
"eip4361" => { "eip4361" => {

View file

@ -15,6 +15,7 @@ use crate::activitypub::{
use crate::config::Config; use crate::config::Config;
use crate::database::{DatabaseClient, DatabaseError}; use crate::database::{DatabaseClient, DatabaseError};
use crate::errors::ValidationError; use crate::errors::ValidationError;
use crate::ethereum::utils::validate_ethereum_address;
use crate::identity::did::Did; use crate::identity::did::Did;
use crate::models::posts::{ use crate::models::posts::{
helpers::{can_view_post, get_local_post_by_id}, helpers::{can_view_post, get_local_post_by_id},
@ -31,7 +32,7 @@ use crate::models::users::{
queries::get_user_by_name, queries::get_user_by_name,
types::User, types::User,
}; };
use crate::utils::currencies::{validate_wallet_address, Currency}; use crate::utils::currencies::Currency;
use crate::webfinger::types::ActorAddress; use crate::webfinger::types::ActorAddress;
enum SearchQuery { enum SearchQuery {
@ -79,8 +80,7 @@ fn parse_search_query(search_query: &str) -> SearchQuery {
return SearchQuery::Url(search_query.to_string()); return SearchQuery::Url(search_query.to_string());
}; };
// TODO: support other currencies // TODO: support other currencies
if validate_wallet_address( if validate_ethereum_address(
&Currency::Ethereum,
&search_query.to_lowercase(), &search_query.to_lowercase(),
).is_ok() { ).is_ok() {
return SearchQuery::WalletAddress(search_query.to_string()); return SearchQuery::WalletAddress(search_query.to_string());

View file

@ -1,7 +1,3 @@
use regex::Regex;
use crate::errors::ValidationError;
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum Currency { pub enum Currency {
Ethereum, Ethereum,
@ -28,23 +24,6 @@ impl Currency {
} }
} }
pub fn validate_wallet_address(
currency: &Currency,
wallet_address: &str,
) -> Result<(), ValidationError> {
match currency {
Currency::Ethereum => {
// Address should be lowercase
let address_regexp = Regex::new(r"^0x[a-f0-9]{40}$").unwrap();
if !address_regexp.is_match(wallet_address) {
return Err(ValidationError("address is not lowercase"));
};
},
Currency::Monero => (), // no validation
};
Ok(())
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -54,15 +33,4 @@ mod tests {
let ethereum = Currency::Ethereum; let ethereum = Currency::Ethereum;
assert_eq!(ethereum.field_name(), "$ETH"); assert_eq!(ethereum.field_name(), "$ETH");
} }
#[test]
fn test_validate_wallet_address() {
let ethereum = Currency::Ethereum;
let result_1 = validate_wallet_address(&ethereum, "0xab5801a7d398351b8be11c439e05c5b3259aec9b");
assert_eq!(result_1.is_ok(), true);
let result_2 = validate_wallet_address(&ethereum, "ab5801a7d398351b8be11c439e05c5b3259aec9b");
assert_eq!(result_2.is_ok(), false);
let result_3 = validate_wallet_address(&ethereum, "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B");
assert_eq!(result_3.is_ok(), false);
}
} }