Change path of user creation endpoint

This commit is contained in:
silverpill 2021-10-05 20:57:24 +00:00
parent b39733beb7
commit 9519786788
6 changed files with 43 additions and 24 deletions

View file

@ -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)

View file

@ -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>,

View file

@ -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)

View file

@ -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?;

View file

@ -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 {

View file

@ -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)?;