Don't require wallet address during registration

This commit is contained in:
silverpill 2021-12-24 17:46:01 +00:00
parent c628885c9e
commit 81a260e691
9 changed files with 51 additions and 21 deletions

View file

@ -18,10 +18,19 @@ paths:
type: string
enum:
- password
- ethereum
username:
description: User name (required if grant type is "password").
type: string
wallet_address:
description: Ethereum wallet address (required if grant type is "ethereum").
type: string
example: null
password:
type: string
required:
- grant_type
- password
responses:
200:
description: Successful operation
@ -59,7 +68,7 @@ paths:
description: The password to be used for login.
type: string
wallet_address:
description: Ethereum wallet address
description: Ethereum wallet address.
type: string
example: '0xd8da6bf...'
invite_code:
@ -69,7 +78,6 @@ paths:
required:
- username
- password
- wallet_address
responses:
201:
description: Successful operation
@ -193,7 +201,7 @@ paths:
type: string
example: '6a5cb313907cd3...'
403:
description: Post does not belong to user or is not public
description: Post does not belong to user or is not public or user's wallet address is not known
404:
description: Post not found
418:
@ -295,6 +303,10 @@ components:
description: The Webfinger account URI. Equal to username for local actors, or username@domain for remote actors.
type: string
example: user@example.com
wallet_address:
description: Ethereum wallet address.
type: string
example: '0xd8da6bf...'
Status:
type: object
properties:

View file

@ -0,0 +1 @@
ALTER TABLE user_account ALTER COLUMN wallet_address DROP NOT NULL;

View file

@ -22,7 +22,7 @@ CREATE TABLE user_invite_code (
CREATE TABLE user_account (
id UUID PRIMARY KEY REFERENCES actor_profile (id) ON DELETE CASCADE,
wallet_address VARCHAR(100) UNIQUE NOT NULL,
wallet_address VARCHAR(100) UNIQUE,
password_hash VARCHAR(200) NOT NULL,
private_key TEXT NOT NULL,
invite_code VARCHAR(100) UNIQUE REFERENCES user_invite_code (code) ON DELETE SET NULL,

View file

@ -87,7 +87,7 @@ impl Account {
};
let mut account = Self::from_profile(user.profile, instance_url);
account.source = Some(source);
account.wallet_address = Some(user.wallet_address);
account.wallet_address = user.wallet_address;
account
}
}
@ -98,7 +98,7 @@ pub struct AccountCreateData {
username: String,
password: String,
wallet_address: String,
wallet_address: Option<String>,
invite_code: Option<String>,
}
@ -204,7 +204,7 @@ mod tests {
..Default::default()
};
let user = User {
wallet_address: wallet_address.to_string(),
wallet_address: Some(wallet_address.to_string()),
profile,
..Default::default()
};

View file

@ -58,7 +58,10 @@ pub async fn create_account(
}
}
if config.ethereum_contract.is_some() {
let is_allowed = is_allowed_user(&config, &user_data.wallet_address).await
// Wallet address is required only if ethereum integration is enabled
let wallet_address = user_data.wallet_address.as_ref()
.ok_or(ValidationError("wallet address is required"))?;
let is_allowed = is_allowed_user(&config, wallet_address).await
.map_err(|_| HttpError::InternalError)?;
if !is_allowed {
return Err(ValidationError("not allowed to sign up").into());

View file

@ -3,7 +3,8 @@ use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
pub struct TokenRequest {
pub grant_type: String,
pub username: String, // wallet address
pub username: Option<String>,
pub wallet_address: Option<String>,
pub password: String,
}

View file

@ -4,7 +4,10 @@ use chrono::{Duration, Utc};
use crate::database::{Pool, get_database_client};
use crate::errors::{HttpError, ValidationError};
use crate::models::oauth::queries::save_oauth_token;
use crate::models::users::queries::get_user_by_wallet_address;
use crate::models::users::queries::{
get_user_by_name,
get_user_by_wallet_address,
};
use crate::utils::crypto::verify_password;
use super::types::{TokenRequest, TokenResponse};
use super::utils::generate_access_token;
@ -18,14 +21,22 @@ async fn token_view(
db_pool: web::Data<Pool>,
request_data: web::Json<TokenRequest>,
) -> Result<HttpResponse, HttpError> {
if &request_data.grant_type != "password" {
return Err(ValidationError("unsupported grant type").into());
}
let db_client = &**get_database_client(&db_pool).await?;
let user = get_user_by_wallet_address(
db_client,
&request_data.username,
).await?;
let user = match request_data.grant_type.as_str() {
"password" => {
let username = request_data.username.as_ref()
.ok_or(ValidationError("username is required"))?;
get_user_by_name(db_client, username).await?
},
"ethereum" => {
let wallet_address = request_data.wallet_address.as_ref()
.ok_or(ValidationError("wallet address is required"))?;
get_user_by_wallet_address(db_client, wallet_address).await?
},
_ => {
return Err(ValidationError("unsupported grant type").into());
},
};
let password_correct = verify_password(
&user.password_hash,
&request_data.password,

View file

@ -477,6 +477,8 @@ async fn get_signature(
let current_user = get_current_user(db_client, auth.token()).await?;
let contract_config = config.ethereum_contract.as_ref()
.ok_or(HttpError::NotSupported)?;
let wallet_address = current_user.wallet_address
.ok_or(HttpError::PermissionError)?;
let post = get_post_by_id(db_client, &status_id).await?;
if post.author.id != current_user.id || !post.is_public() {
// Users can only tokenize their own public posts
@ -488,7 +490,7 @@ async fn get_signature(
let token_uri = get_ipfs_url(&ipfs_cid);
let signature = create_mint_signature(
contract_config,
&current_user.wallet_address,
&wallet_address,
&token_uri,
).map_err(|_| HttpError::InternalError)?;
Ok(HttpResponse::Ok().json(signature))

View file

@ -11,7 +11,7 @@ use crate::models::profiles::types::DbActorProfile;
#[postgres(name = "user_account")]
pub struct DbUser {
pub id: Uuid,
pub wallet_address: String,
pub wallet_address: Option<String>,
pub password_hash: String,
pub private_key: String,
pub invite_code: Option<String>,
@ -23,7 +23,7 @@ pub struct DbUser {
#[cfg_attr(test, derive(Default))]
pub struct User {
pub id: Uuid,
pub wallet_address: String,
pub wallet_address: Option<String>,
pub password_hash: String,
pub private_key: String,
pub profile: DbActorProfile,
@ -49,7 +49,7 @@ impl User {
pub struct UserCreateData {
pub username: String,
pub password: String,
pub wallet_address: String,
pub wallet_address: Option<String>,
pub invite_code: Option<String>,
}