]> Untitled Git - lemmy.git/blobdiff - crates/api_crud/src/user/create.rs
Making public key required. Fixes #1934
[lemmy.git] / crates / api_crud / src / user / create.rs
index 8047369fa722e24bb272650871fd647a35e111e6..2ce2fa366af7e6c19a813e0850900d840d089382 100644 (file)
@@ -1,35 +1,36 @@
 use crate::PerformCrud;
 use actix_web::web::Data;
-use lemmy_api_common::{blocking, password_length_check, person::*};
+use lemmy_api_common::{blocking, honeypot_check, password_length_check, person::*};
 use lemmy_apub::{
-  generate_apub_endpoint,
   generate_followers_url,
   generate_inbox_url,
+  generate_local_apub_endpoint,
   generate_shared_inbox_url,
   EndpointType,
 };
-use lemmy_db_queries::{
-  source::{local_user::LocalUser_, site::Site_},
-  Crud,
-  Followable,
-  Joinable,
-  ListingType,
-  SortType,
-};
 use lemmy_db_schema::{
+  newtypes::CommunityId,
   source::{
-    community::*,
+    community::{
+      Community,
+      CommunityFollower,
+      CommunityFollowerForm,
+      CommunityForm,
+      CommunityModerator,
+      CommunityModeratorForm,
+    },
     local_user::{LocalUser, LocalUserForm},
-    person::*,
-    site::*,
+    person::{Person, PersonForm},
+    site::Site,
   },
-  CommunityId,
+  traits::{Crud, Followable, Joinable},
+  ListingType,
+  SortType,
 };
 use lemmy_db_views_actor::person_view::PersonViewSafe;
 use lemmy_utils::{
   apub::generate_actor_keypair,
   claims::Claims,
-  settings::structs::Settings,
   utils::{check_slurs, is_valid_actor_name},
   ApiError,
   ConnectionId,
@@ -49,17 +50,18 @@ impl PerformCrud for Register {
     let data: &Register = self;
 
     // Make sure site has open registration
-    if let Ok(site) = blocking(context.pool(), move |conn| Site::read_simple(conn)).await? {
+    if let Ok(site) = blocking(context.pool(), Site::read_simple).await? {
       if !site.open_registration {
-        return Err(ApiError::err("registration_closed").into());
+        return Err(ApiError::err_plain("registration_closed").into());
       }
     }
 
     password_length_check(&data.password)?;
+    honeypot_check(&data.honeypot)?;
 
     // Make sure passwords match
     if data.password != data.password_verify {
-      return Err(ApiError::err("passwords_dont_match").into());
+      return Err(ApiError::err_plain("passwords_dont_match").into());
     }
 
     // Check if there are admins. False if admins exist
@@ -69,7 +71,7 @@ impl PerformCrud for Register {
     .await??;
 
     // If its not the admin, check the captcha
-    if !no_admins && Settings::get().captcha().enabled {
+    if !no_admins && context.settings().captcha.enabled {
       let check = context
         .chat_server()
         .send(CheckCaptcha {
@@ -84,17 +86,21 @@ impl PerformCrud for Register {
         })
         .await?;
       if !check {
-        return Err(ApiError::err("captcha_incorrect").into());
+        return Err(ApiError::err_plain("captcha_incorrect").into());
       }
     }
 
-    check_slurs(&data.username)?;
+    check_slurs(&data.username, &context.settings().slur_regex())?;
 
     let actor_keypair = generate_actor_keypair()?;
-    if !is_valid_actor_name(&data.username) {
-      return Err(ApiError::err("invalid_username").into());
+    if !is_valid_actor_name(&data.username, context.settings().actor_name_max_length) {
+      return Err(ApiError::err_plain("invalid_username").into());
     }
-    let actor_id = generate_apub_endpoint(EndpointType::Person, &data.username)?;
+    let actor_id = generate_local_apub_endpoint(
+      EndpointType::Person,
+      &data.username,
+      &context.settings().get_protocol_and_hostname(),
+    )?;
 
     // We have to create both a person, and local_user
 
@@ -103,7 +109,7 @@ impl PerformCrud for Register {
       name: data.username.to_owned(),
       actor_id: Some(actor_id.clone()),
       private_key: Some(Some(actor_keypair.private_key)),
-      public_key: Some(Some(actor_keypair.public_key)),
+      public_key: actor_keypair.public_key,
       inbox_url: Some(generate_inbox_url(&actor_id)?),
       shared_inbox_url: Some(Some(generate_shared_inbox_url(&actor_id)?)),
       admin: Some(no_admins),
@@ -115,7 +121,7 @@ impl PerformCrud for Register {
       Person::create(conn, &person_form)
     })
     .await?
-    .map_err(|_| ApiError::err("user_already_exists"))?;
+    .map_err(|e| ApiError::err("user_already_exists", e))?;
 
     // Create the local user
     // TODO some of these could probably use the DB defaults
@@ -157,13 +163,14 @@ impl PerformCrud for Register {
         })
         .await??;
 
-        return Err(ApiError::err(err_type).into());
+        return Err(ApiError::err(err_type, e).into());
       }
     };
 
     let main_community_keypair = generate_actor_keypair()?;
 
     // Create the main community if it doesn't exist
+    let protocol_and_hostname = context.settings().get_protocol_and_hostname();
     let main_community = match blocking(context.pool(), move |conn| {
       Community::read(conn, CommunityId(2))
     })
@@ -172,14 +179,18 @@ impl PerformCrud for Register {
       Ok(c) => c,
       Err(_e) => {
         let default_community_name = "main";
-        let actor_id = generate_apub_endpoint(EndpointType::Community, default_community_name)?;
+        let actor_id = generate_local_apub_endpoint(
+          EndpointType::Community,
+          default_community_name,
+          &protocol_and_hostname,
+        )?;
         let community_form = CommunityForm {
           name: default_community_name.to_string(),
           title: "The Default Community".to_string(),
           description: Some("The Default Community".to_string()),
           actor_id: Some(actor_id.to_owned()),
-          private_key: Some(main_community_keypair.private_key),
-          public_key: Some(main_community_keypair.public_key),
+          private_key: Some(Some(main_community_keypair.private_key)),
+          public_key: main_community_keypair.public_key,
           followers_url: Some(generate_followers_url(&actor_id)?),
           inbox_url: Some(generate_inbox_url(&actor_id)?),
           shared_inbox_url: Some(Some(generate_shared_inbox_url(&actor_id)?)),
@@ -200,9 +211,9 @@ impl PerformCrud for Register {
     };
 
     let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
-    if blocking(context.pool(), follow).await?.is_err() {
-      return Err(ApiError::err("community_follower_already_exists").into());
-    };
+    blocking(context.pool(), follow)
+      .await?
+      .map_err(|e| ApiError::err("community_follower_already_exists", e))?;
 
     // If its an admin, add them as a mod and follower to main
     if no_admins {
@@ -212,14 +223,18 @@ impl PerformCrud for Register {
       };
 
       let join = move |conn: &'_ _| CommunityModerator::join(conn, &community_moderator_form);
-      if blocking(context.pool(), join).await?.is_err() {
-        return Err(ApiError::err("community_moderator_already_exists").into());
-      }
+      blocking(context.pool(), join)
+        .await?
+        .map_err(|e| ApiError::err("community_moderator_already_exists", e))?;
     }
 
     // Return the jwt
     Ok(LoginResponse {
-      jwt: Claims::jwt(inserted_local_user.id.0)?,
+      jwt: Claims::jwt(
+        inserted_local_user.id.0,
+        &context.secret().jwt_secret,
+        &context.settings().hostname,
+      )?,
     })
   }
 }