handle addresses consistently

This commit is contained in:
Bryan Stitt 2023-06-24 10:20:24 -07:00
parent 39a505c0ff
commit 9115419ec0
10 changed files with 27 additions and 67 deletions

@ -26,7 +26,7 @@ pub async fn query_admin_modify_usertier<'a>(
params: &'a HashMap<String, String>,
) -> Web3ProxyResponse {
// Quickly return if any of the input tokens are bad
let user_address: Vec<u8> = 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::<Address>()
.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(

@ -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<u8> = 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(());
}

@ -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<u8> = old_address.to_fixed_bytes().into();
let new_address: Vec<u8> = 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(())

@ -24,11 +24,9 @@ pub struct ChangeUserTierByAddressSubCommand {
impl ChangeUserTierByAddressSubCommand {
pub async fn main(self, db_conn: &DatabaseConnection) -> anyhow::Result<()> {
let address: Vec<u8> = 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")?;

@ -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<u8> = if self.address.starts_with("0x") {
let address = self.address.parse::<Address>()?;
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<u8>")
};
// 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")?;

@ -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<u8> = address.parse::<Address>()?.to_fixed_bytes().into();
let address = address.parse::<Address>()?;
// 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")?;

@ -29,8 +29,6 @@ impl TransferKeySubCommand {
let new_address: Address = self.new_address.parse()?;
let new_address: Vec<u8> = 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")?;

@ -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?
{

@ -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<u8> = 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<u8> = 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::<Address>()
.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<u8> = 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

@ -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?
{