]> Untitled Git - lemmy.git/blob - tests/integration_test.rs
Remove categories (fixes #1429)
[lemmy.git] / tests / integration_test.rs
1 extern crate lemmy_server;
2
3 #[macro_use]
4 extern crate diesel_migrations;
5 use activitystreams::{
6   activity::{
7     kind::{CreateType, FollowType},
8     ActorAndObject,
9   },
10   base::{BaseExt, ExtendsExt},
11   object::{Note, ObjectExt},
12 };
13 use actix::prelude::*;
14 use actix_web::{test::TestRequest, web, web::Path, HttpRequest};
15 use chrono::Utc;
16 use diesel::{
17   r2d2::{ConnectionManager, Pool},
18   PgConnection,
19 };
20 use http_signature_normalization_actix::PrepareVerifyError;
21 use lemmy_api::match_websocket_operation;
22 use lemmy_apub::{
23   activity_queue::create_activity_queue,
24   inbox::{
25     community_inbox,
26     community_inbox::community_inbox,
27     shared_inbox,
28     shared_inbox::shared_inbox,
29     user_inbox,
30     user_inbox::user_inbox,
31   },
32 };
33 use lemmy_db_queries::{get_database_url_from_env, Crud, ListingType, SortType};
34 use lemmy_db_schema::source::{
35   community::{Community, CommunityForm},
36   user::{UserForm, User_},
37 };
38 use lemmy_server::code_migrations::run_advanced_migrations;
39 use lemmy_utils::{
40   apub::generate_actor_keypair,
41   rate_limit::{rate_limiter::RateLimiter, RateLimit},
42   settings::Settings,
43 };
44 use lemmy_websocket::{chat_server::ChatServer, LemmyContext};
45 use reqwest::Client;
46 use serde::{Deserialize, Serialize};
47 use std::{ops::Deref, sync::Arc};
48 use tokio::sync::Mutex;
49 use url::Url;
50
51 embed_migrations!();
52
53 fn create_context() -> LemmyContext {
54   let settings = Settings::get();
55   let db_url = match get_database_url_from_env() {
56     Ok(url) => url,
57     Err(_) => settings.get_database_url(),
58   };
59   let manager = ConnectionManager::<PgConnection>::new(&db_url);
60   let pool = Pool::builder()
61     .max_size(settings.database.pool_size)
62     .build(manager)
63     .unwrap();
64   embedded_migrations::run(&pool.get().unwrap()).unwrap();
65   run_advanced_migrations(pool.get().unwrap().deref()).unwrap();
66   let rate_limiter = RateLimit {
67     rate_limiter: Arc::new(Mutex::new(RateLimiter::default())),
68   };
69   let activity_queue = create_activity_queue();
70   let chat_server = ChatServer::startup(
71     pool.clone(),
72     rate_limiter,
73     |c, i, o, d| Box::pin(match_websocket_operation(c, i, o, d)),
74     Client::default(),
75     activity_queue,
76   )
77   .start();
78   LemmyContext::create(
79     pool,
80     chat_server,
81     Client::default(),
82     create_activity_queue(),
83   )
84 }
85
86 fn create_user(conn: &PgConnection, name: &str) -> User_ {
87   let user_keypair = generate_actor_keypair().unwrap();
88   let new_user = UserForm {
89     name: name.into(),
90     preferred_username: None,
91     password_encrypted: "nope".into(),
92     email: None,
93     matrix_user_id: None,
94     avatar: None,
95     banner: None,
96     admin: false,
97     banned: Some(false),
98     updated: None,
99     published: None,
100     show_nsfw: false,
101     theme: "browser".into(),
102     default_sort_type: SortType::Hot as i16,
103     default_listing_type: ListingType::Subscribed as i16,
104     lang: "browser".into(),
105     show_avatars: true,
106     send_notifications_to_email: false,
107     actor_id: Some(
108       Url::parse(&format!("http://localhost:8536/u/{}", name))
109         .unwrap()
110         .into(),
111     ),
112     bio: None,
113     local: true,
114     private_key: Some(user_keypair.private_key),
115     public_key: Some(user_keypair.public_key),
116     last_refreshed_at: None,
117     inbox_url: None,
118     shared_inbox_url: None,
119   };
120
121   User_::create(&conn, &new_user).unwrap()
122 }
123
124 fn create_community(conn: &PgConnection, creator_id: i32) -> Community {
125   let new_community = CommunityForm {
126     name: "test_community".into(),
127     creator_id,
128     title: "test_community".to_owned(),
129     description: None,
130     nsfw: false,
131     removed: None,
132     deleted: None,
133     updated: None,
134     actor_id: None,
135     local: true,
136     private_key: None,
137     public_key: None,
138     last_refreshed_at: None,
139     published: None,
140     icon: None,
141     banner: None,
142     followers_url: None,
143     inbox_url: None,
144     shared_inbox_url: None,
145   };
146   Community::create(&conn, &new_community).unwrap()
147 }
148 fn create_activity<'a, Activity, Return>(user_id: Url) -> web::Json<Return>
149 where
150   for<'de> Return: Deserialize<'de> + 'a,
151   Activity: std::default::Default + Serialize,
152 {
153   let mut activity = ActorAndObject::<Activity>::new(user_id, Note::new().into_any_base().unwrap());
154   activity
155     .set_id(Url::parse("http://localhost:8536/create/1").unwrap())
156     .set_many_ccs(vec![Url::parse("http://localhost:8536/c/main").unwrap()]);
157   let activity = serde_json::to_value(&activity).unwrap();
158   let activity: Return = serde_json::from_value(activity).unwrap();
159   web::Json(activity)
160 }
161
162 fn create_http_request() -> HttpRequest {
163   let time1 = Utc::now().timestamp();
164   let time2 = Utc::now().timestamp();
165   let signature = format!(
166     r#"keyId="my-key-id",algorithm="hs2019",created="{}",expires="{}",headers="(request-target) (created) (expires) date content-type",signature="blah blah blah""#,
167     time1, time2
168   );
169   TestRequest::post()
170     .uri("http://localhost:8536/")
171     .header("Signature", signature)
172     .to_http_request()
173 }
174
175 // TODO: this fails with a stack overflow for some reason
176 #[actix_rt::test]
177 #[ignore]
178 async fn test_shared_inbox_expired_signature() {
179   let request = create_http_request();
180   let context = create_context();
181   let connection = &context.pool().get().unwrap();
182   let user = create_user(connection, "shared_inbox_rvgfd");
183   let activity =
184     create_activity::<CreateType, ActorAndObject<shared_inbox::ValidTypes>>(user.actor_id.into());
185   let response = shared_inbox(request, activity, web::Data::new(context)).await;
186   assert_eq!(
187     format!("{}", response.err().unwrap()),
188     format!("{}", PrepareVerifyError::Expired)
189   );
190   User_::delete(connection, user.id).unwrap();
191 }
192
193 #[actix_rt::test]
194 async fn test_user_inbox_expired_signature() {
195   let request = create_http_request();
196   let context = create_context();
197   let connection = &context.pool().get().unwrap();
198   let user = create_user(connection, "user_inbox_cgsax");
199   let activity =
200     create_activity::<CreateType, ActorAndObject<user_inbox::UserValidTypes>>(user.actor_id.into());
201   let path = Path::<String> {
202     0: "username".to_string(),
203   };
204   let response = user_inbox(request, activity, path, web::Data::new(context)).await;
205   assert_eq!(
206     format!("{}", response.err().unwrap()),
207     format!("{}", PrepareVerifyError::Expired)
208   );
209   User_::delete(connection, user.id).unwrap();
210 }
211
212 #[actix_rt::test]
213 async fn test_community_inbox_expired_signature() {
214   let context = create_context();
215   let connection = &context.pool().get().unwrap();
216   let user = create_user(connection, "community_inbox_hrxa");
217   let community = create_community(connection, user.id);
218   let request = create_http_request();
219   let activity = create_activity::<FollowType, ActorAndObject<community_inbox::CommunityValidTypes>>(
220     user.actor_id.into(),
221   );
222   let path = Path::<String> { 0: community.name };
223   let response = community_inbox(request, activity, path, web::Data::new(context)).await;
224   assert_eq!(
225     format!("{}", response.err().unwrap()),
226     format!("{}", PrepareVerifyError::Expired)
227   );
228   User_::delete(connection, user.id).unwrap();
229   Community::delete(connection, community.id).unwrap();
230 }