Don't require wallet address during registration
This commit is contained in:
parent
c628885c9e
commit
81a260e691
9 changed files with 51 additions and 21 deletions
|
@ -18,10 +18,19 @@ paths:
|
||||||
type: string
|
type: string
|
||||||
enum:
|
enum:
|
||||||
- password
|
- password
|
||||||
|
- ethereum
|
||||||
username:
|
username:
|
||||||
|
description: User name (required if grant type is "password").
|
||||||
type: string
|
type: string
|
||||||
|
wallet_address:
|
||||||
|
description: Ethereum wallet address (required if grant type is "ethereum").
|
||||||
|
type: string
|
||||||
|
example: null
|
||||||
password:
|
password:
|
||||||
type: string
|
type: string
|
||||||
|
required:
|
||||||
|
- grant_type
|
||||||
|
- password
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: Successful operation
|
description: Successful operation
|
||||||
|
@ -59,7 +68,7 @@ paths:
|
||||||
description: The password to be used for login.
|
description: The password to be used for login.
|
||||||
type: string
|
type: string
|
||||||
wallet_address:
|
wallet_address:
|
||||||
description: Ethereum wallet address
|
description: Ethereum wallet address.
|
||||||
type: string
|
type: string
|
||||||
example: '0xd8da6bf...'
|
example: '0xd8da6bf...'
|
||||||
invite_code:
|
invite_code:
|
||||||
|
@ -69,7 +78,6 @@ paths:
|
||||||
required:
|
required:
|
||||||
- username
|
- username
|
||||||
- password
|
- password
|
||||||
- wallet_address
|
|
||||||
responses:
|
responses:
|
||||||
201:
|
201:
|
||||||
description: Successful operation
|
description: Successful operation
|
||||||
|
@ -193,7 +201,7 @@ paths:
|
||||||
type: string
|
type: string
|
||||||
example: '6a5cb313907cd3...'
|
example: '6a5cb313907cd3...'
|
||||||
403:
|
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:
|
404:
|
||||||
description: Post not found
|
description: Post not found
|
||||||
418:
|
418:
|
||||||
|
@ -295,6 +303,10 @@ components:
|
||||||
description: The Webfinger account URI. Equal to username for local actors, or username@domain for remote actors.
|
description: The Webfinger account URI. Equal to username for local actors, or username@domain for remote actors.
|
||||||
type: string
|
type: string
|
||||||
example: user@example.com
|
example: user@example.com
|
||||||
|
wallet_address:
|
||||||
|
description: Ethereum wallet address.
|
||||||
|
type: string
|
||||||
|
example: '0xd8da6bf...'
|
||||||
Status:
|
Status:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE user_account ALTER COLUMN wallet_address DROP NOT NULL;
|
|
@ -22,7 +22,7 @@ CREATE TABLE user_invite_code (
|
||||||
|
|
||||||
CREATE TABLE user_account (
|
CREATE TABLE user_account (
|
||||||
id UUID PRIMARY KEY REFERENCES actor_profile (id) ON DELETE CASCADE,
|
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,
|
password_hash VARCHAR(200) NOT NULL,
|
||||||
private_key TEXT NOT NULL,
|
private_key TEXT NOT NULL,
|
||||||
invite_code VARCHAR(100) UNIQUE REFERENCES user_invite_code (code) ON DELETE SET NULL,
|
invite_code VARCHAR(100) UNIQUE REFERENCES user_invite_code (code) ON DELETE SET NULL,
|
||||||
|
|
|
@ -87,7 +87,7 @@ impl Account {
|
||||||
};
|
};
|
||||||
let mut account = Self::from_profile(user.profile, instance_url);
|
let mut account = Self::from_profile(user.profile, instance_url);
|
||||||
account.source = Some(source);
|
account.source = Some(source);
|
||||||
account.wallet_address = Some(user.wallet_address);
|
account.wallet_address = user.wallet_address;
|
||||||
account
|
account
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ pub struct AccountCreateData {
|
||||||
username: String,
|
username: String,
|
||||||
password: String,
|
password: String,
|
||||||
|
|
||||||
wallet_address: String,
|
wallet_address: Option<String>,
|
||||||
invite_code: Option<String>,
|
invite_code: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ mod tests {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let user = User {
|
let user = User {
|
||||||
wallet_address: wallet_address.to_string(),
|
wallet_address: Some(wallet_address.to_string()),
|
||||||
profile,
|
profile,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,7 +58,10 @@ pub async fn create_account(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if config.ethereum_contract.is_some() {
|
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)?;
|
.map_err(|_| HttpError::InternalError)?;
|
||||||
if !is_allowed {
|
if !is_allowed {
|
||||||
return Err(ValidationError("not allowed to sign up").into());
|
return Err(ValidationError("not allowed to sign up").into());
|
||||||
|
|
|
@ -3,7 +3,8 @@ use serde::{Deserialize, Serialize};
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct TokenRequest {
|
pub struct TokenRequest {
|
||||||
pub grant_type: String,
|
pub grant_type: String,
|
||||||
pub username: String, // wallet address
|
pub username: Option<String>,
|
||||||
|
pub wallet_address: Option<String>,
|
||||||
pub password: String,
|
pub password: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,10 @@ use chrono::{Duration, Utc};
|
||||||
use crate::database::{Pool, get_database_client};
|
use crate::database::{Pool, get_database_client};
|
||||||
use crate::errors::{HttpError, ValidationError};
|
use crate::errors::{HttpError, ValidationError};
|
||||||
use crate::models::oauth::queries::save_oauth_token;
|
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 crate::utils::crypto::verify_password;
|
||||||
use super::types::{TokenRequest, TokenResponse};
|
use super::types::{TokenRequest, TokenResponse};
|
||||||
use super::utils::generate_access_token;
|
use super::utils::generate_access_token;
|
||||||
|
@ -18,14 +21,22 @@ async fn token_view(
|
||||||
db_pool: web::Data<Pool>,
|
db_pool: web::Data<Pool>,
|
||||||
request_data: web::Json<TokenRequest>,
|
request_data: web::Json<TokenRequest>,
|
||||||
) -> Result<HttpResponse, HttpError> {
|
) -> 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 db_client = &**get_database_client(&db_pool).await?;
|
||||||
let user = get_user_by_wallet_address(
|
let user = match request_data.grant_type.as_str() {
|
||||||
db_client,
|
"password" => {
|
||||||
&request_data.username,
|
let username = request_data.username.as_ref()
|
||||||
).await?;
|
.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(
|
let password_correct = verify_password(
|
||||||
&user.password_hash,
|
&user.password_hash,
|
||||||
&request_data.password,
|
&request_data.password,
|
||||||
|
|
|
@ -477,6 +477,8 @@ async fn get_signature(
|
||||||
let current_user = get_current_user(db_client, auth.token()).await?;
|
let current_user = get_current_user(db_client, auth.token()).await?;
|
||||||
let contract_config = config.ethereum_contract.as_ref()
|
let contract_config = config.ethereum_contract.as_ref()
|
||||||
.ok_or(HttpError::NotSupported)?;
|
.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?;
|
let post = get_post_by_id(db_client, &status_id).await?;
|
||||||
if post.author.id != current_user.id || !post.is_public() {
|
if post.author.id != current_user.id || !post.is_public() {
|
||||||
// Users can only tokenize their own public posts
|
// 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 token_uri = get_ipfs_url(&ipfs_cid);
|
||||||
let signature = create_mint_signature(
|
let signature = create_mint_signature(
|
||||||
contract_config,
|
contract_config,
|
||||||
¤t_user.wallet_address,
|
&wallet_address,
|
||||||
&token_uri,
|
&token_uri,
|
||||||
).map_err(|_| HttpError::InternalError)?;
|
).map_err(|_| HttpError::InternalError)?;
|
||||||
Ok(HttpResponse::Ok().json(signature))
|
Ok(HttpResponse::Ok().json(signature))
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::models::profiles::types::DbActorProfile;
|
||||||
#[postgres(name = "user_account")]
|
#[postgres(name = "user_account")]
|
||||||
pub struct DbUser {
|
pub struct DbUser {
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
pub wallet_address: String,
|
pub wallet_address: Option<String>,
|
||||||
pub password_hash: String,
|
pub password_hash: String,
|
||||||
pub private_key: String,
|
pub private_key: String,
|
||||||
pub invite_code: Option<String>,
|
pub invite_code: Option<String>,
|
||||||
|
@ -23,7 +23,7 @@ pub struct DbUser {
|
||||||
#[cfg_attr(test, derive(Default))]
|
#[cfg_attr(test, derive(Default))]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
pub wallet_address: String,
|
pub wallet_address: Option<String>,
|
||||||
pub password_hash: String,
|
pub password_hash: String,
|
||||||
pub private_key: String,
|
pub private_key: String,
|
||||||
pub profile: DbActorProfile,
|
pub profile: DbActorProfile,
|
||||||
|
@ -49,7 +49,7 @@ impl User {
|
||||||
pub struct UserCreateData {
|
pub struct UserCreateData {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub password: String,
|
pub password: String,
|
||||||
pub wallet_address: String,
|
pub wallet_address: Option<String>,
|
||||||
pub invite_code: Option<String>,
|
pub invite_code: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue