diff --git a/entities/src/admin.rs b/entities/src/admin.rs index d1d46999..dc8a737d 100644 --- a/entities/src/admin.rs +++ b/entities/src/admin.rs @@ -1,5 +1,6 @@ //! `SeaORM` Entity. Generated by sea-orm-codegen 0.10.6 +use crate::serialization; use sea_orm::entity::prelude::*; use serde::{Deserialize, Serialize}; diff --git a/entities/src/mod.rs b/entities/src/mod.rs index 07d58029..209dead2 100644 --- a/entities/src/mod.rs +++ b/entities/src/mod.rs @@ -13,5 +13,6 @@ pub mod rpc_key; pub mod rpc_request; pub mod sea_orm_active_enums; pub mod secondary_user; +pub mod serialization; pub mod user; pub mod user_tier; diff --git a/web3_proxy/src/admin_queries.rs b/web3_proxy/src/admin_queries.rs index c23e79a3..92f75d51 100644 --- a/web3_proxy/src/admin_queries.rs +++ b/web3_proxy/src/admin_queries.rs @@ -12,7 +12,7 @@ use entities::{admin, user, user_tier}; use ethers::prelude::Address; use hashbrown::HashMap; use http::StatusCode; -use migration::sea_orm::{self, IntoActiveModel}; +use migration::sea_orm::{self, ActiveModelTrait, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter}; use log::info; @@ -51,14 +51,6 @@ pub async fn query_admin_modify_usertier<'a>( // Prepare output body let mut response_body = HashMap::new(); - response_body.insert( - "user_address", - serde_json::Value::String(user_address.into()), - ); - response_body.insert( - "user_tier_title", - serde_json::Value::String(user_tier_title.into()), - ); // Establish connections let db_conn = app.db_conn().context("query_admin_modify_user needs a db")?; @@ -78,8 +70,8 @@ pub async fn query_admin_modify_usertier<'a>( // Check if the caller is an admin (i.e. if he is in an admin table) let admin: admin::Model = admin::Entity::find() - .filter(admin::Entity::UserId.eq(caller_id)) - .one(&db_replica) + .filter(admin::Column::UserId.eq(caller_id)) + .one(&db_conn) .await? .context("This user is not registered as an admin")?; @@ -88,19 +80,19 @@ 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)) - .one(&db_replica) + .one(&db_conn) .await? .context("No user with this id found as the change")?; // Return early if the target user_tier_id is the same as the original user_tier_id response_body.insert( "user_tier_title", - serde_json::Value::String(user.user_tier_id.into()), + serde_json::Value::Number(user.user_tier_id.into()), ); // Now we can modify the user's tier let new_user_tier: user_tier::Model = user_tier::Entity::find() .filter(user_tier::Column::Title.eq(user_tier_title.clone())) - .one(&db_replica) + .one(&db_conn) .await? .context("No user tier found with that name")?; diff --git a/web3_proxy/src/frontend/admin.rs b/web3_proxy/src/frontend/admin.rs new file mode 100644 index 00000000..8f6273e3 --- /dev/null +++ b/web3_proxy/src/frontend/admin.rs @@ -0,0 +1,65 @@ +//! Handle admin helper logic + +use super::authorization::{login_is_authorized, RpcSecretKey}; +use super::errors::FrontendResult; +use crate::app::Web3ProxyApp; +use crate::user_queries::{get_page_from_params, get_user_id_from_params}; +use crate::user_queries::{ + get_chain_id_from_params, get_query_start_from_params, query_user_stats, StatResponse, +}; +use entities::prelude::{User, SecondaryUser}; +use crate::user_token::UserBearerToken; +use anyhow::Context; +use axum::headers::{Header, Origin, Referer, UserAgent}; +use axum::{ + extract::{Path, Query}, + headers::{authorization::Bearer, Authorization}, + response::IntoResponse, + Extension, Json, TypedHeader, +}; +use axum_client_ip::ClientIp; +use axum_macros::debug_handler; +use chrono::{TimeZone, Utc}; +use entities::sea_orm_active_enums::{LogLevel, Role}; +use entities::{login, pending_login, revert_log, rpc_key, secondary_user, user, user_tier}; +use ethers::{prelude::Address, types::Bytes}; +use hashbrown::HashMap; +use http::{HeaderValue, StatusCode}; +use ipnet::IpNet; +use itertools::Itertools; +use log::{debug, info, warn}; +use migration::sea_orm::prelude::Uuid; +use migration::sea_orm::{ + self, ActiveModelTrait, ColumnTrait, EntityTrait, IntoActiveModel, PaginatorTrait, QueryFilter, + QueryOrder, TransactionTrait, TryIntoModel, +}; +use serde::Deserialize; +use serde_json::json; +use siwe::{Message, VerificationOpts}; +use std::ops::Add; +use std::str::FromStr; +use std::sync::Arc; +use time::{Duration, OffsetDateTime}; +use ulid::Ulid; +use crate::admin_queries::query_admin_modify_usertier; +use crate::frontend::errors::FrontendErrorResponse; + +/// `GET /admin/modify_role` -- Use a bearer token to get the user's key stats such as bandwidth used and methods requested. +/// +/// If no bearer is provided, detailed stats for all users will be shown. +/// View a single user with `?user_id=$x`. +/// View a single chain with `?chain_id=$x`. +/// +/// Set `$x` to zero to see all. +/// +/// TODO: this will change as we add better support for secondary users. +#[debug_handler] +pub async fn admin_change_user_roles( + Extension(app): Extension>, + bearer: Option>>, + Query(params): Query>, +) -> FrontendResult { + let response = query_admin_modify_usertier(&app, bearer, ¶ms).await?; + + Ok(response) +} diff --git a/web3_proxy/src/frontend/mod.rs b/web3_proxy/src/frontend/mod.rs index 6c463067..885fa487 100644 --- a/web3_proxy/src/frontend/mod.rs +++ b/web3_proxy/src/frontend/mod.rs @@ -2,6 +2,7 @@ //! //! Important reading about axum extractors: https://docs.rs/axum/latest/axum/extract/index.html#the-order-of-extractors +pub mod admin; pub mod authorization; pub mod errors; // TODO: these are only public so docs are generated. What's a better way to do this? @@ -167,7 +168,7 @@ pub async fn serve(port: u16, proxy_app: Arc) -> anyhow::Result<() get(users::user_stats_aggregated_get), ) .route("/user/stats/detailed", get(users::user_stats_detailed_get)) - .route("/admin/modify_role", get(users::admin_change_user_roles)) + .route("/admin/modify_role", get(admin::admin_change_user_roles)) .route("/user/logout", post(users::user_logout_post)) // // Axum layers diff --git a/web3_proxy/src/frontend/users.rs b/web3_proxy/src/frontend/users.rs index 0f56fae4..aa35ac4d 100644 --- a/web3_proxy/src/frontend/users.rs +++ b/web3_proxy/src/frontend/users.rs @@ -939,23 +939,3 @@ pub async fn user_stats_detailed_get( Ok(response) } - -/// `GET /user/stats/detailed` -- Use a bearer token to get the user's key stats such as bandwidth used and methods requested. -/// -/// If no bearer is provided, detailed stats for all users will be shown. -/// View a single user with `?user_id=$x`. -/// View a single chain with `?chain_id=$x`. -/// -/// Set `$x` to zero to see all. -/// -/// TODO: this will change as we add better support for secondary users. -#[debug_handler] -pub async fn admin_change_user_roles( - Extension(app): Extension>, - bearer: Option>>, - Query(params): Query>, -) -> FrontendResult { - let response = query_admin_modify_usertier(&app, bearer, ¶ms).await?; - - response -}