Improve ethereum address validation and move validator to ethereum::utils module
This commit is contained in:
parent
44d013bc5e
commit
0988c0c91e
4 changed files with 46 additions and 38 deletions
|
@ -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",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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" => {
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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(ð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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue