From: Dessalines <tyhou13@gmx.com>
Date: Sat, 5 Dec 2020 04:18:30 +0000 (-0500)
Subject: Userview safe updated.
X-Git-Url: http://these/git/sneer-club-logo.svg?a=commitdiff_plain;h=028d1d0efc78451c0002a009b73fd7e1174886d2;p=lemmy.git

Userview safe updated.
---

diff --git a/lemmy_db/src/lib.rs b/lemmy_db/src/lib.rs
index 61a2120d..4f2e85cd 100644
--- a/lemmy_db/src/lib.rs
+++ b/lemmy_db/src/lib.rs
@@ -140,6 +140,11 @@ impl<T> MaybeOptional<T> for Option<T> {
   }
 }
 
+pub(crate) trait ToSafe {
+  type SafeColumns;
+  fn safe_columns_tuple() -> Self::SafeColumns;
+}
+
 pub fn get_database_url_from_env() -> Result<String, VarError> {
   env::var("LEMMY_DATABASE_URL")
 }
diff --git a/lemmy_db/src/user.rs b/lemmy_db/src/user.rs
index 96483c1d..38955426 100644
--- a/lemmy_db/src/user.rs
+++ b/lemmy_db/src/user.rs
@@ -40,6 +40,26 @@ pub struct User_ {
   pub deleted: bool,
 }
 
