diff --git a/src/ethereum/utils.rs b/src/ethereum/utils.rs index 233713a..ee9d253 100644 --- a/src/ethereum/utils.rs +++ b/src/ethereum/utils.rs @@ -1,11 +1,14 @@ use std::str::FromStr; +use regex::Regex; use secp256k1::SecretKey; use web3::{ signing::Key, types::Address, }; +use crate::errors::ValidationError; + pub fn key_to_ethereum_address(private_key: &SecretKey) -> Address { private_key.address() } @@ -22,3 +25,38 @@ pub fn parse_address(address: &str) -> Result { pub fn address_to_string(address: Address) -> String { 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", + ); + } +} diff --git a/src/mastodon_api/oauth/views.rs b/src/mastodon_api/oauth/views.rs index 24adf9d..4f0a34d 100644 --- a/src/mastodon_api/oauth/views.rs +++ b/src/mastodon_api/oauth/views.rs @@ -13,7 +13,10 @@ use chrono::{Duration, Utc}; use crate::config::Config; use crate::database::{get_database_client, DatabaseError, DbPool}; 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::{ create_oauth_authorization, delete_oauth_token, @@ -25,7 +28,6 @@ use crate::models::users::queries::{ get_user_by_name, get_user_by_login_address, }; -use crate::utils::currencies::{validate_wallet_address, Currency}; use crate::utils::passwords::verify_password; use super::auth::get_current_user; use super::types::{ @@ -138,7 +140,7 @@ async fn token_view( // DEPRECATED let wallet_address = request_data.wallet_address.as_ref() .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? }, "eip4361" => { diff --git a/src/mastodon_api/search/helpers.rs b/src/mastodon_api/search/helpers.rs index 1d26b83..6fe783e 100644 --- a/src/mastodon_api/search/helpers.rs +++ b/src/mastodon_api/search/helpers.rs @@ -15,6 +15,7 @@ use crate::activitypub::{ use crate::config::Config; use crate::database::{DatabaseClient, DatabaseError}; use crate::errors::ValidationError; +use crate::ethereum::utils::validate_ethereum_address; use crate::identity::did::Did; use crate::models::posts::{ helpers::{can_view_post, get_local_post_by_id}, @@ -31,7 +32,7 @@ use crate::models::users::{ queries::get_user_by_name, types::User, }; -use crate::utils::currencies::{validate_wallet_address, Currency}; +use crate::utils::currencies::Currency; use crate::webfinger::types::ActorAddress; enum SearchQuery { @@ -79,8 +80,7 @@ fn parse_search_query(search_query: &str) -> SearchQuery { return SearchQuery::Url(search_query.to_string()); }; // TODO: support other currencies - if validate_wallet_address( - &Currency::Ethereum, + if validate_ethereum_address( &search_query.to_lowercase(), ).is_ok() { return SearchQuery::WalletAddress(search_query.to_string()); diff --git a/src/utils/currencies.rs b/src/utils/currencies.rs index 2bf0546..695b6d1 100644 --- a/src/utils/currencies.rs +++ b/src/utils/currencies.rs @@ -1,7 +1,3 @@ -use regex::Regex; - -use crate::errors::ValidationError; - #[derive(Debug, PartialEq)] pub enum Currency { 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)] mod tests { use super::*; @@ -54,15 +33,4 @@ mod tests { let ethereum = Currency::Ethereum; assert_eq!(ethereum.field_name(), "$ETH"); } - - #[test] - fn test_validate_wallet_address() { - let ethereum = Currency::Ethereum; - let result_1 = validate_wallet_address(ðereum, "0xab5801a7d398351b8be11c439e05c5b3259aec9b"); - assert_eq!(result_1.is_ok(), true); - let result_2 = validate_wallet_address(ðereum, "ab5801a7d398351b8be11c439e05c5b3259aec9b"); - assert_eq!(result_2.is_ok(), false); - let result_3 = validate_wallet_address(ðereum, "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B"); - assert_eq!(result_3.is_ok(), false); - } }