Do EIP-4361 verification at signup

This commit is contained in:
silverpill 2022-02-14 18:07:16 +00:00
parent e8a29a3af1
commit 6ddfb5b52d
3 changed files with 24 additions and 10 deletions

View file

@ -77,10 +77,12 @@ paths:
password:
description: The password to be used for login.
type: string
wallet_address:
description: Ethereum wallet address.
message:
description: EIP-4361 message
type: string
signature:
description: EIP-4361 signature (required if message is present)
type: string
example: '0xd8da6bf...'
invite_code:
description: Invite code
type: string

View file

@ -13,7 +13,6 @@ use crate::models::profiles::types::{
use crate::models::profiles::validators::validate_username;
use crate::models::users::types::{
validate_local_username,
validate_wallet_address,
User,
};
use crate::utils::files::{FileError, save_validated_b64_file, get_file_url};
@ -107,7 +106,9 @@ pub struct AccountCreateData {
pub username: String,
pub password: String,
pub wallet_address: Option<String>,
pub message: Option<String>,
pub signature: Option<String>,
pub invite_code: Option<String>,
}
@ -116,9 +117,6 @@ impl AccountCreateData {
pub fn clean(&self) -> Result<(), ValidationError> {
validate_username(&self.username)?;
validate_local_username(&self.username)?;
if let Some(wallet_address) = self.wallet_address.as_ref() {
validate_wallet_address(wallet_address)?;
};
Ok(())
}
}

View file

@ -13,6 +13,7 @@ use crate::activitypub::deliverer::deliver_activity;
use crate::config::Config;
use crate::database::{Pool, get_database_client};
use crate::errors::{DatabaseError, HttpError, ValidationError};
use crate::ethereum::eip4361::verify_eip4361_signature;
use crate::ethereum::gate::is_allowed_user;
use crate::ethereum::subscriptions::create_subscription_signature;
use crate::mastodon_api::oauth::auth::get_current_user;
@ -71,9 +72,22 @@ pub async fn create_account(
return Err(ValidationError("invalid invite code").into());
}
}
let wallet_address = if let Some(message) = account_data.message.as_ref() {
let signature = account_data.signature.as_ref()
.ok_or(ValidationError("signature is required"))?;
let wallet_address = verify_eip4361_signature(
&message,
&signature,
&config.instance().host(),
&config.login_message,
)?;
Some(wallet_address)
} else {
None
};
if let Some(blockchain_config) = config.blockchain.as_ref() {
// Wallet address is required only if blockchain integration is enabled
let wallet_address = account_data.wallet_address.as_ref()
let wallet_address = wallet_address.as_ref()
.ok_or(ValidationError("wallet address is required"))?;
let is_allowed = is_allowed_user(blockchain_config, wallet_address).await
.map_err(|_| HttpError::InternalError)?;
@ -91,7 +105,7 @@ pub async fn create_account(
let private_key_pem = serialize_private_key(private_key)
.map_err(|_| HttpError::InternalError)?;
let AccountCreateData { username, wallet_address, invite_code, .. } =
let AccountCreateData { username, invite_code, .. } =
account_data.into_inner();
let user_data = UserCreateData {
username,