multiple ways to sign

This commit is contained in:
Bryan Stitt 2022-08-19 20:18:12 +00:00
parent 23e5e2c777
commit 9a2fe46105
4 changed files with 27 additions and 9 deletions

View File

@ -5,6 +5,6 @@ authors = ["Bryan Stitt <bryan@stitthappens.com>"]
edition = "2021"
[dependencies]
anyhow = "1.0.61"
anyhow = "1.0.62"
bb8-redis = "0.11.0"
tracing = "0.1.36"

View File

@ -16,12 +16,12 @@ entities = { path = "../entities" }
migration = { path = "../migration" }
redis-rate-limit = { path = "../redis-rate-limit" }
anyhow = { version = "1.0.61", features = ["backtrace"] }
anyhow = { version = "1.0.62", features = ["backtrace"] }
arc-swap = "1.5.1"
argh = "0.1.8"
axum = { version = "0.5.15", features = ["headers", "serde_json", "tokio-tungstenite", "ws"] }
axum-client-ip = "0.2.0"
axum-macros = "*"
axum-macros = "0.2.3"
counter = "0.5.6"
dashmap = "5.3.4"
derive_more = "0.99.17"
@ -39,7 +39,7 @@ num = "0.4.0"
parking_lot = { version = "0.12.1", features = ["arc_lock"] }
petgraph = "0.6.2"
proctitle = "0.1.1"
prometheus-client = "0.17.0"
prometheus-client = "0.18.0"
rand = "0.8.5"
# TODO: regex has several "perf" features that we might want to use
regex = "1.6.0"
@ -51,7 +51,7 @@ sea-orm = { version = "0.9.1", features = ["macros"] }
serde = { version = "1.0.143", features = [] }
serde_json = { version = "1.0.83", default-features = false, features = ["alloc", "raw_value"] }
# TODO: make sure this time version matches siwe. PR to put this in their prelude
time = "0.3.11"
time = "0.3.13"
tokio = { version = "1.20.1", features = ["full", "tracing"] }
# TODO: make sure this uuid version matches sea-orm. PR to put this in their prelude
tokio-stream = { version = "0.1.9", features = ["sync"] }

View File

@ -34,7 +34,9 @@ async fn handle_anyhow_error(err: anyhow::Error) -> (StatusCode, String) {
/// http and websocket frontend for customers
pub async fn serve(port: u16, proxy_app: Arc<Web3ProxyApp>) -> anyhow::Result<()> {
// create a tracing span for each request
// create a tracing span for each request with a random request id and the method
// GET: websocket or static pages
// POST: http rpc or login
let request_tracing_layer =
TraceLayer::new_for_http().make_span_with(|request: &Request<Body>| {
// We get the request id from the extensions
@ -70,6 +72,7 @@ pub async fn serve(port: u16, proxy_app: Arc<Web3ProxyApp>) -> anyhow::Result<()
.route("/health", get(http::health))
.route("/status", get(http::status))
.route("/login/:user_address", get(users::get_login))
.route("/login/:user_address/:message_eip", get(users::get_login))
.route("/users", post(users::create_user))
// .route(
// "/foo",

View File

@ -21,6 +21,7 @@ use axum_client_ip::ClientIp;
use axum_macros::debug_handler;
use entities::{user, user_keys};
use ethers::{prelude::Address, types::Bytes};
use hashbrown::HashMap;
use redis_rate_limit::redis::AsyncCommands;
use reqwest::StatusCode;
use sea_orm::ActiveModelTrait;
@ -38,7 +39,7 @@ pub async fn get_login(
ClientIp(ip): ClientIp,
// TODO: what does axum's error handling look like if the path fails to parse?
// TODO: allow ENS names here?
Path(user_address): Path<Address>,
Path(mut params): Path<HashMap<String, String>>,
) -> FrontendResult {
// TODO: refactor this to use the try operator
let _ip = match app.rate_limit_by_ip(ip).await {
@ -65,7 +66,8 @@ pub async fn get_login(
let expiration_time = issued_at.add(Duration::new(expire_seconds as i64, 0));
// TODO: get request_id out of the trace? do we need that when we have a none?
// TODO: proper errors. the first unwrap should be impossible, but the second will happen with bad input
let user_address: Address = params.remove("user_address").unwrap().parse().unwrap();
// TODO: get most of these from the app config
let message = Message {
@ -98,7 +100,20 @@ pub async fn get_login(
.set_ex(session_key, message.to_string(), expire_seconds)
.await?;
Ok(message.to_string().into_response())
// there are multiple ways to sign messages and not all wallets support them
let message_eip = params
.remove("message_eip")
.unwrap_or_else(|| "eip4361".to_string());
let message: String = match message_eip.as_str() {
"eip4361" => message.to_string(),
// https://github.com/spruceid/siwe/issues/98
"eip191_string" => Bytes::from(message.eip191_string().unwrap()).to_string(),
"eip191_hash" => Bytes::from(&message.eip191_hash().unwrap()).to_string(),
_ => todo!("return a proper error"),
};
Ok(message.into_response())
}
#[debug_handler]