Browse Source

fix autosubscribe sql, cargo fmt

feature/better-newuser-experience
Dash8 2 years ago
parent
commit
07c271fa3c
  1. 2
      server/lemmy_api_structs/src/community.rs
  2. 2
      server/lemmy_api_structs/src/lib.rs
  3. 18
      server/lemmy_api_structs/src/site.rs
  4. 4
      server/lemmy_db/src/activity.rs
  5. 35
      server/lemmy_db/src/comment.rs
  6. 17
      server/lemmy_db/src/comment_view.rs
  7. 7
      server/lemmy_db/src/community.rs
  8. 2
      server/lemmy_db/src/lib.rs
  9. 21
      server/lemmy_db/src/moderator.rs
  10. 7
      server/lemmy_db/src/password_reset_request.rs
  11. 36
      server/lemmy_db/src/post.rs
  12. 12
      server/lemmy_db/src/post_view.rs
  13. 6
      server/lemmy_db/src/private_message.rs
  14. 78
      server/lemmy_db/src/schema.rs
  15. 14
      server/lemmy_db/src/user.rs
  16. 174
      server/lemmy_db/src/user_ban_id.rs
  17. 10
      server/lemmy_db/src/user_mention.rs
  18. 52
      server/lemmy_db/src/user_view.rs
  19. 14
      server/lemmy_utils/src/lib.rs
  20. 9
      server/migrations/2021-05-13-171343_comms_to_autosubscribe/down.sql
  21. 9
      server/migrations/2021-05-13-171343_comms_to_autosubscribe/up.sql
  22. 39
      server/src/api/comment.rs
  23. 39
      server/src/api/community.rs
  24. 5
      server/src/api/community_settings.rs
  25. 20
      server/src/api/mod.rs
  26. 35
      server/src/api/post.rs
  27. 8
      server/src/api/report.rs
  28. 132
      server/src/api/user.rs
  29. 8
      server/src/apub/activity_queue.rs
  30. 34
      server/src/apub/comment.rs
  31. 22
      server/src/apub/community.rs
  32. 11
      server/src/apub/fetcher.rs
  33. 9
      server/src/apub/inbox/activities/announce.rs
  34. 8
      server/src/apub/inbox/activities/create.rs
  35. 13
      server/src/apub/inbox/activities/delete.rs
  36. 7
      server/src/apub/inbox/activities/dislike.rs
  37. 7
      server/src/apub/inbox/activities/like.rs
  38. 13
      server/src/apub/inbox/activities/remove.rs
  39. 16
      server/src/apub/inbox/activities/undo.rs
  40. 8
      server/src/apub/inbox/activities/update.rs
  41. 10
      server/src/apub/inbox/community_inbox.rs
  42. 12
      server/src/apub/inbox/shared_inbox.rs
  43. 6
      server/src/apub/inbox/user_inbox.rs
  44. 9
      server/src/apub/mod.rs
  45. 24
      server/src/apub/post.rs
  46. 23
      server/src/apub/private_message.rs
  47. 20
      server/src/apub/user.rs
  48. 19
      server/src/main.rs
  49. 2
      server/src/routes/api.rs
  50. 3
      server/src/routes/feeds.rs
  51. 5
      server/src/routes/images.rs
  52. 5
      server/src/routes/webfinger.rs
  53. 11
      server/src/websocket/chat_server.rs

2
server/lemmy_api_structs/src/community.rs

@ -140,4 +140,4 @@ pub struct CommunityJoinRoom {
#[derive(Serialize, Deserialize)]
pub struct CommunityJoinRoomResponse {
pub community_id: i32,
}
}

2
server/lemmy_api_structs/src/lib.rs

@ -24,4 +24,4 @@ impl APIError {
message: msg.to_string(),
}
}
}
}

18
server/lemmy_api_structs/src/site.rs

