Change path of user creation endpoint
This commit is contained in:
parent
b39733beb7
commit
9519786788
6 changed files with 43 additions and 24 deletions
|
@ -81,7 +81,6 @@ async fn main() -> std::io::Result<()> {
|
||||||
config.contract_dir.clone(),
|
config.contract_dir.clone(),
|
||||||
))
|
))
|
||||||
.service(oauth_api_scope())
|
.service(oauth_api_scope())
|
||||||
.service(user_api::create_user_view)
|
|
||||||
.service(user_api::login_view)
|
.service(user_api::login_view)
|
||||||
.service(user_api::current_user_view)
|
.service(user_api::current_user_view)
|
||||||
.service(user_api::logout_view)
|
.service(user_api::logout_view)
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::models::profiles::types::{
|
||||||
ExtraField,
|
ExtraField,
|
||||||
ProfileUpdateData,
|
ProfileUpdateData,
|
||||||
};
|
};
|
||||||
use crate::models::users::types::User;
|
use crate::models::users::types::{User, UserCreateData};
|
||||||
use crate::utils::files::{FileError, save_validated_b64_file, get_file_url};
|
use crate::utils::files::{FileError, save_validated_b64_file, get_file_url};
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
@ -96,6 +96,26 @@ impl Account {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://docs.joinmastodon.org/methods/accounts/
|
/// https://docs.joinmastodon.org/methods/accounts/
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct AccountCreateData {
|
||||||
|
username: String,
|
||||||
|
password: String,
|
||||||
|
|
||||||
|
wallet_address: String,
|
||||||
|
invite_code: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AccountCreateData {
|
||||||
|
pub fn into_user_data(self) -> UserCreateData {
|
||||||
|
UserCreateData {
|
||||||
|
username: self.username,
|
||||||
|
password: self.password,
|
||||||
|
wallet_address: self.wallet_address,
|
||||||
|
invite_code: self.invite_code,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct AccountUpdateData {
|
pub struct AccountUpdateData {
|
||||||
pub display_name: Option<String>,
|
pub display_name: Option<String>,
|
||||||
|
|
|
@ -16,6 +16,7 @@ use crate::errors::HttpError;
|
||||||
use crate::mastodon_api::statuses::types::Status;
|
use crate::mastodon_api::statuses::types::Status;
|
||||||
use crate::mastodon_api::oauth::auth::get_current_user as get_current_user_;
|
use crate::mastodon_api::oauth::auth::get_current_user as get_current_user_;
|
||||||
use crate::mastodon_api::users::auth::get_current_user;
|
use crate::mastodon_api::users::auth::get_current_user;
|
||||||
|
use crate::mastodon_api::users::views::create_user_view;
|
||||||
use crate::models::posts::queries::get_posts_by_author;
|
use crate::models::posts::queries::get_posts_by_author;
|
||||||
use crate::models::profiles::queries::{
|
use crate::models::profiles::queries::{
|
||||||
get_profile_by_id,
|
get_profile_by_id,
|
||||||
|
@ -210,6 +211,7 @@ async fn get_account_statuses(
|
||||||
pub fn account_api_scope() -> Scope {
|
pub fn account_api_scope() -> Scope {
|
||||||
web::scope("/api/v1/accounts")
|
web::scope("/api/v1/accounts")
|
||||||
// Routes without account ID
|
// Routes without account ID
|
||||||
|
.service(create_user_view)
|
||||||
.service(get_relationships)
|
.service(get_relationships)
|
||||||
.service(verify_credentials)
|
.service(verify_credentials)
|
||||||
.service(update_credentials)
|
.service(update_credentials)
|
||||||
|
|
|
@ -7,16 +7,13 @@ use actix_web::{
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
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::mastodon_api::accounts::types::Account;
|
use crate::mastodon_api::accounts::types::{Account, AccountCreateData};
|
||||||
use crate::models::users::queries::{
|
use crate::models::users::queries::{
|
||||||
is_valid_invite_code,
|
is_valid_invite_code,
|
||||||
create_user,
|
create_user,
|
||||||
get_user_by_wallet_address,
|
get_user_by_wallet_address,
|
||||||
};
|
};
|
||||||
use crate::models::users::types::{
|
use crate::models::users::types::UserLoginData;
|
||||||
UserRegistrationData,
|
|
||||||
UserLoginData,
|
|
||||||
};
|
|
||||||
use crate::utils::crypto::{
|
use crate::utils::crypto::{
|
||||||
hash_password,
|
hash_password,
|
||||||
verify_password,
|
verify_password,
|
||||||
|
@ -26,25 +23,26 @@ use crate::utils::crypto::{
|
||||||
use super::auth::get_current_user;
|
use super::auth::get_current_user;
|
||||||
|
|
||||||
// /api/v1/accounts
|
// /api/v1/accounts
|
||||||
#[post("/api/v0/create")]
|
#[post("")]
|
||||||
async fn create_user_view(
|
pub async fn create_user_view(
|
||||||
config: web::Data<Config>,
|
config: web::Data<Config>,
|
||||||
db_pool: web::Data<Pool>,
|
db_pool: web::Data<Pool>,
|
||||||
form: web::Json<UserRegistrationData>,
|
account_data: web::Json<AccountCreateData>,
|
||||||
session: Session,
|
session: Session,
|
||||||
) -> Result<HttpResponse, HttpError> {
|
) -> Result<HttpResponse, HttpError> {
|
||||||
let db_client = &mut **get_database_client(&db_pool).await?;
|
let db_client = &mut **get_database_client(&db_pool).await?;
|
||||||
|
let user_data = account_data.into_inner().into_user_data();
|
||||||
// Validate
|
// Validate
|
||||||
form.clean()?;
|
user_data.clean()?;
|
||||||
if !config.registrations_open {
|
if !config.registrations_open {
|
||||||
let invite_code = form.invite_code.as_ref()
|
let invite_code = user_data.invite_code.as_ref()
|
||||||
.ok_or(ValidationError("invite code is required"))?;
|
.ok_or(ValidationError("invite code is required"))?;
|
||||||
if !is_valid_invite_code(db_client, &invite_code).await? {
|
if !is_valid_invite_code(db_client, &invite_code).await? {
|
||||||
Err(ValidationError("invalid invite code"))?;
|
Err(ValidationError("invalid invite code"))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Hash password and generate private key
|
// Hash password and generate private key
|
||||||
let password_hash = hash_password(&form.signature)
|
let password_hash = hash_password(&user_data.password)
|
||||||
.map_err(|_| HttpError::InternalError)?;
|
.map_err(|_| HttpError::InternalError)?;
|
||||||
let private_key = match web::block(move || generate_private_key()).await {
|
let private_key = match web::block(move || generate_private_key()).await {
|
||||||
Ok(private_key) => private_key,
|
Ok(private_key) => private_key,
|
||||||
|
@ -55,7 +53,7 @@ async fn create_user_view(
|
||||||
|
|
||||||
let user = create_user(
|
let user = create_user(
|
||||||
db_client,
|
db_client,
|
||||||
form.into_inner(),
|
user_data,
|
||||||
password_hash,
|
password_hash,
|
||||||
private_key_pem,
|
private_key_pem,
|
||||||
).await?;
|
).await?;
|
||||||
|
|
|
@ -4,7 +4,7 @@ use uuid::Uuid;
|
||||||
use crate::errors::DatabaseError;
|
use crate::errors::DatabaseError;
|
||||||
use crate::models::profiles::queries::create_profile;
|
use crate::models::profiles::queries::create_profile;
|
||||||
use crate::models::profiles::types::{DbActorProfile, ProfileCreateData};
|
use crate::models::profiles::types::{DbActorProfile, ProfileCreateData};
|
||||||
use super::types::{DbUser, User, UserRegistrationData};
|
use super::types::{DbUser, User, UserCreateData};
|
||||||
use super::utils::generate_invite_code;
|
use super::utils::generate_invite_code;
|
||||||
|
|
||||||
pub async fn create_invite_code(
|
pub async fn create_invite_code(
|
||||||
|
@ -118,13 +118,13 @@ pub async fn is_registered_user(
|
||||||
|
|
||||||
pub async fn create_user(
|
pub async fn create_user(
|
||||||
db_client: &mut impl GenericClient,
|
db_client: &mut impl GenericClient,
|
||||||
form: UserRegistrationData,
|
user_data: UserCreateData,
|
||||||
password_hash: String,
|
password_hash: String,
|
||||||
private_key_pem: String,
|
private_key_pem: String,
|
||||||
) -> Result<User, DatabaseError> {
|
) -> Result<User, DatabaseError> {
|
||||||
let transaction = db_client.transaction().await?;
|
let transaction = db_client.transaction().await?;
|
||||||
// Use invite code
|
// Use invite code
|
||||||
if let Some(ref invite_code) = form.invite_code {
|
if let Some(ref invite_code) = user_data.invite_code {
|
||||||
let updated_count = transaction.execute(
|
let updated_count = transaction.execute(
|
||||||
"
|
"
|
||||||
UPDATE user_invite_code
|
UPDATE user_invite_code
|
||||||
|
@ -139,9 +139,9 @@ pub async fn create_user(
|
||||||
}
|
}
|
||||||
// Create profile
|
// Create profile
|
||||||
let profile_data = ProfileCreateData {
|
let profile_data = ProfileCreateData {
|
||||||
username: form.username.clone(),
|
username: user_data.username.clone(),
|
||||||
display_name: None,
|
display_name: None,
|
||||||
acct: form.username.clone(),
|
acct: user_data.username.clone(),
|
||||||
bio: None,
|
bio: None,
|
||||||
avatar: None,
|
avatar: None,
|
||||||
banner: None,
|
banner: None,
|
||||||
|
@ -160,10 +160,10 @@ pub async fn create_user(
|
||||||
",
|
",
|
||||||
&[
|
&[
|
||||||
&profile.id,
|
&profile.id,
|
||||||
&form.wallet_address,
|
&user_data.wallet_address,
|
||||||
&password_hash,
|
&password_hash,
|
||||||
&private_key_pem,
|
&private_key_pem,
|
||||||
&form.invite_code,
|
&user_data.invite_code,
|
||||||
],
|
],
|
||||||
).await;
|
).await;
|
||||||
match result {
|
match result {
|
||||||
|
|
|
@ -29,9 +29,9 @@ pub struct User {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct UserRegistrationData {
|
pub struct UserCreateData {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub signature: String,
|
pub password: String,
|
||||||
pub wallet_address: String,
|
pub wallet_address: String,
|
||||||
pub invite_code: Option<String>,
|
pub invite_code: Option<String>,
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ fn validate_username(username: &str) -> Result<(), ValidationError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UserRegistrationData {
|
impl UserCreateData {
|
||||||
/// Validate and clean.
|
/// Validate and clean.
|
||||||
pub fn clean(&self) -> Result<(), ValidationError> {
|
pub fn clean(&self) -> Result<(), ValidationError> {
|
||||||
validate_username(&self.username)?;
|
validate_username(&self.username)?;
|
||||||
|
|
Loading…
Reference in a new issue