handle addresses consistently
This commit is contained in:
parent
39a505c0ff
commit
9115419ec0
@ -26,7 +26,7 @@ pub async fn query_admin_modify_usertier<'a>(
|
|||||||
params: &'a HashMap<String, String>,
|
params: &'a HashMap<String, String>,
|
||||||
) -> Web3ProxyResponse {
|
) -> Web3ProxyResponse {
|
||||||
// Quickly return if any of the input tokens are bad
|
// Quickly return if any of the input tokens are bad
|
||||||
let user_address: Vec<u8> = params
|
let user_address = params
|
||||||
.get("user_address")
|
.get("user_address")
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
Web3ProxyError::BadRequest("Unable to find user_address key in request".into())
|
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>()
|
.parse::<Address>()
|
||||||
.map_err(|_| {
|
.map_err(|_| {
|
||||||
Web3ProxyError::BadRequest("Unable to parse user_address as an Address".into())
|
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(|| {
|
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())
|
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
|
// Fetch the admin, and the user
|
||||||
let user: user::Model = user::Entity::find()
|
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)
|
.one(&db_conn)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(Web3ProxyError::BadRequest(
|
.ok_or(Web3ProxyError::BadRequest(
|
||||||
|
@ -26,15 +26,12 @@ impl ChangeAdminStatusSubCommand {
|
|||||||
let address: Address = self.address.parse()?;
|
let address: Address = self.address.parse()?;
|
||||||
let should_be_admin: bool = self.should_be_admin;
|
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
|
// Find user in database
|
||||||
let user = user::Entity::find()
|
let user = user::Entity::find()
|
||||||
.filter(user::Column::Address.eq(address_vec))
|
.filter(user::Column::Address.eq(address.as_bytes()))
|
||||||
.one(db_conn)
|
.one(db_conn)
|
||||||
.await?
|
.await?
|
||||||
.context(format!("No user with this id found {:?}", address))?;
|
.context(format!("No user with this address found {:?}", address))?;
|
||||||
|
|
||||||
debug!("user: {:#}", json!(&user));
|
debug!("user: {:#}", json!(&user));
|
||||||
|
|
||||||
@ -59,7 +56,7 @@ impl ChangeAdminStatusSubCommand {
|
|||||||
info!("granted admin status");
|
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.
|
// Since no change happened, we do not want to delete active logins. Return now.
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -27,29 +27,24 @@ impl ChangeUserAddressSubCommand {
|
|||||||
let old_address: Address = self.old_address.parse()?;
|
let old_address: Address = self.old_address.parse()?;
|
||||||
let new_address: Address = self.new_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()
|
let u = user::Entity::find()
|
||||||
.filter(user::Column::Address.eq(old_address))
|
.filter(user::Column::Address.eq(old_address.as_bytes()))
|
||||||
.one(db_conn)
|
.one(db_conn)
|
||||||
.await?
|
.await?
|
||||||
.context("No user found with that address")?;
|
.context("No user found with that address")?;
|
||||||
|
|
||||||
debug!("initial user: {:#}", json!(&u));
|
debug!("initial user: {:#}", json!(&u));
|
||||||
|
|
||||||
if u.address == new_address {
|
if u.address == new_address.as_bytes() {
|
||||||
info!("user already has this address");
|
info!("user already has this address");
|
||||||
} else {
|
} else {
|
||||||
let mut u = u.into_active_model();
|
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?;
|
let u = u.save(db_conn).await?;
|
||||||
|
|
||||||
info!("changed user address");
|
info!("updated user: {:#?}", u);
|
||||||
|
|
||||||
debug!("updated user: {:#?}", u);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -24,11 +24,9 @@ pub struct ChangeUserTierByAddressSubCommand {
|
|||||||
|
|
||||||
impl ChangeUserTierByAddressSubCommand {
|
impl ChangeUserTierByAddressSubCommand {
|
||||||
pub async fn main(self, db_conn: &DatabaseConnection) -> anyhow::Result<()> {
|
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
|
// use the address to get the user
|
||||||
let user = user::Entity::find()
|
let user = user::Entity::find()
|
||||||
.filter(user::Column::Address.eq(address))
|
.filter(user::Column::Address.eq(self.user_address.as_bytes()))
|
||||||
.one(db_conn)
|
.one(db_conn)
|
||||||
.await?
|
.await?
|
||||||
.context("No user found with that key")?;
|
.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.
|
/// 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.
|
/// Users from strings are only for testing since they won't be able to log in.
|
||||||
#[argh(positional)]
|
#[argh(positional)]
|
||||||
address: String,
|
address: Address,
|
||||||
|
|
||||||
/// the user's api ULID or UUID key.
|
/// the user's api ULID or UUID key.
|
||||||
/// If none given, one will be created.
|
/// If none given, one will be created.
|
||||||
@ -30,27 +30,9 @@ pub struct CreateKeySubCommand {
|
|||||||
|
|
||||||
impl CreateKeySubCommand {
|
impl CreateKeySubCommand {
|
||||||
pub async fn main(self, db: &sea_orm::DatabaseConnection) -> anyhow::Result<()> {
|
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
|
// TODO: get existing or create a new one
|
||||||
let u = user::Entity::find()
|
let u = user::Entity::find()
|
||||||
.filter(user::Column::Address.eq(address))
|
.filter(user::Column::Address.eq(self.address.as_bytes()))
|
||||||
.one(db)
|
.one(db)
|
||||||
.await?
|
.await?
|
||||||
.context("No user found with that address")?;
|
.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
|
// TODO: do this with add_option? try operator is harder to use then
|
||||||
if let Some(address) = self.address {
|
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
|
// TODO: find_with_related
|
||||||
let u = user::Entity::find()
|
let u = user::Entity::find()
|
||||||
.filter(user::Column::Address.eq(address))
|
.filter(user::Column::Address.eq(address.as_bytes()))
|
||||||
.one(db_conn)
|
.one(db_conn)
|
||||||
.await?
|
.await?
|
||||||
.context("no user found")?;
|
.context("no user found")?;
|
||||||
|
@ -29,8 +29,6 @@ impl TransferKeySubCommand {
|
|||||||
|
|
||||||
let new_address: Address = self.new_address.parse()?;
|
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()
|
let uk = rpc_key::Entity::find()
|
||||||
.filter(rpc_key::Column::SecretKey.eq(rpc_secret_key))
|
.filter(rpc_key::Column::SecretKey.eq(rpc_secret_key))
|
||||||
.one(db_conn)
|
.one(db_conn)
|
||||||
@ -40,7 +38,7 @@ impl TransferKeySubCommand {
|
|||||||
debug!("user key: {}", serde_json::to_string(&uk)?);
|
debug!("user key: {}", serde_json::to_string(&uk)?);
|
||||||
|
|
||||||
let new_u = user::Entity::find()
|
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)
|
.one(db_conn)
|
||||||
.await?
|
.await?
|
||||||
.context("No user found with that key")?;
|
.context("No user found with that key")?;
|
||||||
|
@ -125,7 +125,7 @@ impl UserImportSubCommand {
|
|||||||
for import_u in us.into_iter() {
|
for import_u in us.into_iter() {
|
||||||
// first, check if a user already exists with this address
|
// first, check if a user already exists with this address
|
||||||
if let Some(existing_u) = user::Entity::find()
|
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)
|
.one(db_conn)
|
||||||
.await?
|
.await?
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,6 @@ use crate::errors::Web3ProxyResponse;
|
|||||||
use crate::errors::{Web3ProxyError, Web3ProxyErrorContext};
|
use crate::errors::{Web3ProxyError, Web3ProxyErrorContext};
|
||||||
use crate::user_token::UserBearerToken;
|
use crate::user_token::UserBearerToken;
|
||||||
use crate::PostLogin;
|
use crate::PostLogin;
|
||||||
use anyhow::Context;
|
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Path, Query},
|
extract::{Path, Query},
|
||||||
headers::{authorization::Bearer, Authorization},
|
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())
|
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
|
let note: String = params
|
||||||
.get("note")
|
.get("note")
|
||||||
.ok_or_else(|| Web3ProxyError::BadRequest("Unable to find 'note' key in request".into()))?
|
.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()
|
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)
|
.one(&txn)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(Web3ProxyError::BadRequest(
|
.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 {
|
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 ...)
|
// 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")
|
.get("user_address")
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
Web3ProxyError::BadRequest("Unable to find user_address key in request".into())
|
Web3ProxyError::BadRequest("Unable to find user_address key in request".into())
|
||||||
@ -208,9 +205,7 @@ pub async fn admin_login_get(
|
|||||||
.parse::<Address>()
|
.parse::<Address>()
|
||||||
.map_err(|_err| {
|
.map_err(|_err| {
|
||||||
Web3ProxyError::BadRequest("Unable to parse user_address as an Address".into())
|
Web3ProxyError::BadRequest("Unable to parse user_address as an Address".into())
|
||||||
})?
|
})?;
|
||||||
.to_fixed_bytes()
|
|
||||||
.into();
|
|
||||||
|
|
||||||
// We want to login to llamanodes.com
|
// We want to login to llamanodes.com
|
||||||
let login_domain = app
|
let login_domain = app
|
||||||
@ -228,8 +223,8 @@ pub async fn admin_login_get(
|
|||||||
// TODO: don't unwrap
|
// TODO: don't unwrap
|
||||||
// TODO: accept a login_domain from the request?
|
// TODO: accept a login_domain from the request?
|
||||||
domain: login_domain.parse().unwrap(),
|
domain: login_domain.parse().unwrap(),
|
||||||
// In the case of the admin, the admin needs to sign the message, so we include this logic ...
|
// the admin needs to sign the message, not the imitated user
|
||||||
address: admin_address.to_fixed_bytes(), // user_address.to_fixed_bytes(),
|
address: admin_address.to_fixed_bytes(),
|
||||||
// TODO: config for statement
|
// TODO: config for statement
|
||||||
statement: Some("🦙🦙🦙🦙🦙".to_string()),
|
statement: Some("🦙🦙🦙🦙🦙".to_string()),
|
||||||
// TODO: don't unwrap
|
// TODO: don't unwrap
|
||||||
@ -244,8 +239,6 @@ pub async fn admin_login_get(
|
|||||||
resources: vec![],
|
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_conn = app.db_conn().web3_context("login requires a database")?;
|
||||||
let db_replica = app
|
let db_replica = app
|
||||||
.db_replica()
|
.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 ...)
|
// 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 ...
|
// TODO: Only get the id, not the whole user object ...
|
||||||
let user = user::Entity::find()
|
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())
|
.one(db_replica.as_ref())
|
||||||
.await?
|
.await?
|
||||||
.ok_or(Web3ProxyError::BadRequest(
|
.ok_or(Web3ProxyError::BadRequest(
|
||||||
@ -273,9 +266,8 @@ pub async fn admin_login_get(
|
|||||||
|
|
||||||
// TODO: Gotta check if encoding messes up things maybe ...
|
// TODO: Gotta check if encoding messes up things maybe ...
|
||||||
info!("Admin address is: {:?}", admin_address);
|
info!("Admin address is: {:?}", admin_address);
|
||||||
info!("Encoded admin address is: {:?}", admin_address);
|
|
||||||
let admin = user::Entity::find()
|
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())
|
.one(db_replica.as_ref())
|
||||||
.await?
|
.await?
|
||||||
.ok_or(Web3ProxyError::BadRequest(
|
.ok_or(Web3ProxyError::BadRequest(
|
||||||
@ -287,7 +279,7 @@ pub async fn admin_login_get(
|
|||||||
caller: sea_orm::Set(admin.id),
|
caller: sea_orm::Set(admin.id),
|
||||||
imitating_user: sea_orm::Set(Some(user.id)),
|
imitating_user: sea_orm::Set(Some(user.id)),
|
||||||
endpoint: sea_orm::Set("admin_login_get".to_string()),
|
endpoint: sea_orm::Set("admin_login_get".to_string()),
|
||||||
payload: sea_orm::Set(format!("{:?}", params)),
|
payload: sea_orm::Set(format!("{}", json!(params))),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
trail
|
trail
|
||||||
|
@ -282,7 +282,7 @@ pub async fn user_balance_post(
|
|||||||
);
|
);
|
||||||
|
|
||||||
let recipient = match user::Entity::find()
|
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)
|
.one(&txn)
|
||||||
.await?
|
.await?
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user