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(),
|
||||
))
|
||||
.service(oauth_api_scope())
|
||||
.service(user_api::create_user_view)
|
||||
.service(user_api::login_view)
|
||||
.service(user_api::current_user_view)
|
||||
.service(user_api::logout_view)
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::models::profiles::types::{
|
|||
ExtraField,
|
||||
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};
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
@ -96,6 +96,26 @@ impl Account {
|
|||
}
|
||||
|
||||
/// 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)]
|
||||
pub struct AccountUpdateData {
|
||||
pub display_name: Option<String>,
|
||||
|
|
|
@ -16,6 +16,7 @@ use crate::errors::HttpError;
|
|||
use crate::mastodon_api::statuses::types::Status;
|
||||
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::views::create_user_view;
|
||||
use crate::models::posts::queries::get_posts_by_author;
|
||||
use crate::models::profiles::queries::{
|
||||
get_profile_by_id,
|
||||
|
@ -210,6 +211,7 @@ async fn get_account_statuses(
|
|||
pub fn account_api_scope() -> Scope {
|
||||
web::scope("/api/v1/accounts")
|
||||
// Routes without account ID
|
||||
.service(create_user_view)
|
||||
.service(get_relationships)
|
||||
.service(verify_credentials)
|
||||
.service(update_credentials)
|
||||
|
|
|
@ -7,16 +7,13 @@ use actix_web::{
|
|||
use crate::config::Config;
|
||||
use crate::database::{Pool, get_database_client};
|
||||
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::{
|
||||
is_valid_invite_code,
|
||||
create_user,
|
||||
get_user_by_wallet_address,
|
||||
};
|
||||
use crate::models::users::types::{
|
||||
UserRegistrationData,
|
||||
UserLoginData,
|
||||
};
|
||||
use crate::models::users::types::UserLoginData;
|
||||
use crate::utils::crypto::{
|
||||
hash_password,
|
||||
verify_password,
|
||||
|
@ -26,25 +23,26 @@ use crate::utils::crypto::{
|
|||
use super::auth::get_current_user;
|
||||
|
||||
// /api/v1/accounts
|
||||
#[post("/api/v0/create")]
|
||||
async fn create_user_view(
|
||||
#[post("")]
|
||||
pub async fn create_user_view(
|
||||
config: web::Data<Config>,
|
||||
db_pool: web::Data<Pool>,
|
||||
form: web::Json<UserRegistrationData>,
|
||||
account_data: web::Json<AccountCreateData>,
|
||||
session: Session,
|
||||
) -> Result<HttpResponse, HttpError> {
|
||||
let db_client = &mut **get_database_client(&db_pool).await?;
|
||||
let user_data = account_data.into_inner().into_user_data();
|
||||
// Validate
|
||||
form.clean()?;
|
||||
user_data.clean()?;
|
||||
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"))?;
|
||||
if !is_valid_invite_code(db_client, &invite_code).await? {
|
||||
Err(ValidationError("invalid invite code"))?;
|
||||
}
|
||||
}
|
||||
// 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)?;
|
||||
let private_key = match web::block(move || generate_private_key()).await {
|
||||
Ok(private_key) => private_key,
|
||||
|
@ -55,7 +53,7 @@ async fn create_user_view(
|
|||
|
||||
let user = create_user(
|
||||
db_client,
|
||||
form.into_inner(),
|
||||
user_data,
|
||||
password_hash,
|
||||
private_key_pem,
|
||||
).await?;
|
||||
|
|
|
@ -4,7 +4,7 @@ use uuid::Uuid;
|
|||
use crate::errors::DatabaseError;
|
||||
use crate::models::profiles::queries::create_profile;
|
||||
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;
|
||||
|
||||
pub async fn create_invite_code(
|
||||
|
@ -118,13 +118,13 @@ pub async fn is_registered_user(
|
|||
|
||||
pub async fn create_user(
|
||||
db_client: &mut impl GenericClient,
|
||||
form: UserRegistrationData,
|
||||
user_data: UserCreateData,
|
||||
password_hash: String,
|
||||
private_key_pem: String,
|
||||
) -> Result<User, DatabaseError> {
|
||||
let transaction = db_client.transaction().await?;
|
||||
// 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(
|
||||
"
|
||||
UPDATE user_invite_code
|
||||
|
@ -139,9 +139,9 @@ pub async fn create_user(
|
|||
}
|
||||
// Create profile
|
||||
let profile_data = ProfileCreateData {
|
||||
username: form.username.clone(),
|
||||
username: user_data.username.clone(),
|
||||
display_name: None,
|
||||
acct: form.username.clone(),
|
||||
acct: user_data.username.clone(),
|
||||
bio: None,
|
||||
avatar: None,
|
||||
banner: None,
|
||||
|
@ -160,10 +160,10 @@ pub async fn create_user(
|
|||
",
|
||||
&[
|
||||
&profile.id,
|
||||
&form.wallet_address,
|
||||
&user_data.wallet_address,
|
||||
&password_hash,
|
||||
&private_key_pem,
|
||||
&form.invite_code,
|
||||
&user_data.invite_code,
|
||||
],
|
||||
).await;
|
||||
match result {
|
||||
|
|
|
@ -29,9 +29,9 @@ pub struct User {
|
|||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct UserRegistrationData {
|
||||
pub struct UserCreateData {
|
||||
pub username: String,
|
||||
pub signature: String,
|
||||
pub password: String,
|
||||
pub wallet_address: String,
|
||||
pub invite_code: Option<String>,
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ fn validate_username(username: &str) -> Result<(), ValidationError> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
impl UserRegistrationData {
|
||||
impl UserCreateData {
|
||||
/// Validate and clean.
|
||||
pub fn clean(&self) -> Result<(), ValidationError> {
|
||||
validate_username(&self.username)?;
|
||||
|
|
Loading…
Reference in a new issue