+/// A safe representation of user, without the sensitive info
+#[derive(Clone, Queryable, Identifiable, PartialEq, Debug, Serialize)]
+#[table_name = "user_"]
+pub struct UserSafe {
+  pub id: i32,
+  pub name: String,
+  pub preferred_username: Option<String>,
+  pub avatar: Option<String>,
+  pub admin: bool,
+  pub banned: bool,
+  pub published: chrono::NaiveDateTime,
+  pub updated: Option<chrono::NaiveDateTime>,
+  pub matrix_user_id: Option<String>,
+  pub actor_id: String,
+  pub bio: Option<String>,
+  pub local: bool,
+  pub banner: Option<String>,
+  pub deleted: bool,
+}
+
 #[derive(Insertable, AsChangeset, Clone)]
 #[table_name = "user_"]
 pub struct UserForm {
@@ -69,25 +89,6 @@ pub struct UserForm {
   pub banner: Option<Option<String>>,
 }
 
-/// A safe representation of user, without the sensitive info
-#[derive(Clone, Debug, Serialize)]
-pub struct UserSafe {
-  pub id: i32,
-  pub name: String,
-  pub preferred_username: Option<String>,
-  pub avatar: Option<String>,
-  pub admin: bool,
-  pub banned: bool,
-  pub published: chrono::NaiveDateTime,
-  pub updated: Option<chrono::NaiveDateTime>,
-  pub matrix_user_id: Option<String>,
-  pub actor_id: String,
-  pub bio: Option<String>,
-  pub local: bool,
-  pub banner: Option<String>,
-  pub deleted: bool,
-}
-
 impl Crud<UserForm> for User_ {
   fn read(conn: &PgConnection, user_id: i32) -> Result<Self, Error> {
     user_
@@ -219,23 +220,46 @@ impl User_ {
       ))
       .get_result::<Self>(conn)
   }
+}
+
+mod safe_type {
+  use crate::{schema::user_::columns::*, user::User_, ToSafe};
+  type Columns = (
+    id,
+    name,
+    preferred_username,
+    avatar,
+    admin,
+    banned,
+    published,
+    updated,
+    matrix_user_id,
+    actor_id,
+    bio,
+    local,
+    banner,
+    deleted,
+  );
 
-  pub fn to_safe(&self) -> UserSafe {
-    UserSafe {
-      id: self.id,
-      name: self.name.to_owned(),
-      preferred_username: self.preferred_username.to_owned(),
-      avatar: self.avatar.to_owned(),
-      admin: self.admin,
-      banned: self.banned,
-      published: self.published,
-      updated: self.updated,
-      matrix_user_id: self.matrix_user_id.to_owned(),
-      actor_id: self.actor_id.to_owned(),
-      bio: self.bio.to_owned(),
-      local: self.local,
-      banner: self.banner.to_owned(),
-      deleted: self.deleted,
+  impl ToSafe for User_ {
+    type SafeColumns = Columns;
+    fn safe_columns_tuple() -> Self::SafeColumns {
+      (
+        id,
+        name,
+        preferred_username,
+        avatar,
+        admin,
+        banned,
+        published,
+        updated,
+        matrix_user_id,
+        actor_id,
+        bio,
+        local,
+        banner,
+        deleted,
+      )
     }
   }
 }
diff --git a/lemmy_db/src/views/community_view.rs b/lemmy_db/src/views/community_view.rs
index 4e0b5882..2972b1fe 100644
--- a/lemmy_db/src/views/community_view.rs
+++ b/lemmy_db/src/views/community_view.rs
@@ -4,6 +4,7 @@ use crate::{
   community::{Community, CommunityFollower},
   schema::{category, community, community_aggregates, community_follower, user_},
   user::{UserSafe, User_},
+  ToSafe,
 };
 use diesel::{result::Error, *};
 use serde::Serialize;
@@ -39,11 +40,17 @@ impl CommunityView {
       .inner_join(user_::table)
       .inner_join(category::table)
       .inner_join(community_aggregates::table)
-      .first::<(Community, User_, Category, CommunityAggregates)>(conn)?;
+      .select((
+        community::all_columns,
+        User_::safe_columns_tuple(),
+        category::all_columns,
+        community_aggregates::all_columns,
+      ))
+      .first::<(Community, UserSafe, Category, CommunityAggregates)>(conn)?;
 
     Ok(CommunityView {
       community,
-      creator: creator.to_safe(),
+      creator,
       category,
       subscribed,
       counts,
diff --git a/lemmy_db/src/views/site_view.rs b/lemmy_db/src/views/site_view.rs
index 547c13b4..c00b8378 100644
--- a/lemmy_db/src/views/site_view.rs
+++ b/lemmy_db/src/views/site_view.rs
@@ -2,6 +2,7 @@ use crate::{
   schema::{site, user_},
   site::Site,
   user::{UserSafe, User_},
+  ToSafe,
 };
 use diesel::{result::Error, *};
 use serde::Serialize;
@@ -16,11 +17,9 @@ impl SiteView {
   pub fn read(conn: &PgConnection) -> Result<Self, Error> {
     let (site, creator) = site::table
       .inner_join(user_::table)
-      .first::<(Site, User_)>(conn)?;
+      .select((site::all_columns, User_::safe_columns_tuple()))
+      .first::<(Site, UserSafe)>(conn)?;
 
-    Ok(SiteView {
-      site,
-      creator: creator.to_safe(),
-    })
+    Ok(SiteView { site, creator })
   }
 }
diff --git a/lemmy_db/src/views/user_view.rs b/lemmy_db/src/views/user_view.rs
index be80179b..76bc3c3d 100644
--- a/lemmy_db/src/views/user_view.rs
+++ b/lemmy_db/src/views/user_view.rs
@@ -6,6 +6,7 @@ use crate::{
   user::{UserSafe, User_},
   MaybeOptional,
   SortType,
+  ToSafe,
 };
 use diesel::{dsl::*, result::Error, *};
 use serde::Serialize;
@@ -37,30 +38,30 @@ impl UserViewSafe {
     let (user, counts) = user_::table
       .find(id)
       .inner_join(user_aggregates::table)
-      .first::<(User_, UserAggregates)>(conn)?;
-    Ok(Self {
-      user: user.to_safe(),
-      counts,
-    })
+      .select((User_::safe_columns_tuple(), user_aggregates::all_columns))
+      .first::<(UserSafe, UserAggregates)>(conn)?;
+    Ok(Self { user, counts })
   }
 
   pub fn admins(conn: &PgConnection) -> Result<Vec<Self>, Error> {
     let admins = user_::table
       .inner_join(user_aggregates::table)
+      .select((User_::safe_columns_tuple(), user_aggregates::all_columns))
       .filter(user_::admin.eq(true))
       .order_by(user_::published)
-      .load::<(User_, UserAggregates)>(conn)?;
+      .load::<(UserSafe, UserAggregates)>(conn)?;
 
-    Ok(vec_to_user_view_safe(admins))
+    Ok(to_vec(admins))
   }
 
   pub fn banned(conn: &PgConnection) -> Result<Vec<Self>, Error> {
     let banned = user_::table
       .inner_join(user_aggregates::table)
+      .select((User_::safe_columns_tuple(), user_aggregates::all_columns))
       .filter(user_::banned.eq(true))
-      .load::<(User_, UserAggregates)>(conn)?;
+      .load::<(UserSafe, UserAggregates)>(conn)?;
 
-    Ok(vec_to_user_view_safe(banned))
+    Ok(to_vec(banned))
   }
 }
 
@@ -77,34 +78,24 @@ mod join_types {
   pub(super) type BoxedUserJoin<'a> = BoxedSelectStatement<
     'a,
     (
+      // UserSafe column types
       (
         Integer,
         Text,
         Nullable<Text>,
-        Text,
-        Nullable<Text>,
         Nullable<Text>,
-        diesel::sql_types::Bool,
+        Bool,
         Bool,
         Timestamp,
         Nullable<Timestamp>,
-        Bool,
-        Text,
-        SmallInt,
-        SmallInt,
-        Text,
-        Bool,
-        Bool,
         Nullable<Text>,
         Text,
         Nullable<Text>,
         Bool,
         Nullable<Text>,
-        Nullable<Text>,
-        Timestamp,
-        Nullable<Text>,
         Bool,
       ),
+      // UserAggregates column types
       (Integer, Integer, BigInt, BigInt, BigInt, BigInt),
     ),
     JoinOn<
@@ -128,7 +119,10 @@ pub struct UserQueryBuilder<'a> {
 
 impl<'a> UserQueryBuilder<'a> {
   pub fn create(conn: &'a PgConnection) -> Self {
-    let query = user_::table.inner_join(user_aggregates::table).into_boxed();
+    let query = user_::table
+      .inner_join(user_aggregates::table)
+      .select((User_::safe_columns_tuple(), user_aggregates::all_columns))
+      .into_boxed();
 
     UserQueryBuilder {
       conn,
@@ -192,17 +186,17 @@ impl<'a> UserQueryBuilder<'a> {
     let (limit, offset) = limit_and_offset(self.page, self.limit);
     query = query.limit(limit).offset(offset);
 
-    let res = query.load::<(User_, UserAggregates)>(self.conn)?;
+    let res = query.load::<(UserSafe, UserAggregates)>(self.conn)?;
 
-    Ok(vec_to_user_view_safe(res))
+    Ok(to_vec(res))
   }
 }
 
-fn vec_to_user_view_safe(users: Vec<(User_, UserAggregates)>) -> Vec<UserViewSafe> {
+fn to_vec(users: Vec<(UserSafe, UserAggregates)>) -> Vec<UserViewSafe> {
   users
     .iter()
     .map(|a| UserViewSafe {
-      user: a.0.to_safe(),
+      user: a.0.to_owned(),
       counts: a.1.to_owned(),
     })
     .collect::<Vec<UserViewSafe>>()