From 9115419ec08358e10a9be9e8f21a59e6285f0c9a Mon Sep 17 00:00:00 2001 From: Bryan Stitt Date: Sat, 24 Jun 2023 10:20:24 -0700 Subject: [PATCH] handle addresses consistently --- web3_proxy/src/admin_queries.rs | 8 +++--- .../bin/web3_proxy_cli/change_admin_status.rs | 9 +++---- .../bin/web3_proxy_cli/change_user_address.rs | 13 +++------- .../change_user_tier_by_address.rs | 4 +-- .../src/bin/web3_proxy_cli/create_key.rs | 22 ++-------------- .../src/bin/web3_proxy_cli/rpc_accounting.rs | 4 +-- .../src/bin/web3_proxy_cli/transfer_key.rs | 4 +-- .../src/bin/web3_proxy_cli/user_import.rs | 2 +- web3_proxy/src/frontend/admin.rs | 26 +++++++------------ web3_proxy/src/frontend/users/payment.rs | 2 +- 10 files changed, 27 insertions(+), 67 deletions(-) diff --git a/web3_proxy/src/admin_queries.rs b/web3_proxy/src/admin_queries.rs index 3ec8bf1a..e720a76b 100644 --- a/web3_proxy/src/admin_queries.rs +++ b/web3_proxy/src/admin_queries.rs @@ -26,7 +26,7 @@ pub async fn query_admin_modify_usertier<'a>( params: &'a HashMap, ) -> Web3ProxyResponse { // Quickly return if any of the input tokens are bad - let user_address: Vec = params + let user_address = params .get("user_address") .ok_or_else(|| { Web3ProxyError::BadRequest("Unable to find user_address key in request".into()) @@ -34,9 +34,7 @@ pub async fn query_admin_modify_usertier<'a>( .parse::
() .map_err(|_| { Web3ProxyError::BadRequest("Unable to parse user_address as an Address".into()) - })? - .to_fixed_bytes() - .into(); + })?; let user_tier_title = params.get("user_tier_title").ok_or_else(|| { Web3ProxyError::BadRequest("Unable to get the user_tier_title key from the request".into()) })?; @@ -78,7 +76,7 @@ pub async fn query_admin_modify_usertier<'a>( // Fetch the admin, and the user let user: user::Model = user::Entity::find() - .filter(user::Column::Address.eq(user_address)) + .filter(user::Column::Address.eq(user_address.as_bytes())) .one(&db_conn) .await? .ok_or(Web3ProxyError::BadRequest( diff --git a/web3_proxy/src/bin/web3_proxy_cli/change_admin_status.rs b/web3_proxy/src/bin/web3_proxy_cli/change_admin_status.rs index fb072cb3..9c6cbbf0 100644 --- a/web3_proxy/src/bin/web3_proxy_cli/change_admin_status.rs +++ b/web3_proxy/src/bin/web3_proxy_cli/change_admin_status.rs @@ -26,15 +26,12 @@ impl ChangeAdminStatusSubCommand { let address: Address = self.address.parse()?; let should_be_admin: bool = self.should_be_admin; - // we keep "address" around for use in logs - let address_vec: Vec = address.to_fixed_bytes().into(); - // Find user in database let user = user::Entity::find() - .filter(user::Column::Address.eq(address_vec)) + .filter(user::Column::Address.eq(address.as_bytes())) .one(db_conn) .await? - .context(format!("No user with this id found {:?}", address))?; + .context(format!("No user with this address found {:?}", address))?; debug!("user: {:#}", json!(&user)); @@ -59,7 +56,7 @@ impl ChangeAdminStatusSubCommand { info!("granted admin status"); } _ => { - info!("no change needed for: {:#?}", user); + info!("no change needed for: {:#}", json!(user)); // Since no change happened, we do not want to delete active logins. Return now. return Ok(()); } diff --git a/web3_proxy/src/bin/web3_proxy_cli/change_user_address.rs b/web3_proxy/src/bin/web3_proxy_cli/change_user_address.rs index 5629d56b..a389c293 100644 --- a/web3_proxy/src/bin/web3_proxy_cli/change_user_address.rs +++ b/web3_proxy/src/bin/web3_proxy_cli/change_user_address.rs @@ -27,29 +27,24 @@ impl ChangeUserAddressSubCommand { let old_address: Address = self.old_address.parse()?; let new_address: Address = self.new_address.parse()?; - let old_address: Vec = old_address.to_fixed_bytes().into(); - let new_address: Vec = new_address.to_fixed_bytes().into(); - let u = user::Entity::find() - .filter(user::Column::Address.eq(old_address)) + .filter(user::Column::Address.eq(old_address.as_bytes())) .one(db_conn) .await? .context("No user found with that address")?; debug!("initial user: {:#}", json!(&u)); - if u.address == new_address { + if u.address == new_address.as_bytes() { info!("user already has this address"); } else { let mut u = u.into_active_model(); - u.address = sea_orm::Set(new_address); + u.address = sea_orm::Set(new_address.as_bytes().to_vec()); let u = u.save(db_conn).await?; - info!("changed user address"); - - debug!("updated user: {:#?}", u); + info!("updated user: {:#?}", u); } Ok(()) diff --git a/web3_proxy/src/bin/web3_proxy_cli/change_user_tier_by_address.rs b/web3_proxy/src/bin/web3_proxy_cli/change_user_tier_by_address.rs index cca70730..3ec58b54 100644 --- a/web3_proxy/src/bin/web3_proxy_cli/change_user_tier_by_address.rs +++ b/web3_proxy/src/bin/web3_proxy_cli/change_user_tier_by_address.rs @@ -24,11 +24,9 @@ pub struct ChangeUserTierByAddressSubCommand { impl ChangeUserTierByAddressSubCommand { pub async fn main(self, db_conn: &DatabaseConnection) -> anyhow::Result<()> { - let address: Vec = self.user_address.to_fixed_bytes().into(); - // use the address to get the user let user = user::Entity::find() - .filter(user::Column::Address.eq(address)) + .filter(user::Column::Address.eq(self.user_address.as_bytes())) .one(db_conn) .await? .context("No user found with that key")?; diff --git a/web3_proxy/src/bin/web3_proxy_cli/create_key.rs b/web3_proxy/src/bin/web3_proxy_cli/create_key.rs index 0de187cd..58bae44d 100644 --- a/web3_proxy/src/bin/web3_proxy_cli/create_key.rs +++ b/web3_proxy/src/bin/web3_proxy_cli/create_key.rs @@ -16,7 +16,7 @@ pub struct CreateKeySubCommand { /// If a string is given, it will be converted to hex and potentially truncated. /// Users from strings are only for testing since they won't be able to log in. #[argh(positional)] - address: String, + address: Address, /// the user's api ULID or UUID key. /// If none given, one will be created. @@ -30,27 +30,9 @@ pub struct CreateKeySubCommand { impl CreateKeySubCommand { pub async fn main(self, db: &sea_orm::DatabaseConnection) -> anyhow::Result<()> { - // TODO: would be nice to use the fixed array instead of a Vec in the entities - // take a simple String. If it starts with 0x, parse as address. otherwise convert ascii to hex - let address: Vec = if self.address.starts_with("0x") { - let address = self.address.parse::
()?; - - address.to_fixed_bytes().into() - } else { - // TODO: allow ENS - // left pad and truncate the string - let address = &format!("{:\x00>20}", self.address)[0..20]; - - // convert the string to bytes - let bytes = address.as_bytes(); - - // convert the slice to a Vec - bytes.try_into().expect("Bytes can always be a Vec") - }; - // TODO: get existing or create a new one let u = user::Entity::find() - .filter(user::Column::Address.eq(address)) + .filter(user::Column::Address.eq(self.address.as_bytes())) .one(db) .await? .context("No user found with that address")?; diff --git a/web3_proxy/src/bin/web3_proxy_cli/rpc_accounting.rs b/web3_proxy/src/bin/web3_proxy_cli/rpc_accounting.rs index 273086a9..1df2e50d 100644 --- a/web3_proxy/src/bin/web3_proxy_cli/rpc_accounting.rs +++ b/web3_proxy/src/bin/web3_proxy_cli/rpc_accounting.rs @@ -93,11 +93,11 @@ impl RpcAccountingSubCommand { // TODO: do this with add_option? try operator is harder to use then if let Some(address) = self.address { - let address: Vec = address.parse::
()?.to_fixed_bytes().into(); + let address = address.parse::
()?; // TODO: find_with_related let u = user::Entity::find() - .filter(user::Column::Address.eq(address)) + .filter(user::Column::Address.eq(address.as_bytes())) .one(db_conn) .await? .context("no user found")?; diff --git a/web3_proxy/src/bin/web3_proxy_cli/transfer_key.rs b/web3_proxy/src/bin/web3_proxy_cli/transfer_key.rs index f9bdc278..c44b8fe1 100644 --- a/web3_proxy/src/bin/web3_proxy_cli/transfer_key.rs +++ b/web3_proxy/src/bin/web3_proxy_cli/transfer_key.rs @@ -29,8 +29,6 @@ impl TransferKeySubCommand { let new_address: Address = self.new_address.parse()?; - let new_address: Vec = new_address.to_fixed_bytes().into(); - let uk = rpc_key::Entity::find() .filter(rpc_key::Column::SecretKey.eq(rpc_secret_key)) .one(db_conn) @@ -40,7 +38,7 @@ impl TransferKeySubCommand { debug!("user key: {}", serde_json::to_string(&uk)?); let new_u = user::Entity::find() - .filter(user::Column::Address.eq(new_address)) + .filter(user::Column::Address.eq(new_address.as_bytes())) .one(db_conn) .await? .context("No user found with that key")?; diff --git a/web3_proxy/src/bin/web3_proxy_cli/user_import.rs b/web3_proxy/src/bin/web3_proxy_cli/user_import.rs index 482d981e..59835ac2 100644 --- a/web3_proxy/src/bin/web3_proxy_cli/user_import.rs +++ b/web3_proxy/src/bin/web3_proxy_cli/user_import.rs @@ -125,7 +125,7 @@ impl UserImportSubCommand { for import_u in us.into_iter() { // first, check if a user already exists with this address if let Some(existing_u) = user::Entity::find() - .filter(user::Column::Address.eq(import_u.address.clone())) + .filter(user::Column::Address.eq(import_u.address)) .one(db_conn) .await? { diff --git a/web3_proxy/src/frontend/admin.rs b/web3_proxy/src/frontend/admin.rs index 8f298ada..98cd3c28 100644 --- a/web3_proxy/src/frontend/admin.rs +++ b/web3_proxy/src/frontend/admin.rs @@ -7,7 +7,6 @@ use crate::errors::Web3ProxyResponse; use crate::errors::{Web3ProxyError, Web3ProxyErrorContext}; use crate::user_token::UserBearerToken; use crate::PostLogin; -use anyhow::Context; use axum::{ extract::{Path, Query}, headers::{authorization::Bearer, Authorization}, @@ -73,8 +72,6 @@ pub async fn admin_increase_balance( Web3ProxyError::BadRequest("Unable to parse user_address as an Address".into()) })?; - let user_address_bytes: Vec = user_address.to_fixed_bytes().into(); - let note: String = params .get("note") .ok_or_else(|| Web3ProxyError::BadRequest("Unable to find 'note' key in request".into()))? @@ -95,11 +92,11 @@ pub async fn admin_increase_balance( })?; let user_entry: user::Model = user::Entity::find() - .filter(user::Column::Address.eq(user_address_bytes.clone())) + .filter(user::Column::Address.eq(user_address.as_bytes())) .one(&txn) .await? .ok_or(Web3ProxyError::BadRequest( - "No user with this id found".into(), + format!("No user found with {:?}", user_address).into(), ))?; let increase_balance_receipt = admin_increase_balance_receipt::ActiveModel { @@ -200,7 +197,7 @@ pub async fn admin_login_get( })?; // Fetch the user_address parameter from the login string ... (as who we want to be logging in ...) - let user_address: Vec = params + let user_address: Address = params .get("user_address") .ok_or_else(|| { Web3ProxyError::BadRequest("Unable to find user_address key in request".into()) @@ -208,9 +205,7 @@ pub async fn admin_login_get( .parse::
() .map_err(|_err| { Web3ProxyError::BadRequest("Unable to parse user_address as an Address".into()) - })? - .to_fixed_bytes() - .into(); + })?; // We want to login to llamanodes.com let login_domain = app @@ -228,8 +223,8 @@ pub async fn admin_login_get( // TODO: don't unwrap // TODO: accept a login_domain from the request? domain: login_domain.parse().unwrap(), - // In the case of the admin, the admin needs to sign the message, so we include this logic ... - address: admin_address.to_fixed_bytes(), // user_address.to_fixed_bytes(), + // the admin needs to sign the message, not the imitated user + address: admin_address.to_fixed_bytes(), // TODO: config for statement statement: Some("🦙🦙🦙🦙🦙".to_string()), // TODO: don't unwrap @@ -244,8 +239,6 @@ pub async fn admin_login_get( resources: vec![], }; - let admin_address: Vec = admin_address.to_fixed_bytes().into(); - let db_conn = app.db_conn().web3_context("login requires a database")?; let db_replica = app .db_replica() @@ -264,7 +257,7 @@ pub async fn admin_login_get( // Get the user that we want to imitate from the read-only database (their id ...) // TODO: Only get the id, not the whole user object ... let user = user::Entity::find() - .filter(user::Column::Address.eq(user_address)) + .filter(user::Column::Address.eq(user_address.as_bytes())) .one(db_replica.as_ref()) .await? .ok_or(Web3ProxyError::BadRequest( @@ -273,9 +266,8 @@ pub async fn admin_login_get( // TODO: Gotta check if encoding messes up things maybe ... info!("Admin address is: {:?}", admin_address); - info!("Encoded admin address is: {:?}", admin_address); let admin = user::Entity::find() - .filter(user::Column::Address.eq(admin_address)) + .filter(user::Column::Address.eq(admin_address.as_bytes())) .one(db_replica.as_ref()) .await? .ok_or(Web3ProxyError::BadRequest( @@ -287,7 +279,7 @@ pub async fn admin_login_get( caller: sea_orm::Set(admin.id), imitating_user: sea_orm::Set(Some(user.id)), endpoint: sea_orm::Set("admin_login_get".to_string()), - payload: sea_orm::Set(format!("{:?}", params)), + payload: sea_orm::Set(format!("{}", json!(params))), ..Default::default() }; trail diff --git a/web3_proxy/src/frontend/users/payment.rs b/web3_proxy/src/frontend/users/payment.rs index 295857aa..d9ce453d 100644 --- a/web3_proxy/src/frontend/users/payment.rs +++ b/web3_proxy/src/frontend/users/payment.rs @@ -282,7 +282,7 @@ pub async fn user_balance_post( ); let recipient = match user::Entity::find() - .filter(user::Column::Address.eq(recipient_account.to_fixed_bytes().as_slice())) + .filter(user::Column::Address.eq(recipient_account.as_bytes())) .one(&txn) .await? {