Merge pull request 'Add pending status for federated follows' (#130) from pending-follow into main
Reviewed-on: https://yerbamate.ml/LemmyNet/lemmy/pulls/130
This commit is contained in:
commit
15c77f85c1
25 changed files with 109 additions and 57 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -1852,8 +1852,10 @@ dependencies = [
|
||||||
name = "lemmy_server"
|
name = "lemmy_server"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"activitystreams",
|
||||||
"actix",
|
"actix",
|
||||||
"actix-files",
|
"actix-files",
|
||||||
|
"actix-rt",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"actix-web-actors",
|
"actix-web-actors",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
@ -1877,6 +1879,7 @@ dependencies = [
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rss",
|
"rss",
|
||||||
"serde 1.0.117",
|
"serde 1.0.117",
|
||||||
|
"serde_json",
|
||||||
"sha2",
|
"sha2",
|
||||||
"strum",
|
"strum",
|
||||||
"tokio 0.3.1",
|
"tokio 0.3.1",
|
||||||
|
|
|
@ -46,6 +46,9 @@ tokio = "0.3"
|
||||||
sha2 = "0.9"
|
sha2 = "0.9"
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
reqwest = { version = "0.10", features = ["json"] }
|
reqwest = { version = "0.10", features = ["json"] }
|
||||||
|
activitystreams = "0.7.0-alpha.4"
|
||||||
|
actix-rt = { version = "1.1", default-features = false }
|
||||||
|
serde_json = { version = "1.0", features = ["preserve_order"]}
|
||||||
|
|
||||||
[dev-dependencies.cargo-husky]
|
[dev-dependencies.cargo-husky]
|
||||||
version = "1"
|
version = "1"
|
||||||
|
|
|
@ -188,6 +188,7 @@ impl Perform for CreateCommunity {
|
||||||
let community_follower_form = CommunityFollowerForm {
|
let community_follower_form = CommunityFollowerForm {
|
||||||
community_id: inserted_community.id,
|
community_id: inserted_community.id,
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
|
pending: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
|
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
|
||||||
|
@ -479,6 +480,7 @@ impl Perform for FollowCommunity {
|
||||||
let community_follower_form = CommunityFollowerForm {
|
let community_follower_form = CommunityFollowerForm {
|
||||||
community_id: data.community_id,
|
community_id: data.community_id,
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
|
pending: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
if community.local {
|
if community.local {
|
||||||
|
|
|
@ -251,6 +251,7 @@ impl Perform for Register {
|
||||||
let community_follower_form = CommunityFollowerForm {
|
let community_follower_form = CommunityFollowerForm {
|
||||||
community_id: main_community.id,
|
community_id: main_community.id,
|
||||||
user_id: inserted_user.id,
|
user_id: inserted_user.id,
|
||||||
|
pending: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
|
let follow = move |conn: &'_ _| CommunityFollower::follow(conn, &community_follower_form);
|
||||||
|
|
|
@ -12,7 +12,12 @@ use activitystreams::{
|
||||||
base::{AnyBase, BaseExt, ExtendsExt},
|
base::{AnyBase, BaseExt, ExtendsExt},
|
||||||
object::ObjectExt,
|
object::ObjectExt,
|
||||||
};
|
};
|
||||||
use lemmy_db::{community::Community, user::User_, DbPool};
|
use lemmy_db::{
|
||||||
|
community::{Community, CommunityFollower, CommunityFollowerForm},
|
||||||
|
user::User_,
|
||||||
|
DbPool,
|
||||||
|
Followable,
|
||||||
|
};
|
||||||
use lemmy_structs::blocking;
|
use lemmy_structs::blocking;
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
|
@ -44,6 +49,16 @@ impl ActorType for User_ {
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
|
let community_follower_form = CommunityFollowerForm {
|
||||||
|
community_id: community.id,
|
||||||
|
user_id: self.id,
|
||||||
|
pending: true,
|
||||||
|
};
|
||||||
|
blocking(&context.pool(), move |conn| {
|
||||||
|
CommunityFollower::follow(conn, &community_follower_form).ok()
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
let mut follow = Follow::new(self.actor_id.to_owned(), community.actor_id()?);
|
let mut follow = Follow::new(self.actor_id.to_owned(), community.actor_id()?);
|
||||||
follow
|
follow
|
||||||
.set_context(activitystreams::context())
|
.set_context(activitystreams::context())
|
||||||
|
|
|
@ -54,7 +54,8 @@ pub async fn get_activity(
|
||||||
})
|
})
|
||||||
.await??;
|
.await??;
|
||||||
|
|
||||||
if !activity.local || activity.sensitive {
|
let sensitive = activity.sensitive.unwrap_or(true);
|
||||||
|
if !activity.local || sensitive {
|
||||||
Ok(HttpResponse::NotFound().finish())
|
Ok(HttpResponse::NotFound().finish())
|
||||||
} else {
|
} else {
|
||||||
Ok(create_apub_response(&activity.data))
|
Ok(create_apub_response(&activity.data))
|
||||||
|
|
|
@ -191,6 +191,7 @@ async fn handle_follow(
|
||||||
let community_follower_form = CommunityFollowerForm {
|
let community_follower_form = CommunityFollowerForm {
|
||||||
community_id: community.id,
|
community_id: community.id,
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
|
pending: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
// This will fail if they're already a follower, but ignore the error.
|
// This will fail if they're already a follower, but ignore the error.
|
||||||
|
@ -245,6 +246,7 @@ async fn handle_undo_follow(
|
||||||
let community_follower_form = CommunityFollowerForm {
|
let community_follower_form = CommunityFollowerForm {
|
||||||
community_id: community.id,
|
community_id: community.id,
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
|
pending: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
// This will fail if they aren't a follower, but ignore the error.
|
// This will fail if they aren't a follower, but ignore the error.
|
||||||
|
|
|
@ -46,7 +46,7 @@ use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use diesel::NotFound;
|
use diesel::NotFound;
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
community::{Community, CommunityFollower, CommunityFollowerForm},
|
community::{Community, CommunityFollower},
|
||||||
private_message::PrivateMessage,
|
private_message::PrivateMessage,
|
||||||
user::User_,
|
user::User_,
|
||||||
Followable,
|
Followable,
|
||||||
|
@ -173,8 +173,6 @@ async fn receive_accept(
|
||||||
let accept = Accept::from_any_base(activity)?.context(location_info!())?;
|
let accept = Accept::from_any_base(activity)?.context(location_info!())?;
|
||||||
verify_activity_domains_valid(&accept, &actor.actor_id()?, false)?;
|
verify_activity_domains_valid(&accept, &actor.actor_id()?, false)?;
|
||||||
|
|
||||||
// TODO: we should check that we actually sent this activity, because the remote instance
|
|
||||||
// could just put a fake Follow
|
|
||||||
let object = accept.object().to_owned().one().context(location_info!())?;
|
let object = accept.object().to_owned().one().context(location_info!())?;
|
||||||
let follow = Follow::from_any_base(object)?.context(location_info!())?;
|
let follow = Follow::from_any_base(object)?.context(location_info!())?;
|
||||||
verify_activity_domains_valid(&follow, &user.actor_id()?, false)?;
|
verify_activity_domains_valid(&follow, &user.actor_id()?, false)?;
|
||||||
|
@ -188,17 +186,13 @@ async fn receive_accept(
|
||||||
let community =
|
let community =
|
||||||
get_or_fetch_and_upsert_community(&community_uri, context, request_counter).await?;
|
get_or_fetch_and_upsert_community(&community_uri, context, request_counter).await?;
|
||||||
|
|
||||||
// Now you need to add this to the community follower
|
let community_id = community.id;
|
||||||
let community_follower_form = CommunityFollowerForm {
|
let user_id = user.id;
|
||||||
community_id: community.id,
|
// This will throw an error if no follow was requested
|
||||||
user_id: user.id,
|
|
||||||
};
|
|
||||||
|
|
||||||
// This will fail if they're already a follower
|
|
||||||
blocking(&context.pool(), move |conn| {
|
blocking(&context.pool(), move |conn| {
|
||||||
CommunityFollower::follow(conn, &community_follower_form).ok()
|
CommunityFollower::follow_accepted(conn, community_id, user_id)
|
||||||
})
|
})
|
||||||
.await?;
|
.await??;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,22 +12,22 @@ use std::{
|
||||||
#[table_name = "activity"]
|
#[table_name = "activity"]
|
||||||
pub struct Activity {
|
pub struct Activity {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub ap_id: String,
|
|
||||||
pub data: Value,
|
pub data: Value,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
pub sensitive: bool,
|
|
||||||
pub published: chrono::NaiveDateTime,
|
pub published: chrono::NaiveDateTime,
|
||||||
pub updated: Option<chrono::NaiveDateTime>,
|
pub updated: Option<chrono::NaiveDateTime>,
|
||||||
|
pub ap_id: Option<String>,
|
||||||
|
pub sensitive: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Insertable, AsChangeset)]
|
#[derive(Insertable, AsChangeset)]
|
||||||
#[table_name = "activity"]
|
#[table_name = "activity"]
|
||||||
pub struct ActivityForm {
|
pub struct ActivityForm {
|
||||||
pub ap_id: String,
|
|
||||||
pub data: Value,
|
pub data: Value,
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
pub sensitive: bool,
|
|
||||||
pub updated: Option<chrono::NaiveDateTime>,
|
pub updated: Option<chrono::NaiveDateTime>,
|
||||||
|
pub ap_id: String,
|
||||||
|
pub sensitive: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Crud<ActivityForm> for Activity {
|
impl Crud<ActivityForm> for Activity {
|
||||||
|
@ -53,6 +53,10 @@ impl Crud<ActivityForm> for Activity {
|
||||||
.set(new_activity)
|
.set(new_activity)
|
||||||
.get_result::<Self>(conn)
|
.get_result::<Self>(conn)
|
||||||
}
|
}
|
||||||
|
fn delete(conn: &PgConnection, activity_id: i32) -> Result<usize, Error> {
|
||||||
|
use crate::schema::activity::dsl::*;
|
||||||
|
diesel::delete(activity.find(activity_id)).execute(conn)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Activity {
|
impl Activity {
|
||||||
|
@ -115,7 +119,7 @@ mod tests {
|
||||||
avatar: None,
|
avatar: None,
|
||||||
banner: None,
|
banner: None,
|
||||||
admin: false,
|
admin: false,
|
||||||
banned: false,
|
banned: Some(false),
|
||||||
published: None,
|
published: None,
|
||||||
updated: None,
|
updated: None,
|
||||||
show_nsfw: false,
|
show_nsfw: false,
|
||||||
|
@ -162,11 +166,11 @@ mod tests {
|
||||||
let inserted_activity = Activity::create(&conn, &activity_form).unwrap();
|
let inserted_activity = Activity::create(&conn, &activity_form).unwrap();
|
||||||
|
|
||||||
let expected_activity = Activity {
|
let expected_activity = Activity {
|
||||||
ap_id: ap_id.to_string(),
|
ap_id: Some(ap_id.to_string()),
|
||||||
id: inserted_activity.id,
|
id: inserted_activity.id,
|
||||||
data: test_json,
|
data: test_json,
|
||||||
local: true,
|
local: true,
|
||||||
sensitive: false,
|
sensitive: Some(false),
|
||||||
published: inserted_activity.published,
|
published: inserted_activity.published,
|
||||||
updated: None,
|
updated: None,
|
||||||
};
|
};
|
||||||
|
@ -174,6 +178,7 @@ mod tests {
|
||||||
let read_activity = Activity::read(&conn, inserted_activity.id).unwrap();
|
let read_activity = Activity::read(&conn, inserted_activity.id).unwrap();
|
||||||
let read_activity_by_apub_id = Activity::read_from_apub_id(&conn, ap_id).unwrap();
|
let read_activity_by_apub_id = Activity::read_from_apub_id(&conn, ap_id).unwrap();
|
||||||
User_::delete(&conn, inserted_creator.id).unwrap();
|
User_::delete(&conn, inserted_creator.id).unwrap();
|
||||||
|
Activity::delete(&conn, inserted_activity.id).unwrap();
|
||||||
|
|
||||||
assert_eq!(expected_activity, read_activity);
|
assert_eq!(expected_activity, read_activity);
|
||||||
assert_eq!(expected_activity, read_activity_by_apub_id);
|
assert_eq!(expected_activity, read_activity_by_apub_id);
|
||||||
|
|
|
@ -280,7 +280,7 @@ mod tests {
|
||||||
avatar: None,
|
avatar: None,
|
||||||
banner: None,
|
banner: None,
|
||||||
admin: false,
|
admin: false,
|
||||||
banned: false,
|
banned: Some(false),
|
||||||
published: None,
|
published: None,
|
||||||
updated: None,
|
updated: None,
|
||||||
show_nsfw: false,
|
show_nsfw: false,
|
||||||
|
|
|
@ -519,7 +519,7 @@ mod tests {
|
||||||
avatar: None,
|
avatar: None,
|
||||||
banner: None,
|
banner: None,
|
||||||
admin: false,
|
admin: false,
|
||||||
banned: false,
|
banned: Some(false),
|
||||||
published: None,
|
published: None,
|
||||||
updated: None,
|
updated: None,
|
||||||
show_nsfw: false,
|
show_nsfw: false,
|
||||||
|
|
|
@ -276,6 +276,7 @@ pub struct CommunityFollower {
|
||||||
pub community_id: i32,
|
pub community_id: i32,
|
||||||
pub user_id: i32,
|
pub user_id: i32,
|
||||||
pub published: chrono::NaiveDateTime,
|
pub published: chrono::NaiveDateTime,
|
||||||
|
pub pending: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Insertable, AsChangeset, Clone)]
|
#[derive(Insertable, AsChangeset, Clone)]
|
||||||
|
@ -283,6 +284,7 @@ pub struct CommunityFollower {
|
||||||
pub struct CommunityFollowerForm {
|
pub struct CommunityFollowerForm {
|
||||||
pub community_id: i32,
|
pub community_id: i32,
|
||||||
pub user_id: i32,
|
pub user_id: i32,
|
||||||
|
pub pending: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Followable<CommunityFollowerForm> for CommunityFollower {
|
impl Followable<CommunityFollowerForm> for CommunityFollower {
|
||||||
|
@ -295,6 +297,19 @@ impl Followable<CommunityFollowerForm> for CommunityFollower {
|
||||||
.values(community_follower_form)
|
.values(community_follower_form)
|
||||||
.get_result::<Self>(conn)
|
.get_result::<Self>(conn)
|
||||||
}
|
}
|
||||||
|
fn follow_accepted(conn: &PgConnection, community_id_: i32, user_id_: i32) -> Result<Self, Error>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
use crate::schema::community_follower::dsl::*;
|
||||||
|
diesel::update(
|
||||||
|
community_follower
|
||||||
|
.filter(community_id.eq(community_id_))
|
||||||
|
.filter(user_id.eq(user_id_)),
|
||||||
|
)
|
||||||
|
.set(pending.eq(true))
|
||||||
|
.get_result::<Self>(conn)
|
||||||
|
}
|
||||||
fn unfollow(
|
fn unfollow(
|
||||||
conn: &PgConnection,
|
conn: &PgConnection,
|
||||||
community_follower_form: &CommunityFollowerForm,
|
community_follower_form: &CommunityFollowerForm,
|
||||||
|
@ -326,7 +341,7 @@ mod tests {
|
||||||
avatar: None,
|
avatar: None,
|
||||||
banner: None,
|
banner: None,
|
||||||
admin: false,
|
admin: false,
|
||||||
banned: false,
|
banned: Some(false),
|
||||||
published: None,
|
published: None,
|
||||||
updated: None,
|
updated: None,
|
||||||
show_nsfw: false,
|
show_nsfw: false,
|
||||||
|
@ -392,6 +407,7 @@ mod tests {
|
||||||
let community_follower_form = CommunityFollowerForm {
|
let community_follower_form = CommunityFollowerForm {
|
||||||
community_id: inserted_community.id,
|
community_id: inserted_community.id,
|
||||||
user_id: inserted_user.id,
|
user_id: inserted_user.id,
|
||||||
|
pending: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let inserted_community_follower =
|
let inserted_community_follower =
|
||||||
|
@ -401,6 +417,7 @@ mod tests {
|
||||||
id: inserted_community_follower.id,
|
id: inserted_community_follower.id,
|
||||||
community_id: inserted_community.id,
|
community_id: inserted_community.id,
|
||||||
user_id: inserted_user.id,
|
user_id: inserted_user.id,
|
||||||
|
pending: Some(false),
|
||||||
published: inserted_community_follower.published,
|
published: inserted_community_follower.published,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,9 @@ pub trait Crud<T> {
|
||||||
|
|
||||||
pub trait Followable<T> {
|
pub trait Followable<T> {
|
||||||
fn follow(conn: &PgConnection, form: &T) -> Result<Self, Error>
|
fn follow(conn: &PgConnection, form: &T) -> Result<Self, Error>
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
fn follow_accepted(conn: &PgConnection, community_id: i32, user_id: i32) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
fn unfollow(conn: &PgConnection, form: &T) -> Result<usize, Error>
|
fn unfollow(conn: &PgConnection, form: &T) -> Result<usize, Error>
|
||||||
|
|
|
@ -416,7 +416,7 @@ mod tests {
|
||||||
avatar: None,
|
avatar: None,
|
||||||
banner: None,
|
banner: None,
|
||||||
admin: false,
|
admin: false,
|
||||||
banned: false,
|
banned: Some(false),
|
||||||
published: None,
|
published: None,
|
||||||
updated: None,
|
updated: None,
|
||||||
show_nsfw: false,
|
show_nsfw: false,
|
||||||
|
@ -445,7 +445,7 @@ mod tests {
|
||||||
avatar: None,
|
avatar: None,
|
||||||
banner: None,
|
banner: None,
|
||||||
admin: false,
|
admin: false,
|
||||||
banned: false,
|
banned: Some(false),
|
||||||
published: None,
|
published: None,
|
||||||
updated: None,
|
updated: None,
|
||||||
show_nsfw: false,
|
show_nsfw: false,
|
||||||
|
|
|
@ -100,7 +100,7 @@ mod tests {
|
||||||
avatar: None,
|
avatar: None,
|
||||||
banner: None,
|
banner: None,
|
||||||
admin: false,
|
admin: false,
|
||||||
banned: false,
|
banned: Some(false),
|
||||||
published: None,
|
published: None,
|
||||||
updated: None,
|
updated: None,
|
||||||
show_nsfw: false,
|
show_nsfw: false,
|
||||||
|
|
|
@ -349,7 +349,7 @@ mod tests {
|
||||||
avatar: None,
|
avatar: None,
|
||||||
banner: None,
|
banner: None,
|
||||||
admin: false,
|
admin: false,
|
||||||
banned: false,
|
banned: Some(false),
|
||||||
published: None,
|
published: None,
|
||||||
updated: None,
|
updated: None,
|
||||||
show_nsfw: false,
|
show_nsfw: false,
|
||||||
|
|
|
@ -416,7 +416,7 @@ mod tests {
|
||||||
published: None,
|
published: None,
|
||||||
updated: None,
|
updated: None,
|
||||||
admin: false,
|
admin: false,
|
||||||
banned: false,
|
banned: Some(false),
|
||||||
show_nsfw: false,
|
show_nsfw: false,
|
||||||
theme: "browser".into(),
|
theme: "browser".into(),
|
||||||
default_sort_type: SortType::Hot as i16,
|
default_sort_type: SortType::Hot as i16,
|
||||||
|
|
|
@ -157,7 +157,7 @@ mod tests {
|
||||||
avatar: None,
|
avatar: None,
|
||||||
banner: None,
|
banner: None,
|
||||||
admin: false,
|
admin: false,
|
||||||
banned: false,
|
banned: Some(false),
|
||||||
published: None,
|
published: None,
|
||||||
updated: None,
|
updated: None,
|
||||||
show_nsfw: false,
|
show_nsfw: false,
|
||||||
|
@ -186,7 +186,7 @@ mod tests {
|
||||||
avatar: None,
|
avatar: None,
|
||||||
banner: None,
|
banner: None,
|
||||||
admin: false,
|
admin: false,
|
||||||
banned: false,
|
banned: Some(false),
|
||||||
published: None,
|
published: None,
|
||||||
updated: None,
|
updated: None,
|
||||||
show_nsfw: false,
|
show_nsfw: false,
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
table! {
|
table! {
|
||||||
activity (id) {
|
activity (id) {
|
||||||
id -> Int4,
|
id -> Int4,
|
||||||
ap_id -> Text,
|
|
||||||
data -> Jsonb,
|
data -> Jsonb,
|
||||||
local -> Bool,
|
local -> Bool,
|
||||||
sensitive -> Bool,
|
|
||||||
published -> Timestamp,
|
published -> Timestamp,
|
||||||
updated -> Nullable<Timestamp>,
|
updated -> Nullable<Timestamp>,
|
||||||
|
ap_id -> Nullable<Text>,
|
||||||
|
sensitive -> Nullable<Bool>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,6 +150,7 @@ table! {
|
||||||
community_id -> Int4,
|
community_id -> Int4,
|
||||||
user_id -> Int4,
|
user_id -> Int4,
|
||||||
published -> Timestamp,
|
published -> Timestamp,
|
||||||
|
pending -> Nullable<Bool>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -196,7 +196,7 @@ mod tests {
|
||||||
avatar: None,
|
avatar: None,
|
||||||
banner: None,
|
banner: None,
|
||||||
admin: false,
|
admin: false,
|
||||||
banned: false,
|
banned: Some(false),
|
||||||
published: None,
|
published: None,
|
||||||
updated: None,
|
updated: None,
|
||||||
show_nsfw: false,
|
show_nsfw: false,
|
||||||
|
|
|
@ -96,7 +96,7 @@ mod tests {
|
||||||
avatar: None,
|
avatar: None,
|
||||||
banner: None,
|
banner: None,
|
||||||
admin: false,
|
admin: false,
|
||||||
banned: false,
|
banned: Some(false),
|
||||||
published: None,
|
published: None,
|
||||||
updated: None,
|
updated: None,
|
||||||
show_nsfw: false,
|
show_nsfw: false,
|
||||||
|
@ -125,7 +125,7 @@ mod tests {
|
||||||
avatar: None,
|
avatar: None,
|
||||||
banner: None,
|
banner: None,
|
||||||
admin: false,
|
admin: false,
|
||||||
banned: false,
|
banned: Some(false),
|
||||||
published: None,
|
published: None,
|
||||||
updated: None,
|
updated: None,
|
||||||
show_nsfw: false,
|
show_nsfw: false,
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE community_follower DROP COLUMN pending;
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE community_follower ADD COLUMN pending BOOLEAN DEFAULT FALSE;
|
5
test.sh
5
test.sh
|
@ -2,4 +2,7 @@
|
||||||
export DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy
|
export DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy
|
||||||
diesel migration run
|
diesel migration run
|
||||||
export LEMMY_DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy
|
export LEMMY_DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy
|
||||||
RUST_TEST_THREADS=1 cargo test --workspace --no-fail-fast
|
# Integration tests only work on stable due to a bug in config-rs
|
||||||
|
# https://github.com/mehcode/config-rs/issues/158
|
||||||
|
RUST_BACKTRACE=1 RUST_TEST_THREADS=1 \
|
||||||
|
cargo +stable test --workspace --no-fail-fast
|
||||||
|
|
|
@ -16,6 +16,18 @@ use diesel::{
|
||||||
PgConnection,
|
PgConnection,
|
||||||
};
|
};
|
||||||
use http_signature_normalization_actix::PrepareVerifyError;
|
use http_signature_normalization_actix::PrepareVerifyError;
|
||||||
|
use lemmy_api::match_websocket_operation;
|
||||||
|
use lemmy_apub::{
|
||||||
|
activity_queue::create_activity_queue,
|
||||||
|
inbox::{
|
||||||
|
community_inbox,
|
||||||
|
community_inbox::community_inbox,
|
||||||
|
shared_inbox,
|
||||||
|
shared_inbox::shared_inbox,
|
||||||
|
user_inbox,
|
||||||
|
user_inbox::user_inbox,
|
||||||
|
},
|
||||||
|
};
|
||||||
use lemmy_db::{
|
use lemmy_db::{
|
||||||
community::{Community, CommunityForm},
|
community::{Community, CommunityForm},
|
||||||
user::{User_, *},
|
user::{User_, *},
|
||||||
|
@ -24,22 +36,8 @@ use lemmy_db::{
|
||||||
SortType,
|
SortType,
|
||||||
};
|
};
|
||||||
use lemmy_rate_limit::{rate_limiter::RateLimiter, RateLimit};
|
use lemmy_rate_limit::{rate_limiter::RateLimiter, RateLimit};
|
||||||
use lemmy_server::{
|
|
||||||
apub::{
|
|
||||||
activity_queue::create_activity_queue,
|
|
||||||
inbox::{
|
|
||||||
community_inbox,
|
|
||||||
community_inbox::community_inbox,
|
|
||||||
shared_inbox,
|
|
||||||
shared_inbox::shared_inbox,
|
|
||||||
user_inbox,
|
|
||||||
user_inbox::user_inbox,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
websocket::chat_server::ChatServer,
|
|
||||||
LemmyContext,
|
|
||||||
};
|
|
||||||
use lemmy_utils::{apub::generate_actor_keypair, settings::Settings};
|
use lemmy_utils::{apub::generate_actor_keypair, settings::Settings};
|
||||||
|
use lemmy_websocket::{chat_server::ChatServer, LemmyContext};
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -61,11 +59,12 @@ fn create_context() -> LemmyContext {
|
||||||
let chat_server = ChatServer::startup(
|
let chat_server = ChatServer::startup(
|
||||||
pool.clone(),
|
pool.clone(),
|
||||||
rate_limiter.clone(),
|
rate_limiter.clone(),
|
||||||
|
|c, i, o, d| Box::pin(match_websocket_operation(c, i, o, d)),
|
||||||
Client::default(),
|
Client::default(),
|
||||||
activity_queue.clone(),
|
activity_queue.clone(),
|
||||||
)
|
)
|
||||||
.start();
|
.start();
|
||||||
LemmyContext::new(
|
LemmyContext::create(
|
||||||
pool,
|
pool,
|
||||||
chat_server,
|
chat_server,
|
||||||
Client::default(),
|
Client::default(),
|
||||||
|
@ -84,7 +83,7 @@ fn create_user(conn: &PgConnection, name: &str) -> User_ {
|
||||||
avatar: None,
|
avatar: None,
|
||||||
banner: None,
|
banner: None,
|
||||||
admin: false,
|
admin: false,
|
||||||
banned: false,
|
banned: Some(false),
|
||||||
updated: None,
|
updated: None,
|
||||||
published: None,
|
published: None,
|
||||||
show_nsfw: false,
|
show_nsfw: false,
|
||||||
|
@ -177,7 +176,7 @@ async fn test_user_inbox_expired_signature() {
|
||||||
let connection = &context.pool().get().unwrap();
|
let connection = &context.pool().get().unwrap();
|
||||||
let user = create_user(connection, "user_inbox_cgsax");
|
let user = create_user(connection, "user_inbox_cgsax");
|
||||||
let activity =
|
let activity =
|
||||||
create_activity::<CreateType, ActorAndObject<user_inbox::ValidTypes>>(user.actor_id);
|
create_activity::<CreateType, ActorAndObject<user_inbox::UserValidTypes>>(user.actor_id);
|
||||||
let path = Path::<String> {
|
let path = Path::<String> {
|
||||||
0: "username".to_string(),
|
0: "username".to_string(),
|
||||||
};
|
};
|
||||||
|
@ -196,8 +195,9 @@ async fn test_community_inbox_expired_signature() {
|
||||||
let user = create_user(connection, "community_inbox_hrxa");
|
let user = create_user(connection, "community_inbox_hrxa");
|
||||||
let community = create_community(connection, user.id);
|
let community = create_community(connection, user.id);
|
||||||
let request = create_http_request();
|
let request = create_http_request();
|
||||||
let activity =
|
let activity = create_activity::<FollowType, ActorAndObject<community_inbox::CommunityValidTypes>>(
|
||||||
create_activity::<FollowType, ActorAndObject<community_inbox::ValidTypes>>(user.actor_id);
|
user.actor_id,
|
||||||
|
);
|
||||||
let path = Path::<String> { 0: community.name };
|
let path = Path::<String> { 0: community.name };
|
||||||
let response = community_inbox(request, activity, path, web::Data::new(context)).await;
|
let response = community_inbox(request, activity, path, web::Data::new(context)).await;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
Loading…
Reference in a new issue