@ -1,12 +1,6 @@
use lemmy_db::{
category::*,
comment_view::*,
community_view::*,
moderator_views::*,
post_view::*,
site_view::*,
user::*,
user_view::*,
category::*, comment_view::*, community_view::*, moderator_views::*, post_view::*, site_view::*,
user::*, user_view::*,
};
use serde::{Deserialize, Serialize};
@ -45,18 +39,18 @@ pub struct GetModlog {
pub community_id: Option<i32>,
pub page: Option<i64>,
pub limit: Option<i64>,
pub action_filter: Option<u16>, //9 bits for each type of mod action
pub auth: Option<String>, // hexbear
pub action_filter: Option<u16>, //9 bits for each type of mod action
pub auth: Option<String>, // hexbear
}
//exists in upstream, but is different from hexbear ----------
#[derive(Serialize)]
pub struct GetModlogResponse {
pub log: Vec<ModlogAction>
pub log: Vec<ModlogAction>,
}
#[derive(Serialize, Deserialize)]
#[serde(tag = "type")] //enum type is inline with the internal data
#[serde(tag = "type")] //enum type is inline with the internal data
pub enum ModlogAction {
RemovePost(ModRemovePostView),
LockPost(ModLockPostView),

4
server/lemmy_db/src/activity.rs

@ -85,9 +85,7 @@ mod tests {
activity::{Activity, ActivityForm},
tests::establish_unpooled_connection,
user::{UserForm, User_},
Crud,
ListingType,
SortType,
Crud, ListingType, SortType,
};
use serde_json::Value;

35
server/lemmy_db/src/comment.rs

@ -2,10 +2,7 @@ use super::post::Post;
use crate::{
naive_now,
schema::{comment, comment_like, comment_report, comment_saved},
Crud,
Likeable,
Reportable,
Saveable,
Crud, Likeable, Reportable, Saveable,
};
use diesel::{dsl::*, result::Error, sql_types::Integer, *};
use serde::{Deserialize, Serialize};
@ -199,15 +196,19 @@ impl Comment {
.get_result::<Self>(conn)
}
pub fn permadelete_user_comments(conn: &PgConnection, for_creator_id: i32) -> Result<Vec<i32>, Error> {
pub fn permadelete_user_comments(
conn: &PgConnection,
for_creator_id: i32,
) -> Result<Vec<i32>, Error> {
use crate::schema::comment::dsl::*;
diesel::update(
comment
.filter(creator_id.eq(for_creator_id))
)
.set((deleted.eq(true), updated.eq(naive_now()), content.eq("*Permananently Deleted*")))
.returning(id)
.get_results(conn)
diesel::update(comment.filter(creator_id.eq(for_creator_id)))
.set((
deleted.eq(true),
updated.eq(naive_now()),
content.eq("*Permananently Deleted*"),
))
.returning(id)
.get_results(conn)
}
pub fn remove_user_comments(conn: &PgConnection, for_creator_id: i32) -> Result<Vec<i32>, Error> {
@ -370,14 +371,8 @@ impl Saveable<CommentSavedForm> for CommentSaved {
#[cfg(test)]
mod tests {
use crate::{
comment::*,
community::*,
post::*,
tests::establish_unpooled_connection,
user::*,
Crud,
ListingType,
SortType,
comment::*, community::*, post::*, tests::establish_unpooled_connection, user::*, Crud,
ListingType, SortType,
};
#[test]

17
server/lemmy_db/src/comment_view.rs

@ -225,7 +225,11 @@ impl<'a> CommentQueryBuilder<'a> {
};
//in these cases listingtype doesn't matter
if self.for_post_id.is_none() && self.for_comment_ids.is_none() && self.for_community_id.is_none() && self.for_creator_id.is_none() {
if self.for_post_id.is_none()
&& self.for_comment_ids.is_none()
&& self.for_community_id.is_none()
&& self.for_creator_id.is_none()
{
query = match self.listing_type {
ListingType::Subscribed => query.filter(subscribed.eq(true)),
ListingType::Local => query.filter(community_local.eq(true)),
@ -481,15 +485,8 @@ impl<'a> ReplyQueryBuilder<'a> {
#[cfg(test)]
mod tests {
use crate::{
comment::*,
comment_view::*,
community::*,
post::*,
tests::establish_unpooled_connection,
user::*,
Crud,
Likeable,
*,
comment::*, comment_view::*, community::*, post::*, tests::establish_unpooled_connection,
user::*, Crud, Likeable, *,
};
#[test]

7
server/lemmy_db/src/community.rs

@ -2,10 +2,7 @@ use crate::{
community_settings::CommunitySettings,
naive_now,
schema::{community, community_follower, community_moderator, community_user_ban},
Bannable,
Crud,
Followable,
Joinable,
Bannable, Crud, Followable, Joinable,
};
use diesel::{dsl::*, result::Error, *};
use serde::{Deserialize, Serialize};
@ -155,7 +152,7 @@ impl Community {
.append(&mut UserViewSafe::admins(conn).map(|v| v.into_iter().map(|a| a.id).collect())?);
mods_and_admins
.append(&mut UserViewSafe::sitemods(conn).map(|v| v.into_iter().map(|a| a.id).collect())?);
.append(&mut UserViewSafe::sitemods(conn).map(|v| v.into_iter().map(|a| a.id).collect())?);
Ok(mods_and_admins)
}

2
server/lemmy_db/src/lib.rs

@ -45,8 +45,8 @@ pub mod user_tag;
pub mod user_view;
// hexbear
pub mod user_token;
pub mod user_ban_id;
pub mod user_token;
pub trait Crud<T> {
fn create(conn: &PgConnection, form: &T) -> Result<Self, Error>

21
server/lemmy_db/src/moderator.rs

@ -1,14 +1,7 @@
use crate::{
schema::{
mod_add,
mod_add_community,
mod_ban,
mod_ban_from_community,
mod_lock_post,
mod_remove_comment,
mod_remove_community,
mod_remove_post,
mod_sticky_post,
mod_add, mod_add_community, mod_ban, mod_ban_from_community, mod_lock_post, mod_remove_comment,
mod_remove_community, mod_remove_post, mod_sticky_post,
},
Crud,
};
@ -414,14 +407,8 @@ impl Crud<ModAddForm> for ModAdd {
#[cfg(test)]
mod tests {
use crate::{
comment::*,
community::*,
moderator::*,
post::*,
tests::establish_unpooled_connection,
user::*,
ListingType,
SortType,
comment::*, community::*, moderator::*, post::*, tests::establish_unpooled_connection, user::*,
ListingType, SortType,
};
// use Crud;

7
server/lemmy_db/src/password_reset_request.rs

@ -80,11 +80,8 @@ impl PasswordResetRequest {
mod tests {
use super::super::user::*;
use crate::{
password_reset_request::PasswordResetRequest,
tests::establish_unpooled_connection,
Crud,
ListingType,
SortType,
password_reset_request::PasswordResetRequest, tests::establish_unpooled_connection, Crud,
ListingType, SortType,
};
#[test]

36
server/lemmy_db/src/post.rs

@ -1,11 +1,7 @@
use crate::{
naive_now,
schema::{post, post_like, post_read, post_report, post_saved},
Crud,
Likeable,
Readable,
Reportable,
Saveable,
Crud, Likeable, Readable, Reportable, Saveable,
};
use diesel::{dsl::*, result::Error, *};
use serde::{Deserialize, Serialize};
@ -209,24 +205,25 @@ impl Post {
.get_result::<Self>(conn)
}
pub fn permadelete_user_posts(conn: &PgConnection, for_creator_id: i32) -> Result<Vec<i32>, Error> {
pub fn permadelete_user_posts(
conn: &PgConnection,
for_creator_id: i32,
) -> Result<Vec<i32>, Error> {
use crate::schema::post::dsl::*;
let perma_deleted = "*Permananently Deleted*";
let perma_deleted_url = "https://deleted.com";
diesel::update(
post
.filter(creator_id.eq(for_creator_id)),
)
.set((
diesel::update(post.filter(creator_id.eq(for_creator_id)))
.set((
deleted.eq(true),
updated.eq(naive_now()),
name.eq(perma_deleted),
url.eq(perma_deleted_url),
body.eq(perma_deleted)))
.returning(id)
.get_results(conn)
name.eq(perma_deleted),
url.eq(perma_deleted_url),
body.eq(perma_deleted),
))
.returning(id)
.get_results(conn)
}
pub fn update_featured(
@ -447,12 +444,7 @@ impl Readable<PostReadForm> for PostRead {
#[cfg(test)]
mod tests {
use crate::{
community::*,
post::*,
tests::establish_unpooled_connection,
user::*,
ListingType,
SortType,
community::*, post::*, tests::establish_unpooled_connection, user::*, ListingType, SortType,
};
#[test]

12
server/lemmy_db/src/post_view.rs

@ -252,7 +252,7 @@ impl<'a> PostQueryBuilder<'a> {
query = query.filter(community_hide_from_all.eq(false).or(subscribed.eq(true)));
}
query
},
}
_ => query,
};
@ -380,14 +380,8 @@ impl PostView {
#[cfg(test)]
mod tests {
use crate::{
community::*,
post::*,
post_view::*,
tests::establish_unpooled_connection,
user::*,
Crud,
Likeable,
*,
community::*, post::*, post_view::*, tests::establish_unpooled_connection, user::*, Crud,
Likeable, *,
};
#[test]

6
server/lemmy_db/src/private_message.rs

@ -138,11 +138,7 @@ impl PrivateMessage {
#[cfg(test)]
mod tests {
use crate::{
private_message::*,
tests::establish_unpooled_connection,
user::*,
ListingType,
SortType,
private_message::*, tests::establish_unpooled_connection, user::*, ListingType, SortType,
};
#[test]

78
server/lemmy_db/src/schema.rs

@ -9,7 +9,7 @@ table! {
}
}
table!{
table! {
hexbear.ban_id (id) {
id -> Uuid,
created -> Timestamp,
@ -628,43 +628,43 @@ joinable!(user_tag -> user_ (user_id));
joinable!(user_tokens -> user_ (user_id));
allow_tables_to_appear_in_same_query!(
activity,
category,
comment,
comment_aggregates_fast,
comment_like,
comment_report,
comment_saved,
community,
community_aggregates_fast,
community_follower,
community_moderator,
community_settings,
community_user_ban,
community_user_tag,
mod_add,
mod_add_community,
mod_ban,
mod_ban_from_community,
mod_lock_post,
mod_remove_comment,
mod_remove_community,
mod_remove_post,
mod_sticky_post,
password_reset_request,
post,
post_aggregates_fast,
post_like,
post_read,
post_report,
post_saved,
private_message,
site,
user_,
user_ban,
user_ban_id,
user_fast,
user_mention,
user_tag,
activity,
category,
comment,
comment_aggregates_fast,
comment_like,
comment_report,
comment_saved,
community,
community_aggregates_fast,
community_follower,
community_moderator,
community_settings,
community_user_ban,
community_user_tag,
mod_add,
mod_add_community,
mod_ban,
mod_ban_from_community,
mod_lock_post,
mod_remove_comment,
mod_remove_community,
mod_remove_post,
mod_sticky_post,
password_reset_request,
post,
post_aggregates_fast,
post_like,
post_read,
post_report,
post_saved,
private_message,
site,
user_,
user_ban,
user_ban_id,
user_fast,
user_mention,
user_tag,
user_tokens,
);

14
server/lemmy_db/src/user.rs

@ -1,6 +1,5 @@
use crate::{
is_email_regex,
naive_now,
is_email_regex, naive_now,
schema::{user_, user_::dsl::*},
Crud,
};
@ -124,10 +123,15 @@ impl User_ {
.get_result::<Self>(conn)
}
pub fn update_username(conn: &PgConnection, user_id: i32, new_uname: String, new_actor: String) -> Result<Self, Error> {
pub fn update_username(
conn: &PgConnection,
user_id: i32,
new_uname: String,
new_actor: String,
) -> Result<Self, Error> {
diesel::update(user_.find(user_id))
.set((name.eq(new_uname.clone()), actor_id.eq(new_actor)))
.get_result::<Self>(conn)
.set((name.eq(new_uname.clone()), actor_id.eq(new_actor)))
.get_result::<Self>(conn)
}
pub fn read_from_name(conn: &PgConnection, from_user_name: &str) -> Result<Self, Error> {

174
server/lemmy_db/src/user_ban_id.rs

@ -1,102 +1,136 @@
use diesel::{dsl::*, result::Error, *};
use crate::schema::{
{ban_id, ban_id::dsl::*},
{user_ban_id, user_ban_id::dsl::*},
{ban_id, ban_id::dsl::*},
{user_ban_id, user_ban_id::dsl::*},
};
use uuid::Uuid;
use crate::user_view::UserViewSafe;
use diesel::{dsl::*, result::Error, *};
use uuid::Uuid;
#[derive(Queryable, Insertable)]
#[table_name = "ban_id"]
pub struct BanId {
pub id: Uuid,
pub created: chrono::NaiveDateTime,
pub aliased_to: Option<Uuid>,
pub id: Uuid,
pub created: chrono::NaiveDateTime,
pub aliased_to: Option<Uuid>,
}
#[derive(Queryable, Insertable)]
#[table_name = "user_ban_id"]
pub struct UserBanId {
pub bid: Uuid,
pub uid: i32,
pub bid: Uuid,
pub uid: i32,
}
#[derive(Queryable)]
pub struct UserRelationResp {
pub bid: Uuid,
pub uid: i32,
pub name: String,
pub banned: bool,
pub bid: Uuid,
pub uid: i32,
pub name: String,
pub banned: bool,
}
impl BanId {
pub fn create(conn: &PgConnection) -> Result<Self, Error> {
insert_into(ban_id).default_values().get_result::<Self>(conn)
}
pub fn create(conn: &PgConnection) -> Result<Self, Error> {
insert_into(ban_id)
.default_values()
.get_result::<Self>(conn)
}
pub fn read(conn: &PgConnection, ban_id_val: Uuid) -> Result<Self, Error> {
ban_id.find(ban_id_val).first::<Self>(conn)
}
pub fn read(conn: &PgConnection, ban_id_val: Uuid) -> Result<Self, Error> {
ban_id.find(ban_id_val).first::<Self>(conn)
}
pub fn read_opt(conn: &PgConnection, ban_id_val: Uuid) -> Result<Option<Self>, Error> {
ban_id.find(ban_id_val).first::<Self>(conn).optional()
}
pub fn read_opt(conn: &PgConnection, ban_id_val: Uuid) -> Result<Option<Self>, Error> {
ban_id.find(ban_id_val).first::<Self>(conn).optional()
}
pub fn update_alias(conn: &PgConnection, old_bid_val: Uuid, new_bid_val: Uuid) -> Result<Vec<Self>, Error> {
update(ban_id.filter(ban_id::id.eq(old_bid_val).or(aliased_to.eq(old_bid_val)))).set(aliased_to.eq(new_bid_val)).get_results(conn)
}
pub fn update_alias(
conn: &PgConnection,
old_bid_val: Uuid,
new_bid_val: Uuid,
) -> Result<Vec<Self>, Error> {
update(ban_id.filter(ban_id::id.eq(old_bid_val).or(aliased_to.eq(old_bid_val))))
.set(aliased_to.eq(new_bid_val))
.get_results(conn)
}
}
impl UserBanId {
fn simple_associate(conn: &PgConnection, ban_id_val: Uuid, user_id_val: i32) -> Result<Self, Error> {
insert_into(user_ban_id)
.values(UserBanId { bid: ban_id_val, uid: user_id_val })
.get_result::<Self>(conn)
}
fn simple_associate(
conn: &PgConnection,
ban_id_val: Uuid,
user_id_val: i32,
) -> Result<Self, Error> {
insert_into(user_ban_id)
.values(UserBanId {
bid: ban_id_val,
uid: user_id_val,
})
.get_result::<Self>(conn)
}
fn overwriting_associate(conn: &PgConnection, old_bid_val: Uuid, new_bid_val: Uuid) -> Result<Self, Error> {
BanId::update_alias(conn, old_bid_val, new_bid_val)?;
update(user_ban_id.filter(bid.eq(old_bid_val))).set(bid.eq(new_bid_val)).get_result(conn)
}
fn overwriting_associate(
conn: &PgConnection,
old_bid_val: Uuid,
new_bid_val: Uuid,
) -> Result<Self, Error> {
BanId::update_alias(conn, old_bid_val, new_bid_val)?;
update(user_ban_id.filter(bid.eq(old_bid_val)))
.set(bid.eq(new_bid_val))
.get_result(conn)
}
pub fn associate(conn: &PgConnection, ban_id_val: Uuid, user_id_val: i32) -> Result<Self, Error> {
match Self::get_by_user(conn, &user_id_val) {
//UserBanId found attached to user, which is not the same as the incoming one.
Ok(Some(old_bid)) if old_bid.bid != ban_id_val => {
let incoming_bid = BanId::read(conn, ban_id_val)?;
//the incoming bid isn't aliased to the new one.
if incoming_bid.aliased_to.is_none() || incoming_bid.aliased_to.unwrap() != old_bid.bid {
return Self::overwriting_associate(conn, old_bid.bid, ban_id_val);
}
Ok(old_bid)
},
//UserBanId found, but it's the same as the incoming one.
Ok(Some(k)) => Ok(k),
//There wasn't any UBID attached to the user. Associate and move on.
Ok(None) => {
//Check for an alias
let bid_read = BanId::read_opt(conn, ban_id_val)?;
if let Some(BanId { aliased_to: Some(alias), .. }) = bid_read {
Self::simple_associate(conn, alias, user_id_val)
} else {
Self::simple_associate(conn, ban_id_val, user_id_val)
}
},
//Breaking error, bubble it up.
Err(e) => Err(e),
pub fn associate(conn: &PgConnection, ban_id_val: Uuid, user_id_val: i32) -> Result<Self, Error> {
match Self::get_by_user(conn, &user_id_val) {
//UserBanId found attached to user, which is not the same as the incoming one.
Ok(Some(old_bid)) if old_bid.bid != ban_id_val => {
let incoming_bid = BanId::read(conn, ban_id_val)?;
//the incoming bid isn't aliased to the new one.
if incoming_bid.aliased_to.is_none() || incoming_bid.aliased_to.unwrap() != old_bid.bid {
return Self::overwriting_associate(conn, old_bid.bid, ban_id_val);
}
Ok(old_bid)
}
//UserBanId found, but it's the same as the incoming one.
Ok(Some(k)) => Ok(k),
//There wasn't any UBID attached to the user. Associate and move on.
Ok(None) => {
//Check for an alias
let bid_read = BanId::read_opt(conn, ban_id_val)?;
if let Some(BanId {
aliased_to: Some(alias),
..
}) = bid_read
{
Self::simple_associate(conn, alias, user_id_val)
} else {
Self::simple_associate(conn, ban_id_val, user_id_val)
}
}
//Breaking error, bubble it up.
Err(e) => Err(e),
}
}
pub fn create_then_associate(conn: &PgConnection, user_id_val: i32) -> Result<Self, Error> {
Self::simple_associate(conn, BanId::create(conn)?.id, user_id_val)
}
pub fn create_then_associate(conn: &PgConnection, user_id_val: i32) -> Result<Self, Error> {
Self::simple_associate(conn, BanId::create(conn)?.id, user_id_val)
}
pub fn get_by_user(conn: &PgConnection, user_id_val: &i32) -> Result<Option<Self>, Error> {
user_ban_id.filter(uid.eq(user_id_val)).first::<Self>(conn).optional()
}
pub fn get_by_user(conn: &PgConnection, user_id_val: &i32) -> Result<Option<Self>, Error> {
user_ban_id
.filter(uid.eq(user_id_val))
.first::<Self>(conn)
.optional()
}
pub fn get_users_by_bid(conn: &PgConnection, ban_id_val: Uuid) -> Result<Vec<UserViewSafe>, Error> {
let uids = user_ban_id.filter(bid.eq(ban_id_val)).select(uid).load(conn)?;
UserViewSafe::read_mult(conn, uids)
}
}
pub fn get_users_by_bid(
conn: &PgConnection,
ban_id_val: Uuid,
) -> Result<Vec<UserViewSafe>, Error> {
let uids = user_ban_id
.filter(bid.eq(ban_id_val))
.select(uid)
.load(conn)?;
UserViewSafe::read_mult(conn, uids)
}
}

10
server/lemmy_db/src/user_mention.rs

@ -75,14 +75,8 @@ impl UserMention {
#[cfg(test)]
mod tests {
use crate::{
comment::*,
community::*,
post::*,
tests::establish_unpooled_connection,
user::*,
user_mention::*,
ListingType,
SortType,
comment::*, community::*, post::*, tests::establish_unpooled_connection, user::*,
user_mention::*, ListingType, SortType,
};
#[test]

52
server/lemmy_db/src/user_view.rs

@ -80,8 +80,8 @@ pub struct UserViewSafe {
pub moderator: bool,
pub banned: bool,
pub published: chrono::NaiveDateTime,
pub number_of_posts: i64,
pub number_of_comments: i64,
pub number_of_posts: i64,
pub number_of_comments: i64,
}
pub struct UserQueryBuilder<'a> {
@ -103,8 +103,8 @@ pub struct UserQueryBuilder<'a> {
sql_types::Bool,
sql_types::Bool,
sql_types::Timestamp,
sql_types::BigInt,
sql_types::BigInt,
sql_types::BigInt,
sql_types::BigInt,
),
user_view::table,
Pg,
@ -134,8 +134,8 @@ impl<'a> UserQueryBuilder<'a> {
moderator,
banned,
published,
number_of_posts,
number_of_comments,
number_of_posts,
number_of_comments,
))
.into_boxed();
@ -417,26 +417,26 @@ impl UserViewSafe {
pub fn read_mult(conn: &PgConnection, from_user_ids: Vec<i32>) -> Result<Vec<Self>, Error> {
use super::user_view::user_view::dsl::*;
user_view
.select((
id,
actor_id,
name,
preferred_username,
avatar,
banner,
matrix_user_id,
bio,
local,
admin,
sitemod,
moderator,
banned,
published,
number_of_posts,
number_of_comments,
))
.filter(id.eq(any(from_user_ids)))
.load(conn)
.select((
id,
actor_id,
name,
preferred_username,
avatar,
banner,
matrix_user_id,
bio,
local,
admin,
sitemod,
moderator,
banned,
published,
number_of_posts,
number_of_comments,
))
.filter(id.eq(any(from_user_ids)))
.load(conn)
}
pub fn admins(conn: &PgConnection) -> Result<Vec<Self>, Error> {

14
server/lemmy_utils/src/lib.rs

@ -23,9 +23,7 @@ use lettre::{
extension::ClientId,
ConnectionReuseParameters,
},
ClientSecurity,
SmtpClient,
Transport,
ClientSecurity, SmtpClient, Transport,
};
use lettre_email::Email;
use openssl::{pkey::PKey, rsa::Rsa};
@ -247,14 +245,8 @@ pub fn is_valid_post_title(title: &str) -> bool {
#[cfg(test)]
mod tests {
use crate::{
is_valid_community_name,
is_valid_post_title,
is_valid_preferred_username,
is_valid_username,
remove_slurs,
scrape_text_for_mentions,
slur_check,
slurs_vec_to_str,
is_valid_community_name, is_valid_post_title, is_valid_preferred_username, is_valid_username,
remove_slurs, scrape_text_for_mentions, slur_check, slurs_vec_to_str,
};
#[test]

9
server/migrations/2021-05-13-171343_comms_to_autosubscribe/down.sql

@ -3,10 +3,13 @@ drop view site_view;
alter table site drop column autosubscribe_comms;
create view site_view as
select *,
(select name from user_ u where s.creator_id = u.id) as creator_name,
select s.*,
u.name as creator_name,
u.preferred_username as creator_preferred_username,
u.avatar as creator_avatar,
(select count(*) from user_) as number_of_users,
(select count(*) from post) as number_of_posts,
(select count(*) from comment) as number_of_comments,
(select count(*) from community) as number_of_communities
from site s;
from site s
left join user_ u on s.creator_id = u.id;

9
server/migrations/2021-05-13-171343_comms_to_autosubscribe/up.sql

@ -5,10 +5,13 @@ alter table site add column autosubscribe_comms integer[] default '{}' not null;
drop view site_view;
create view site_view as
select *,
(select name from user_ u where s.creator_id = u.id) as creator_name,
select s.*,
u.name as creator_name,
u.preferred_username as creator_preferred_username,
u.avatar as creator_avatar,
(select count(*) from user_) as number_of_users,
(select count(*) from post) as number_of_posts,
(select count(*) from comment) as number_of_comments,
(select count(*) from community) as number_of_communities
from site s;
from site s
left join user_ u on s.creator_id = u.id;

39
server/src/api/comment.rs

@ -5,51 +5,26 @@ use log::error;
use lemmy_api_structs::{comment::*, APIError};
use lemmy_db::{
comment::*,
comment_view::*,
community_settings::*,
moderator::*,
post::*,
site_view::*,
user::*,
user_mention::*,
Crud,
Likeable,
ListingType,
Saveable,
SortType,
comment::*, comment_view::*, community_settings::*, moderator::*, post::*, site_view::*, user::*,
user_mention::*, Crud, Likeable, ListingType, Saveable, SortType,
};
use lemmy_utils::{
make_apub_endpoint,
num_md_images,
remove_slurs,
scrape_text_for_mentions,
send_email,
settings::Settings,
ConnectionId,
EndpointType,
LemmyError,
MentionData,
make_apub_endpoint, num_md_images, remove_slurs, scrape_text_for_mentions, send_email,
settings::Settings, ConnectionId, EndpointType, LemmyError, MentionData,
};
use crate::{
api::{
check_community_ban,
get_post,
get_user_from_jwt,
get_user_from_jwt_opt,
is_mod_or_admin,
check_community_ban, get_post, get_user_from_jwt, get_user_from_jwt_opt, is_mod_or_admin,
Perform,
},
apub::{ApubLikeableType, ApubObjectType},
blocking,
is_within_comment_char_limit,
blocking, is_within_comment_char_limit,
websocket::{
messages::{JoinCommunityRoom, SendComment},
UserOperation,
},
DbPool,
LemmyContext,
DbPool, LemmyContext,
};
use lemmy_db::{
community_view::{CommunityModeratorView, CommunityView},

39
server/src/api/community.rs

@ -5,44 +5,19 @@ use anyhow::Context;
use lemmy_api_structs::{community::*, APIError};
use lemmy_db::{
comment::Comment,
comment_view::CommentQueryBuilder,
community::*,
community_settings::*,
community_view::*,
diesel_option_overwrite,
moderator::*,
naive_now,
post::Post,
site::*,
user_view::*,
Bannable,
Crud,
Followable,
Joinable,
SortType,
comment::Comment, comment_view::CommentQueryBuilder, community::*, community_settings::*,
community_view::*, diesel_option_overwrite, moderator::*, naive_now, post::Post, site::*,
user_view::*, Bannable, Crud, Followable, Joinable, SortType,
};
use lemmy_utils::{
generate_actor_keypair,
is_valid_community_name,
location_info,
make_apub_endpoint,
naive_from_unix,
ConnectionId,
EndpointType,
LemmyError,
generate_actor_keypair, is_valid_community_name, location_info, make_apub_endpoint,
naive_from_unix, ConnectionId, EndpointType, LemmyError,
};
use crate::{
api::{
check_slurs,
check_slurs_opt,
get_user_from_jwt,
get_user_from_jwt_opt,
is_admin,
is_admin_or_sitemod,
is_mod_or_admin,
Perform,
check_slurs, check_slurs_opt, get_user_from_jwt, get_user_from_jwt_opt, is_admin,
is_admin_or_sitemod, is_mod_or_admin, Perform,
},
apub::ActorType,
blocking,

5
server/src/api/community_settings.rs

@ -3,8 +3,7 @@ use actix_web::web::Data;
use lemmy_api_structs::{community_settings::*, APIError};
use lemmy_db::{
community_settings::{CommunitySettings, CommunitySettingsForm},
naive_now,
Crud,
naive_now, Crud,
};
use lemmy_utils::{ConnectionId, LemmyError};
@ -91,7 +90,7 @@ impl Perform for EditCommunitySettings {
comment_images: updated_community_settings.comment_images,
published: updated_community_settings.published,
allow_as_default: updated_community_settings.allow_as_default,
hide_from_all: updated_community_settings.hide_from_all,
hide_from_all: updated_community_settings.hide_from_all,
};
context.chat_server().do_send(SendCommunityRoomMessage {

20
server/src/api/mod.rs

@ -1,13 +1,16 @@
use actix_web::web::Data;
use lemmy_api_structs::APIError;
use lemmy_db::{Crud, community::Community, community_view::CommunityUserBanView, naive_now, post::Post, user::User_};
use lemmy_db::{
community::Community, community_view::CommunityUserBanView, naive_now, post::Post, user::User_,
Crud,
};
use lemmy_utils::{settings::Settings, slur_check, slurs_vec_to_str, ConnectionId, LemmyError};
use crate::{api::claims::Claims, blocking, DbPool, LemmyContext};
use chrono::Duration;
use lemmy_db::user_token::UserToken;
use lemmy_db::user_ban_id::UserBanId;
use lemmy_db::user_token::UserToken;
pub mod claims;
pub mod comment;
@ -86,7 +89,9 @@ pub(in crate::api) async fn get_user_from_jwt(
if !bid_string.is_empty() {
//bid reported, try creating relationship
let bid = bid_string.parse().map_err(|_| APIError::err("invalid_bid"))?;
let bid = bid_string
.parse()
.map_err(|_| APIError::err("invalid_bid"))?;
blocking(pool, move |conn| UserBanId::associate(conn, bid, user_id)).await??;
} else {
//bid not reported, find existing
@ -102,9 +107,14 @@ pub(in crate::api) async fn get_user_from_jwt(
if user.banned {
//generate new bid
if bid_string.is_empty() {
bid_string = blocking(pool, move |conn| UserBanId::create_then_associate(conn, user_id.clone())).await??.bid.to_string();
bid_string = blocking(pool, move |conn| {
UserBanId::create_then_associate(conn, user_id.clone())
})
.await??
.bid
.to_string();
}
return Err(APIError::err(&*format!("site_ban_{}", bid_string)).into());
}
Ok(user)

35
server/src/api/post.rs

@ -5,44 +5,21 @@ use url::Url;
use lemmy_api_structs::{post::*, APIError};
use lemmy_db::{
comment_view::*,
community_settings::*,
community_view::*,
moderator::*,
naive_now,
post::*,
post_view::*,
site::*,
site_view::*,
user_view::*,
Crud,
Likeable,
ListingType,
Saveable,
comment_view::*, community_settings::*, community_view::*, moderator::*, naive_now, post::*,
post_view::*, site::*, site_view::*, user_view::*, Crud, Likeable, ListingType, Saveable,
SortType,
};
use lemmy_utils::{
is_valid_post_title,
make_apub_endpoint,
ConnectionId,
EndpointType,
LemmyError,
is_valid_post_title, make_apub_endpoint, ConnectionId, EndpointType, LemmyError,
};
use crate::{
api::{
check_community_ban,
check_slurs,
check_slurs_opt,
get_user_from_jwt,
get_user_from_jwt_opt,
is_mod_or_admin,
Perform,
check_community_ban, check_slurs, check_slurs_opt, get_user_from_jwt, get_user_from_jwt_opt,
is_mod_or_admin, Perform,
},
apub::{ApubLikeableType, ApubObjectType},
blocking,
fetch_iframely_and_pictrs_data,
is_within_post_body_char_limit,
blocking, fetch_iframely_and_pictrs_data, is_within_post_body_char_limit,
is_within_post_title_char_limit,
websocket::{
messages::{GetPostUsersOnline, JoinCommunityRoom, JoinPostRoom, SendPost},

8
server/src/api/report.rs

@ -8,10 +8,7 @@ use lemmy_db::{
post::*,
post_view::*,
report_views::{
CommentReportQueryBuilder,
CommentReportView,
PostReportQueryBuilder,
PostReportView,
CommentReportQueryBuilder, CommentReportView, PostReportQueryBuilder, PostReportView,
},
user_view::UserViewSafe,
Reportable,
@ -20,8 +17,7 @@ use lemmy_utils::{ConnectionId, LemmyError};
use crate::{
api::{check_community_ban, get_user_from_jwt, Perform},
blocking,
LemmyContext,
blocking, LemmyContext,
};
const MAX_REPORT_LEN: usize = 1000;

132
server/src/api/user.rs

@ -9,79 +9,37 @@ use log::{error, info};
use lemmy_api_structs::{user::*, APIError};
use lemmy_db::{
comment::*,
comment_view::*,
community::*,
community_settings::*,
community_view::*,
diesel_option_overwrite,
moderator::*,
naive_now,
password_reset_request::*,
post::*,
post_view::*,
private_message::*,
private_message_view::*,
site::*,
site_view::*,
user::*,
user_mention::*,
user_mention_view::*,
user_tag::*,
user_view::*,
Crud,
Followable,
Joinable,
ListingType,
SortType,
comment::*, comment_view::*, community::*, community_settings::*, community_view::*,
diesel_option_overwrite, moderator::*, naive_now, password_reset_request::*, post::*,
post_view::*, private_message::*, private_message_view::*, site::*, site_view::*, user::*,
user_mention::*, user_mention_view::*, user_tag::*, user_view::*, Crud, Followable, Joinable,
ListingType, SortType,
};
use lemmy_utils::{
generate_actor_keypair,
generate_random_string,
is_valid_preferred_username,
is_valid_username,
location_info,
make_apub_endpoint,
naive_from_unix,
remove_slurs,
send_email,
settings::Settings,
ConnectionId,
EndpointType,
LemmyError,
generate_actor_keypair, generate_random_string, is_valid_preferred_username, is_valid_username,
location_info, make_apub_endpoint, naive_from_unix, remove_slurs, send_email, settings::Settings,
ConnectionId, EndpointType, LemmyError,
};
use crate::{
api::{
check_slurs,
claims::Claims,
get_user_from_jwt,
get_user_from_jwt_opt,
is_admin,
is_admin_or_sitemod,
validate_token,
Perform,
check_slurs, claims::Claims, get_user_from_jwt, get_user_from_jwt_opt, is_admin,
is_admin_or_sitemod, validate_token, Perform,
},
apub::ApubObjectType,
blocking,
captcha_espeak_wav_base64,
blocking, captcha_espeak_wav_base64,
hcaptcha::hcaptcha_verify,
is_within_message_char_limit,
websocket::{
messages::{
CaptchaItem,
CheckCaptcha,
JoinUserRoom,
LeaveAllRooms,
SendAllMessage,
SendUserRoomMessage,
CaptchaItem, CheckCaptcha, JoinUserRoom, LeaveAllRooms, SendAllMessage, SendUserRoomMessage,
},
UserOperation,
},
LemmyContext,
};
use lemmy_db::user_token::{UserToken, UserTokenForm};
use lemmy_db::user_ban_id::UserBanId;
use lemmy_db::user_token::{UserToken, UserTokenForm};
#[async_trait::async_trait(?Send)]
impl Perform for SetUserTag {
@ -221,7 +179,11 @@ impl Perform for Login {
//get bid (if any)
let uid = user.id;
let bid = blocking(&context.pool, move |conn| UserBanId::get_by_user(conn, &uid)).await??.map_or("".to_string(), |ubid| ubid.bid.to_string());
let bid = blocking(&context.pool, move |conn| {
UserBanId::get_by_user(conn, &uid)
})
.await??
.map_or("".to_string(), |ubid| ubid.bid.to_string());
// Return the jwt
let jwt = generate_token(context, user.id).await?;
@ -433,7 +395,7 @@ impl Perform for Register {
};
// Sign them up for main community no matter what
let community_follower_form = CommunityFollowerForm {
/*let community_follower_form = CommunityFollowerForm {
community_id: main_community.id,
user_id: inserted_user.id,
};
@ -441,18 +403,25 @@ impl Perform 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());
};
};*/
// subscribe the user to all communities that have allow_as_default enabled
let default_communities = blocking(context.pool(), move |conn| {
//get comms that are both admin-selected and enabled allow_as_default, then subscribe users to all of them
let default_communities = blocking(context.pool(), move |conn| SiteView::read(conn))
.await??
.autosubscribe_comms;
let optin_communities = blocking(context.pool(), move |conn| {
CommunitySettings::list_allowed_as_default(conn)
})
.await??;
// Sign up new users for a set of default communities
for comm in default_communities.into_iter() {
for comm in default_communities.into_iter().filter(|comm| {
optin_communities
.iter()
.any(|opt_comm| &opt_comm.id == comm)
}) {
let community_follower_form = CommunityFollowerForm {
community_id: comm.id,
community_id: comm,
user_id: inserted_user.id,
};
@ -1748,18 +1717,27 @@ impl Perform for RemoveUserContent {
if data.scrub_name {
let scrubbed_unames: Vec<String> = blocking(context.pool(), move |conn| {
User_::find_by_username_mult(conn, "UsernameScrubbed_%")
}).await??.into_iter().map(|user| user.name).collect();
})
.await??
.into_iter()
.map(|user| user.name)
.collect();
let mut i = 1;
while scrubbed_unames.contains(&format!("UsernameScrubbed{}", i)){
while scrubbed_unames.contains(&format!("UsernameScrubbed{}", i)) {
i += 1;
}
let scrubbed_name = format!("UsernameScrubbed{}", i);
blocking(context.pool(), move |conn| {
User_::update_username(conn, target.id, scrubbed_name.clone(),
make_apub_endpoint(EndpointType::User, &*scrubbed_name).to_string())
}).await??;
User_::update_username(
conn,
target.id,
scrubbed_name.clone(),
make_apub_endpoint(EndpointType::User, &*scrubbed_name).to_string(),
)
})
.await??;
}
// ban the user first, so when we query the db we won't miss anything
@ -1856,7 +1834,11 @@ impl Perform for RemoveUserContent {
impl Perform for GetRelatedUsers {
type Response = GetRelatedUsersResponse;
async fn perform(&self, context: &Data<LemmyContext>, _websocket_id: Option<usize>) -> Result<Self::Response, LemmyError> {
async fn perform(
&self,
context: &Data<LemmyContext>,
_websocket_id: Option<usize>,
) -> Result<Self::Response, LemmyError> {
let data: &GetRelatedUsers = &self;
// Permissions checks