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