]> Untitled Git - lemmy.git/blob - tests/integration_test.rs
5e6964e440d914cfe3bc08402006e8a0da56bdbd
[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(format!("http://localhost:8536/u/{}", name)),
108     bio: None,
109     local: true,
110     private_key: Some(user_keypair.private_key),
111     public_key: Some(user_keypair.public_key),
112     last_refreshed_at: None,
113   };
114
115   User_::create(&conn, &new_user).unwrap()
116 }
117
118 fn create_community(conn: &PgConnection, creator_id: i32) -> Community {
119   let new_community = CommunityForm {
120     name: "test_community".into(),
121     creator_id,
122     title: "test_community".to_owned(),
123     description: None,
124     category_id: 1,
125     nsfw: false,
126     removed: None,
127     deleted: None,
128     updated: None,
129     actor_id: None,
130     local: true,
131     private_key: None,
132     public_key: None,
133     last_refreshed_at: None,
134     published: None,
135     icon: None,
136     banner: None,
137   };
138   Community::create(&conn, &new_community).unwrap()
139 }
140 fn create_activity<'a, Activity, Return>(user_id: String) -> web::Json<Return>
141 where
142   for<'de> Return: Deserialize<'de> + 'a,
143   Activity: std::default::Default + Serialize,
144 {
145   let mut activity = ActorAndObject::<Activity>::new(user_id, Note::new().into_any_base().unwrap());
146   activity
147     .set_id(Url::parse("http://localhost:8536/create/1").unwrap())
148     .set_many_ccs(vec![Url::parse("http://localhost:8536/c/main").unwrap()]);
149   let activity = serde_json::to_value(&activity).unwrap();
150   let activity: Return = serde_json::from_value(activity).unwrap();
151   web::Json(activity)
152 }
153
154 fn create_http_request() -> HttpRequest {
155   let time1 = Utc::now().timestamp();
156   let time2 = Utc::now().timestamp();
157   let signature = format!(
158     r#"keyId="my-key-id",algorithm="hs2019",created="{}",expires="{}",headers="(request-target) (created) (expires) date content-type",signature="blah blah blah""#,
159     time1, time2
160   );
161   TestRequest::post()
162     .uri("http://localhost:8536/")
163     .header("Signature", signature)
164     .to_http_request()
165 }
166
167 // TODO: this fails with a stack overflow for some reason
168 #[actix_rt::test]
169 #[ignore]
170 async fn test_shared_inbox_expired_signature() {
171   let request = create_http_request();
172   let context = create_context();
173   let connection = &context.pool().get().unwrap();
174   let user = create_user(connection, "shared_inbox_rvgfd");
175   let activity =
176     create_activity::<CreateType, ActorAndObject<shared_inbox::ValidTypes>>(user.actor_id);
177   let response = shared_inbox(request, activity, web::Data::new(context)).await;
178   assert_eq!(
179     format!("{}", response.err().unwrap()),
180     format!("{}", PrepareVerifyError::Expired)
181   );
182   User_::delete(connection, user.id).unwrap();
183 }
184
185 #[actix_rt::test]
186 async fn test_user_inbox_expired_signature() {
187   let request = create_http_request();
188   let context = create_context();
189   let connection = &context.pool().get().unwrap();
190   let user = create_user(connection, "user_inbox_cgsax");
191   let activity =
192     create_activity::<CreateType, ActorAndObject<user_inbox::UserValidTypes>>(user.actor_id);
193   let path = Path::<String> {
194     0: "username".to_string(),
195   };
196   let response = user_inbox(request, activity, path, web::Data::new(context)).await;
197   assert_eq!(
198     format!("{}", response.err().unwrap()),
199     format!("{}", PrepareVerifyError::Expired)
200   );
201   User_::delete(connection, user.id).unwrap();
202 }
203
204 #[actix_rt::test]
205 async fn test_community_inbox_expired_signature() {
206   let context = create_context();
207   let connection = &context.pool().get().unwrap();
208   let user = create_user(connection, "community_inbox_hrxa");
209   let community = create_community(connection, user.id);
210   let request = create_http_request();
211   let activity = create_activity::<FollowType, ActorAndObject<community_inbox::CommunityValidTypes>>(
212     user.actor_id,
213   );
214   let path = Path::<String> { 0: community.name };
215   let response = community_inbox(request, activity, path, web::Data::new(context)).await;
216   assert_eq!(
217     format!("{}", response.err().unwrap()),
218     format!("{}", PrepareVerifyError::Expired)
219   );
220   User_::delete(connection, user.id).unwrap();
221   Community::delete(connection, community.id).unwrap();
222 }