]> Untitled Git - lemmy.git/blob - src/code_migrations.rs
Moving settings and secrets to context.
[lemmy.git] / src / code_migrations.rs
1 // This is for db migrations that require code
2 use diesel::{
3   sql_types::{Nullable, Text},
4   *,
5 };
6 use lemmy_apub::{
7   generate_apub_endpoint,
8   generate_followers_url,
9   generate_inbox_url,
10   generate_shared_inbox_url,
11   EndpointType,
12 };
13 use lemmy_db_queries::{
14   source::{comment::Comment_, post::Post_, private_message::PrivateMessage_},
15   Crud,
16 };
17 use lemmy_db_schema::{
18   naive_now,
19   source::{
20     comment::Comment,
21     community::{Community, CommunityForm},
22     person::{Person, PersonForm},
23     post::Post,
24     private_message::PrivateMessage,
25   },
26 };
27 use lemmy_utils::{apub::generate_actor_keypair, LemmyError};
28 use log::info;
29
30 pub fn run_advanced_migrations(
31   conn: &PgConnection,
32   protocol_and_hostname: &str,
33 ) -> Result<(), LemmyError> {
34   user_updates_2020_04_02(conn, protocol_and_hostname)?;
35   community_updates_2020_04_02(conn, protocol_and_hostname)?;
36   post_updates_2020_04_03(conn, protocol_and_hostname)?;
37   comment_updates_2020_04_03(conn, protocol_and_hostname)?;
38   private_message_updates_2020_05_05(conn, protocol_and_hostname)?;
39   post_thumbnail_url_updates_2020_07_27(conn, protocol_and_hostname)?;
40   apub_columns_2021_02_02(conn)?;
41
42   Ok(())
43 }
44
45 fn user_updates_2020_04_02(
46   conn: &PgConnection,
47   protocol_and_hostname: &str,
48 ) -> Result<(), LemmyError> {
49   use lemmy_db_schema::schema::person::dsl::*;
50
51   info!("Running user_updates_2020_04_02");
52
53   // Update the actor_id, private_key, and public_key, last_refreshed_at
54   let incorrect_persons = person
55     .filter(actor_id.like("http://changeme_%"))
56     .filter(local.eq(true))
57     .load::<Person>(conn)?;
58
59   for cperson in &incorrect_persons {
60     let keypair = generate_actor_keypair()?;
61
62     let form = PersonForm {
63       name: cperson.name.to_owned(),
64       actor_id: Some(generate_apub_endpoint(
65         EndpointType::Person,
66         &cperson.name,
67         protocol_and_hostname,
68       )?),
69       private_key: Some(Some(keypair.private_key)),
70       public_key: Some(Some(keypair.public_key)),
71       last_refreshed_at: Some(naive_now()),
72       ..PersonForm::default()
73     };
74
75     Person::update(conn, cperson.id, &form)?;
76   }
77
78   info!("{} person rows updated.", incorrect_persons.len());
79
80   Ok(())
81 }
82
83 fn community_updates_2020_04_02(
84   conn: &PgConnection,
85   protocol_and_hostname: &str,
86 ) -> Result<(), LemmyError> {
87   use lemmy_db_schema::schema::community::dsl::*;
88
89   info!("Running community_updates_2020_04_02");
90
91   // Update the actor_id, private_key, and public_key, last_refreshed_at
92   let incorrect_communities = community
93     .filter(actor_id.like("http://changeme_%"))
94     .filter(local.eq(true))
95     .load::<Community>(conn)?;
96
97   for ccommunity in &incorrect_communities {
98     let keypair = generate_actor_keypair()?;
99     let community_actor_id = generate_apub_endpoint(
100       EndpointType::Community,
101       &ccommunity.name,
102       protocol_and_hostname,
103     )?;
104
105     let form = CommunityForm {
106       name: ccommunity.name.to_owned(),
107       title: ccommunity.title.to_owned(),
108       description: ccommunity.description.to_owned(),
109       removed: None,
110       deleted: None,
111       nsfw: None,
112       updated: None,
113       actor_id: Some(community_actor_id.to_owned()),
114       local: Some(ccommunity.local),
115       private_key: Some(keypair.private_key),
116       public_key: Some(keypair.public_key),
117       last_refreshed_at: Some(naive_now()),
118       published: None,
119       icon: Some(ccommunity.icon.to_owned()),
120       banner: Some(ccommunity.banner.to_owned()),
121       followers_url: None,
122       inbox_url: None,
123       shared_inbox_url: None,
124     };
125
126     Community::update(conn, ccommunity.id, &form)?;
127   }
128
129   info!("{} community rows updated.", incorrect_communities.len());
130
131   Ok(())
132 }
133
134 fn post_updates_2020_04_03(
135   conn: &PgConnection,
136   protocol_and_hostname: &str,
137 ) -> Result<(), LemmyError> {
138   use lemmy_db_schema::schema::post::dsl::*;
139
140   info!("Running post_updates_2020_04_03");
141
142   // Update the ap_id
143   let incorrect_posts = post
144     .filter(ap_id.like("http://changeme_%"))
145     .filter(local.eq(true))
146     .load::<Post>(conn)?;
147
148   for cpost in &incorrect_posts {
149     let apub_id = generate_apub_endpoint(
150       EndpointType::Post,
151       &cpost.id.to_string(),
152       protocol_and_hostname,
153     )?;
154     Post::update_ap_id(conn, cpost.id, apub_id)?;
155   }
156
157   info!("{} post rows updated.", incorrect_posts.len());
158
159   Ok(())
160 }
161
162 fn comment_updates_2020_04_03(
163   conn: &PgConnection,
164   protocol_and_hostname: &str,
165 ) -> Result<(), LemmyError> {
166   use lemmy_db_schema::schema::comment::dsl::*;
167
168   info!("Running comment_updates_2020_04_03");
169
170   // Update the ap_id
171   let incorrect_comments = comment
172     .filter(ap_id.like("http://changeme_%"))
173     .filter(local.eq(true))
174     .load::<Comment>(conn)?;
175
176   for ccomment in &incorrect_comments {
177     let apub_id = generate_apub_endpoint(
178       EndpointType::Comment,
179       &ccomment.id.to_string(),
180       protocol_and_hostname,
181     )?;
182     Comment::update_ap_id(conn, ccomment.id, apub_id)?;
183   }
184
185   info!("{} comment rows updated.", incorrect_comments.len());
186
187   Ok(())
188 }
189
190 fn private_message_updates_2020_05_05(
191   conn: &PgConnection,
192   protocol_and_hostname: &str,
193 ) -> Result<(), LemmyError> {
194   use lemmy_db_schema::schema::private_message::dsl::*;
195
196   info!("Running private_message_updates_2020_05_05");
197
198   // Update the ap_id
199   let incorrect_pms = private_message
200     .filter(ap_id.like("http://changeme_%"))
201     .filter(local.eq(true))
202     .load::<PrivateMessage>(conn)?;
203
204   for cpm in &incorrect_pms {
205     let apub_id = generate_apub_endpoint(
206       EndpointType::PrivateMessage,
207       &cpm.id.to_string(),
208       protocol_and_hostname,
209     )?;
210     PrivateMessage::update_ap_id(conn, cpm.id, apub_id)?;
211   }
212
213   info!("{} private message rows updated.", incorrect_pms.len());
214
215   Ok(())
216 }
217
218 fn post_thumbnail_url_updates_2020_07_27(
219   conn: &PgConnection,
220   protocol_and_hostname: &str,
221 ) -> Result<(), LemmyError> {
222   use lemmy_db_schema::schema::post::dsl::*;
223
224   info!("Running post_thumbnail_url_updates_2020_07_27");
225
226   let domain_prefix = format!("{}/pictrs/image/", protocol_and_hostname,);
227
228   let incorrect_thumbnails = post.filter(thumbnail_url.not_like("http%"));
229
230   // Prepend the rows with the update
231   let res = diesel::update(incorrect_thumbnails)
232     .set(
233       thumbnail_url.eq(
234         domain_prefix
235           .into_sql::<Nullable<Text>>()
236           .concat(thumbnail_url),
237       ),
238     )
239     .get_results::<Post>(conn)?;
240
241   info!("{} Post thumbnail_url rows updated.", res.len());
242
243   Ok(())
244 }
245
246 /// We are setting inbox and follower URLs for local and remote actors alike, because for now
247 /// all federated instances are also Lemmy and use the same URL scheme.
248 fn apub_columns_2021_02_02(conn: &PgConnection) -> Result<(), LemmyError> {
249   info!("Running apub_columns_2021_02_02");
250   {
251     use lemmy_db_schema::schema::person::dsl::*;
252     let persons = person
253       .filter(inbox_url.like("http://changeme_%"))
254       .load::<Person>(conn)?;
255
256     for p in &persons {
257       let inbox_url_ = generate_inbox_url(&p.actor_id)?;
258       let shared_inbox_url_ = generate_shared_inbox_url(&p.actor_id)?;
259       diesel::update(person.find(p.id))
260         .set((
261           inbox_url.eq(inbox_url_),
262           shared_inbox_url.eq(shared_inbox_url_),
263         ))
264         .get_result::<Person>(conn)?;
265     }
266   }
267
268   {
269     use lemmy_db_schema::schema::community::dsl::*;
270     let communities = community
271       .filter(inbox_url.like("http://changeme_%"))
272       .load::<Community>(conn)?;
273
274     for c in &communities {
275       let followers_url_ = generate_followers_url(&c.actor_id)?;
276       let inbox_url_ = generate_inbox_url(&c.actor_id)?;
277       let shared_inbox_url_ = generate_shared_inbox_url(&c.actor_id)?;
278       diesel::update(community.find(c.id))
279         .set((
280           followers_url.eq(followers_url_),
281           inbox_url.eq(inbox_url_),
282           shared_inbox_url.eq(shared_inbox_url_),
283         ))
284         .get_result::<Community>(conn)?;
285     }
286   }
287
288   Ok(())
289 }