From 8bea13d651c2b53f633e475b4ae426c8ef6678c9 Mon Sep 17 00:00:00 2001
From: Dessalines <dessalines@users.noreply.github.com>
Date: Fri, 25 Sep 2020 11:16:49 -0400
Subject: [PATCH] More overwriteable fields (#1155)

* Adding more overwriteable fields for user. Fixes #1154

* Adding a note for bio.
---
 lemmy_api/src/user.rs  | 35 ++++++++++++++---------------------
 lemmy_apub/src/user.rs |  7 +++++--
 lemmy_db/src/user.rs   |  6 +++---
 src/code_migrations.rs |  6 +++---
 4 files changed, 25 insertions(+), 29 deletions(-)

diff --git a/lemmy_api/src/user.rs b/lemmy_api/src/user.rs
index e2b73c53..60704e3c 100644
--- a/lemmy_api/src/user.rs
+++ b/lemmy_api/src/user.rs
@@ -335,31 +335,24 @@ impl Perform for SaveUserSettings {
     let user_id = user.id;
     let read_user = blocking(context.pool(), move |conn| User_::read(conn, user_id)).await??;
 
-    let bio = match &data.bio {
-      Some(bio) => {
-        if bio.chars().count() <= 300 {
-          Some(bio.to_owned())
-        } else {
-          return Err(APIError::err("bio_length_overflow").into());
-        }
-      }
-      None => read_user.bio,
-    };
-
     let avatar = diesel_option_overwrite(&data.avatar);
     let banner = diesel_option_overwrite(&data.banner);
     let email = diesel_option_overwrite(&data.email);
+    let bio = diesel_option_overwrite(&data.bio);
+    let preferred_username = diesel_option_overwrite(&data.preferred_username);
+    let matrix_user_id = diesel_option_overwrite(&data.matrix_user_id);
 
-    // The DB constraint should stop too many characters
-    let preferred_username = match &data.preferred_username {
-      Some(preferred_username) => {
-        if !is_valid_preferred_username(preferred_username.trim()) {
-          return Err(APIError::err("invalid_username").into());
-        }
-        Some(preferred_username.trim().to_string())
+    if let Some(Some(bio)) = &bio {
+      if bio.chars().count() > 300 {
+        return Err(APIError::err("bio_length_overflow").into());
       }
-      None => read_user.preferred_username,
-    };
+    }
+
+    if let Some(Some(preferred_username)) = &preferred_username {
+      if !is_valid_preferred_username(preferred_username.trim()) {
+        return Err(APIError::err("invalid_username").into());
+      }
+    }
 
     let password_encrypted = match &data.new_password {
       Some(new_password) => {
@@ -397,7 +390,7 @@ impl Perform for SaveUserSettings {
     let user_form = UserForm {
       name: read_user.name,
       email,
-      matrix_user_id: data.matrix_user_id.to_owned(),
+      matrix_user_id,
       avatar,
       banner,
       password_encrypted,
diff --git a/lemmy_apub/src/user.rs b/lemmy_apub/src/user.rs
index 950f59a1..60af834c 100644
--- a/lemmy_apub/src/user.rs
+++ b/lemmy_apub/src/user.rs
@@ -241,6 +241,9 @@ impl FromApub for UserForm {
       .context(location_info!())?
       .to_string();
     let preferred_username = person.inner.preferred_username().map(|u| u.to_string());
+
+    // TODO a limit check (like the API does) might need to be done
+    // here when we federate to other platforms. Same for preferred_username
     let bio = person
       .inner
       .summary()
@@ -253,7 +256,7 @@ impl FromApub for UserForm {
 
     Ok(UserForm {
       name,
-      preferred_username,
+      preferred_username: Some(preferred_username),
       password_encrypted: "".to_string(),
       admin: false,
       banned: false,
@@ -271,7 +274,7 @@ impl FromApub for UserForm {
       send_notifications_to_email: false,
       matrix_user_id: None,
       actor_id: Some(check_actor_domain(person, expected_domain)?),
-      bio,
+      bio: Some(bio),
       local: false,
       private_key: None,
       public_key: Some(person.ext_one.public_key.to_owned().public_key_pem),
diff --git a/lemmy_db/src/user.rs b/lemmy_db/src/user.rs
index f2c20e94..60fdebbb 100644
--- a/lemmy_db/src/user.rs
+++ b/lemmy_db/src/user.rs
@@ -42,7 +42,7 @@ pub struct User_ {
 #[table_name = "user_"]
 pub struct UserForm {
   pub name: String,
-  pub preferred_username: Option<String>,
+  pub preferred_username: Option<Option<String>>,
   pub password_encrypted: String,
   pub admin: bool,
   pub banned: bool,
@@ -57,9 +57,9 @@ pub struct UserForm {
   pub lang: String,
   pub show_avatars: bool,
   pub send_notifications_to_email: bool,
-  pub matrix_user_id: Option<String>,
+  pub matrix_user_id: Option<Option<String>>,
   pub actor_id: Option<String>,
-  pub bio: Option<String>,
+  pub bio: Option<Option<String>>,
   pub local: bool,
   pub private_key: Option<String>,
   pub public_key: Option<String>,
diff --git a/src/code_migrations.rs b/src/code_migrations.rs
index 6a69035d..bd3c7479 100644
--- a/src/code_migrations.rs
+++ b/src/code_migrations.rs
@@ -49,11 +49,11 @@ fn user_updates_2020_04_02(conn: &PgConnection) -> Result<(), LemmyError> {
     let form = UserForm {
       name: cuser.name.to_owned(),
       email: Some(cuser.email.to_owned()),
-      matrix_user_id: cuser.matrix_user_id.to_owned(),
+      matrix_user_id: Some(cuser.matrix_user_id.to_owned()),
       avatar: Some(cuser.avatar.to_owned()),
       banner: Some(cuser.banner.to_owned()),
       password_encrypted: cuser.password_encrypted.to_owned(),
-      preferred_username: cuser.preferred_username.to_owned(),
+      preferred_username: Some(cuser.preferred_username.to_owned()),
       published: Some(cuser.published),
       updated: None,
       admin: cuser.admin,
@@ -66,7 +66,7 @@ fn user_updates_2020_04_02(conn: &PgConnection) -> Result<(), LemmyError> {
       show_avatars: cuser.show_avatars,
       send_notifications_to_email: cuser.send_notifications_to_email,
       actor_id: Some(make_apub_endpoint(EndpointType::User, &cuser.name).to_string()),
-      bio: cuser.bio.to_owned(),
+      bio: Some(cuser.bio.to_owned()),
       local: cuser.local,
       private_key: Some(keypair.private_key),
       public_key: Some(keypair.public_key),
-- 
2.44.1