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