Replace PlumeRocket.conn with DbConn
This commit is contained in:
		
							parent
							
								
									78be49d57d
								
							
						
					
					
						commit
						ad285898f6
					
				| @ -46,8 +46,8 @@ impl_into_inbox_result! { | ||||
|     Reshare => Reshared | ||||
| } | ||||
| 
 | ||||
| pub fn inbox(conn: DbConn, act: serde_json::Value) -> Result<InboxResult, Error> { | ||||
|     Inbox::handle(&conn, act) | ||||
| pub fn inbox(conn: &DbConn, act: serde_json::Value) -> Result<InboxResult, Error> { | ||||
|     Inbox::handle(conn, act) | ||||
|         .with::<User, Announce, Post>(CONFIG.proxy()) | ||||
|         .with::<User, Create, Comment>(CONFIG.proxy()) | ||||
|         .with::<User, Create, Post>(CONFIG.proxy()) | ||||
|  | ||||
| @ -6,7 +6,7 @@ use rocket::{ | ||||
| use rocket_contrib::json::Json; | ||||
| 
 | ||||
| use plume_common::utils::random_hex; | ||||
| use plume_models::{api_tokens::*, apps::App, users::User, Error, PlumeRocket}; | ||||
| use plume_models::{api_tokens::*, apps::App, db_conn::DbConn, users::User, Error}; | ||||
| 
 | ||||
| type Api<T> = Result<Json<T>, ApiError>; | ||||
| 
 | ||||
| @ -54,16 +54,12 @@ pub struct OAuthRequest { | ||||
| } | ||||
| 
 | ||||
| #[get("/oauth2?<query..>")] | ||||
| pub fn oauth( | ||||
|     query: Form<OAuthRequest>, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Json<serde_json::Value>, ApiError> { | ||||
|     let conn = &*rockets.conn; | ||||
|     let app = App::find_by_client_id(conn, &query.client_id)?; | ||||
| pub fn oauth(query: Form<OAuthRequest>, conn: DbConn) -> Result<Json<serde_json::Value>, ApiError> { | ||||
|     let app = App::find_by_client_id(&conn, &query.client_id)?; | ||||
|     if app.client_secret == query.client_secret { | ||||
|         if let Ok(user) = User::login(conn, &query.username, &query.password) { | ||||
|         if let Ok(user) = User::login(&conn, &query.username, &query.password) { | ||||
|             let token = ApiToken::insert( | ||||
|                 conn, | ||||
|                 &conn, | ||||
|                 NewApiToken { | ||||
|                     app_id: app.id, | ||||
|                     user_id: user.id, | ||||
|  | ||||
| @ -102,12 +102,12 @@ pub fn list( | ||||
| pub fn create( | ||||
|     auth: Authorization<Write, Post>, | ||||
|     payload: Json<NewPostData>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Api<PostData> { | ||||
|     let conn = &*rockets.conn; | ||||
|     let worker = &rockets.worker; | ||||
| 
 | ||||
|     let author = User::get(conn, auth.0.user_id)?; | ||||
|     let author = User::get(&conn, auth.0.user_id)?; | ||||
| 
 | ||||
|     let slug = &payload.title.clone().to_kebab_case(); | ||||
|     let date = payload.creation_date.clone().and_then(|d| { | ||||
| @ -119,11 +119,11 @@ pub fn create( | ||||
|         &payload.source, | ||||
|         Some(domain), | ||||
|         false, | ||||
|         Some(Media::get_media_processor(conn, vec![&author])), | ||||
|         Some(Media::get_media_processor(&conn, vec![&author])), | ||||
|     ); | ||||
| 
 | ||||
|     let blog = payload.blog_id.or_else(|| { | ||||
|         let blogs = Blog::find_for_author(conn, &author).ok()?; | ||||
|         let blogs = Blog::find_for_author(&conn, &author).ok()?; | ||||
|         if blogs.len() == 1 { | ||||
|             Some(blogs[0].id) | ||||
|         } else { | ||||
| @ -131,12 +131,12 @@ pub fn create( | ||||
|         } | ||||
|     })?; | ||||
| 
 | ||||
|     if Post::find_by_slug(conn, slug, blog).is_ok() { | ||||
|     if Post::find_by_slug(&conn, slug, blog).is_ok() { | ||||
|         return Err(Error::InvalidValue.into()); | ||||
|     } | ||||
| 
 | ||||
|     let post = Post::insert( | ||||
|         conn, | ||||
|         &conn, | ||||
|         NewPost { | ||||
|             blog_id: blog, | ||||
|             slug: slug.to_string(), | ||||
| @ -157,7 +157,7 @@ pub fn create( | ||||
|     )?; | ||||
| 
 | ||||
|     PostAuthor::insert( | ||||
|         conn, | ||||
|         &conn, | ||||
|         NewPostAuthor { | ||||
|             author_id: author.id, | ||||
|             post_id: post.id, | ||||
| @ -167,7 +167,7 @@ pub fn create( | ||||
|     if let Some(ref tags) = payload.tags { | ||||
|         for tag in tags { | ||||
|             Tag::insert( | ||||
|                 conn, | ||||
|                 &conn, | ||||
|                 NewTag { | ||||
|                     tag: tag.to_string(), | ||||
|                     is_hashtag: false, | ||||
| @ -178,7 +178,7 @@ pub fn create( | ||||
|     } | ||||
|     for hashtag in hashtags { | ||||
|         Tag::insert( | ||||
|             conn, | ||||
|             &conn, | ||||
|             NewTag { | ||||
|                 tag: hashtag, | ||||
|                 is_hashtag: true, | ||||
| @ -190,25 +190,29 @@ pub fn create( | ||||
|     if post.published { | ||||
|         for m in mentions.into_iter() { | ||||
|             Mention::from_activity( | ||||
|                 &*conn, | ||||
|                 &Mention::build_activity(&rockets, &m)?, | ||||
|                 &conn, | ||||
|                 &Mention::build_activity(&conn, &m)?, | ||||
|                 post.id, | ||||
|                 true, | ||||
|                 true, | ||||
|             )?; | ||||
|         } | ||||
| 
 | ||||
|         let act = post.create_activity(&*conn)?; | ||||
|         let dest = User::one_by_instance(&*conn)?; | ||||
|         let act = post.create_activity(&conn)?; | ||||
|         let dest = User::one_by_instance(&conn)?; | ||||
|         worker.execute(move || broadcast(&author, act, dest, CONFIG.proxy().cloned())); | ||||
|     } | ||||
| 
 | ||||
|     Timeline::add_to_all_timelines(&rockets, &post, Kind::Original)?; | ||||
|     Timeline::add_to_all_timelines(&conn, &post, Kind::Original)?; | ||||
| 
 | ||||
|     Ok(Json(PostData { | ||||
|         authors: post.get_authors(conn)?.into_iter().map(|a| a.fqn).collect(), | ||||
|         authors: post | ||||
|             .get_authors(&conn)? | ||||
|             .into_iter() | ||||
|             .map(|a| a.fqn) | ||||
|             .collect(), | ||||
|         creation_date: post.creation_date.format("%Y-%m-%d").to_string(), | ||||
|         tags: Tag::for_post(conn, post.id)? | ||||
|         tags: Tag::for_post(&conn, post.id)? | ||||
|             .into_iter() | ||||
|             .map(|t| t.tag) | ||||
|             .collect(), | ||||
| @ -226,11 +230,11 @@ pub fn create( | ||||
| } | ||||
| 
 | ||||
| #[delete("/posts/<id>")] | ||||
| pub fn delete(auth: Authorization<Write, Post>, rockets: PlumeRocket, id: i32) -> Api<()> { | ||||
|     let author = User::get(&*rockets.conn, auth.0.user_id)?; | ||||
|     if let Ok(post) = Post::get(&*rockets.conn, id) { | ||||
|         if post.is_author(&*rockets.conn, author.id).unwrap_or(false) { | ||||
|             post.delete(&*rockets.conn)?; | ||||
| pub fn delete(auth: Authorization<Write, Post>, conn: DbConn, id: i32) -> Api<()> { | ||||
|     let author = User::get(&conn, auth.0.user_id)?; | ||||
|     if let Ok(post) = Post::get(&conn, id) { | ||||
|         if post.is_author(&conn, author.id).unwrap_or(false) { | ||||
|             post.delete(&conn)?; | ||||
|         } | ||||
|     } | ||||
|     Ok(Json(())) | ||||
|  | ||||
							
								
								
									
										15
									
								
								src/inbox.rs
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/inbox.rs
									
									
									
									
									
								
							| @ -4,7 +4,7 @@ use plume_common::activity_pub::{ | ||||
|     sign::{verify_http_headers, Signable}, | ||||
| }; | ||||
| use plume_models::{ | ||||
|     headers::Headers, inbox::inbox, instance::Instance, users::User, Error, PlumeRocket, CONFIG, | ||||
|     db_conn::DbConn, headers::Headers, inbox::inbox, instance::Instance, users::User, Error, CONFIG, | ||||
| }; | ||||
| use rocket::{data::*, http::Status, response::status, Outcome::*, Request}; | ||||
| use rocket_contrib::json::*; | ||||
| @ -13,11 +13,10 @@ use std::io::Read; | ||||
| use tracing::warn; | ||||
| 
 | ||||
| pub fn handle_incoming( | ||||
|     rockets: PlumeRocket, | ||||
|     conn: DbConn, | ||||
|     data: SignedJson<serde_json::Value>, | ||||
|     headers: Headers<'_>, | ||||
| ) -> Result<String, status::BadRequest<&'static str>> { | ||||
|     let conn = &*rockets.conn; | ||||
|     let act = data.1.into_inner(); | ||||
|     let sig = data.0; | ||||
| 
 | ||||
| @ -27,13 +26,13 @@ pub fn handle_incoming( | ||||
|         .or_else(|| activity["actor"]["id"].as_str()) | ||||
|         .ok_or(status::BadRequest(Some("Missing actor id for activity")))?; | ||||
| 
 | ||||
|     let actor = User::from_id(&rockets, actor_id, None, CONFIG.proxy()) | ||||
|     let actor = User::from_id(&conn, actor_id, None, CONFIG.proxy()) | ||||
|         .expect("instance::shared_inbox: user error"); | ||||
|     if !verify_http_headers(&actor, &headers.0, &sig).is_secure() && !act.clone().verify(&actor) { | ||||
|         // maybe we just know an old key?
 | ||||
|         actor | ||||
|             .refetch(conn) | ||||
|             .and_then(|_| User::get(conn, actor.id)) | ||||
|             .refetch(&conn) | ||||
|             .and_then(|_| User::get(&conn, actor.id)) | ||||
|             .and_then(|u| { | ||||
|                 if verify_http_headers(&u, &headers.0, &sig).is_secure() || act.clone().verify(&u) { | ||||
|                     Ok(()) | ||||
| @ -50,13 +49,13 @@ pub fn handle_incoming( | ||||
|             })?; | ||||
|     } | ||||
| 
 | ||||
|     if Instance::is_blocked(conn, actor_id) | ||||
|     if Instance::is_blocked(&conn, actor_id) | ||||
|         .map_err(|_| status::BadRequest(Some("Can't tell if instance is blocked")))? | ||||
|     { | ||||
|         return Ok(String::new()); | ||||
|     } | ||||
| 
 | ||||
|     Ok(match inbox(&rockets, act) { | ||||
|     Ok(match inbox(&conn, act) { | ||||
|         Ok(_) => String::new(), | ||||
|         Err(e) => { | ||||
|             warn!("Shared inbox error: {:?}", e); | ||||
|  | ||||
| @ -14,21 +14,25 @@ use crate::template_utils::{IntoContext, Ructe}; | ||||
| use plume_common::activity_pub::{ActivityStream, ApRequest}; | ||||
| use plume_common::utils; | ||||
| use plume_models::{ | ||||
|     blog_authors::*, blogs::*, instance::Instance, medias::*, posts::Post, safe_string::SafeString, | ||||
|     users::User, Connection, PlumeRocket, | ||||
|     blog_authors::*, blogs::*, db_conn::DbConn, instance::Instance, medias::*, posts::Post, | ||||
|     safe_string::SafeString, users::User, Connection, PlumeRocket, | ||||
| }; | ||||
| 
 | ||||
| #[get("/~/<name>?<page>", rank = 2)] | ||||
| pub fn details(name: String, page: Option<Page>, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
| pub fn details( | ||||
|     name: String, | ||||
|     page: Option<Page>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Ructe, ErrorPage> { | ||||
|     let page = page.unwrap_or_default(); | ||||
|     let conn = &*rockets.conn; | ||||
|     let blog = Blog::find_by_fqn(&rockets, &name)?; | ||||
|     let posts = Post::blog_page(conn, &blog, page.limits())?; | ||||
|     let articles_count = Post::count_for_blog(conn, &blog)?; | ||||
|     let authors = &blog.list_authors(conn)?; | ||||
|     let blog = Blog::find_by_fqn(&conn, &name)?; | ||||
|     let posts = Post::blog_page(&conn, &blog, page.limits())?; | ||||
|     let articles_count = Post::count_for_blog(&conn, &blog)?; | ||||
|     let authors = &blog.list_authors(&conn)?; | ||||
| 
 | ||||
|     Ok(render!(blogs::details( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         blog, | ||||
|         authors, | ||||
|         page.0, | ||||
| @ -40,17 +44,17 @@ pub fn details(name: String, page: Option<Page>, rockets: PlumeRocket) -> Result | ||||
| #[get("/~/<name>", rank = 1)] | ||||
| pub fn activity_details( | ||||
|     name: String, | ||||
|     rockets: PlumeRocket, | ||||
|     conn: DbConn, | ||||
|     _ap: ApRequest, | ||||
| ) -> Option<ActivityStream<CustomGroup>> { | ||||
|     let blog = Blog::find_by_fqn(&rockets, &name).ok()?; | ||||
|     Some(ActivityStream::new(blog.to_activity(&*rockets.conn).ok()?)) | ||||
|     let blog = Blog::find_by_fqn(&conn, &name).ok()?; | ||||
|     Some(ActivityStream::new(blog.to_activity(&conn).ok()?)) | ||||
| } | ||||
| 
 | ||||
| #[get("/blogs/new")] | ||||
| pub fn new(rockets: PlumeRocket, _user: User) -> Ructe { | ||||
| pub fn new(conn: DbConn, rockets: PlumeRocket, _user: User) -> Ructe { | ||||
|     render!(blogs::new( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         &NewBlogForm::default(), | ||||
|         ValidationErrors::default() | ||||
|     )) | ||||
| @ -83,9 +87,12 @@ fn valid_slug(title: &str) -> Result<(), ValidationError> { | ||||
| } | ||||
| 
 | ||||
| #[post("/blogs/new", data = "<form>")] | ||||
| pub fn create(form: LenientForm<NewBlogForm>, rockets: PlumeRocket) -> RespondOrRedirect { | ||||
| pub fn create( | ||||
|     form: LenientForm<NewBlogForm>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> RespondOrRedirect { | ||||
|     let slug = utils::make_actor_id(&form.title); | ||||
|     let conn = &*rockets.conn; | ||||
|     let intl = &rockets.intl.catalog; | ||||
|     let user = rockets.user.clone().unwrap(); | ||||
| 
 | ||||
| @ -93,7 +100,7 @@ pub fn create(form: LenientForm<NewBlogForm>, rockets: PlumeRocket) -> RespondOr | ||||
|         Ok(_) => ValidationErrors::new(), | ||||
|         Err(e) => e, | ||||
|     }; | ||||
|     if Blog::find_by_fqn(&rockets, &slug).is_ok() { | ||||
|     if Blog::find_by_fqn(&conn, &slug).is_ok() { | ||||
|         errors.add( | ||||
|             "title", | ||||
|             ValidationError { | ||||
| @ -108,11 +115,11 @@ pub fn create(form: LenientForm<NewBlogForm>, rockets: PlumeRocket) -> RespondOr | ||||
|     } | ||||
| 
 | ||||
|     if !errors.is_empty() { | ||||
|         return render!(blogs::new(&rockets.to_context(), &*form, errors)).into(); | ||||
|         return render!(blogs::new(&(&conn, &rockets).to_context(), &*form, errors)).into(); | ||||
|     } | ||||
| 
 | ||||
|     let blog = Blog::insert( | ||||
|         &*conn, | ||||
|         &conn, | ||||
|         NewBlog::new_local( | ||||
|             slug.clone(), | ||||
|             form.title.to_string(), | ||||
| @ -126,7 +133,7 @@ pub fn create(form: LenientForm<NewBlogForm>, rockets: PlumeRocket) -> RespondOr | ||||
|     .expect("blog::create:  error"); | ||||
| 
 | ||||
|     BlogAuthor::insert( | ||||
|         &*conn, | ||||
|         &conn, | ||||
|         NewBlogAuthor { | ||||
|             blog_id: blog.id, | ||||
|             author_id: user.id, | ||||
| @ -143,17 +150,16 @@ pub fn create(form: LenientForm<NewBlogForm>, rockets: PlumeRocket) -> RespondOr | ||||
| } | ||||
| 
 | ||||
| #[post("/~/<name>/delete")] | ||||
| pub fn delete(name: String, rockets: PlumeRocket) -> RespondOrRedirect { | ||||
|     let conn = &*rockets.conn; | ||||
|     let blog = Blog::find_by_fqn(&rockets, &name).expect("blog::delete: blog not found"); | ||||
| pub fn delete(name: String, conn: DbConn, rockets: PlumeRocket) -> RespondOrRedirect { | ||||
|     let blog = Blog::find_by_fqn(&conn, &name).expect("blog::delete: blog not found"); | ||||
| 
 | ||||
|     if rockets | ||||
|         .user | ||||
|         .clone() | ||||
|         .and_then(|u| u.is_author_in(&*conn, &blog).ok()) | ||||
|         .and_then(|u| u.is_author_in(&conn, &blog).ok()) | ||||
|         .unwrap_or(false) | ||||
|     { | ||||
|         blog.delete(&conn).expect("blog::expect: deletion error"); | ||||
|         blog.delete(&*conn).expect("blog::expect: deletion error"); | ||||
|         Flash::success( | ||||
|             Redirect::to(uri!(super::instance::index)), | ||||
|             i18n!(rockets.intl.catalog, "Your blog was deleted."), | ||||
| @ -162,7 +168,7 @@ pub fn delete(name: String, rockets: PlumeRocket) -> RespondOrRedirect { | ||||
|     } else { | ||||
|         // TODO actually return 403 error code
 | ||||
|         render!(errors::not_authorized( | ||||
|             &rockets.to_context(), | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             i18n!( | ||||
|                 rockets.intl.catalog, | ||||
|                 "You are not allowed to delete this blog." | ||||
| @ -183,22 +189,21 @@ pub struct EditForm { | ||||
| } | ||||
| 
 | ||||
| #[get("/~/<name>/edit")] | ||||
| pub fn edit(name: String, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
|     let conn = &*rockets.conn; | ||||
|     let blog = Blog::find_by_fqn(&rockets, &name)?; | ||||
| pub fn edit(name: String, conn: DbConn, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
|     let blog = Blog::find_by_fqn(&conn, &name)?; | ||||
|     if rockets | ||||
|         .user | ||||
|         .clone() | ||||
|         .and_then(|u| u.is_author_in(conn, &blog).ok()) | ||||
|         .and_then(|u| u.is_author_in(&conn, &blog).ok()) | ||||
|         .unwrap_or(false) | ||||
|     { | ||||
|         let user = rockets | ||||
|             .user | ||||
|             .clone() | ||||
|             .expect("blogs::edit: User was None while it shouldn't"); | ||||
|         let medias = Media::for_user(conn, user.id).expect("Couldn't list media"); | ||||
|         let medias = Media::for_user(&conn, user.id).expect("Couldn't list media"); | ||||
|         Ok(render!(blogs::edit( | ||||
|             &rockets.to_context(), | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             &blog, | ||||
|             medias, | ||||
|             &EditForm { | ||||
| @ -213,7 +218,7 @@ pub fn edit(name: String, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
|     } else { | ||||
|         // TODO actually return 403 error code
 | ||||
|         Ok(render!(errors::not_authorized( | ||||
|             &rockets.to_context(), | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             i18n!( | ||||
|                 rockets.intl.catalog, | ||||
|                 "You are not allowed to edit this blog." | ||||
| @ -235,20 +240,20 @@ fn check_media(conn: &Connection, id: i32, user: &User) -> bool { | ||||
| pub fn update( | ||||
|     name: String, | ||||
|     form: LenientForm<EditForm>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> RespondOrRedirect { | ||||
|     let conn = &*rockets.conn; | ||||
|     let intl = &rockets.intl.catalog; | ||||
|     let mut blog = Blog::find_by_fqn(&rockets, &name).expect("blog::update: blog not found"); | ||||
|     let mut blog = Blog::find_by_fqn(&conn, &name).expect("blog::update: blog not found"); | ||||
|     if !rockets | ||||
|         .user | ||||
|         .clone() | ||||
|         .and_then(|u| u.is_author_in(&*conn, &blog).ok()) | ||||
|         .and_then(|u| u.is_author_in(&conn, &blog).ok()) | ||||
|         .unwrap_or(false) | ||||
|     { | ||||
|         // TODO actually return 403 error code
 | ||||
|         return render!(errors::not_authorized( | ||||
|             &rockets.to_context(), | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             i18n!( | ||||
|                 rockets.intl.catalog, | ||||
|                 "You are not allowed to edit this blog." | ||||
| @ -264,7 +269,7 @@ pub fn update( | ||||
|     form.validate() | ||||
|         .and_then(|_| { | ||||
|             if let Some(icon) = form.icon { | ||||
|                 if !check_media(&*conn, icon, &user) { | ||||
|                 if !check_media(&conn, icon, &user) { | ||||
|                     let mut errors = ValidationErrors::new(); | ||||
|                     errors.add( | ||||
|                         "", | ||||
| @ -282,7 +287,7 @@ pub fn update( | ||||
|             } | ||||
| 
 | ||||
|             if let Some(banner) = form.banner { | ||||
|                 if !check_media(&*conn, banner, &user) { | ||||
|                 if !check_media(&conn, banner, &user) { | ||||
|                     let mut errors = ValidationErrors::new(); | ||||
|                     errors.add( | ||||
|                         "", | ||||
| @ -327,9 +332,9 @@ pub fn update( | ||||
|             )) | ||||
|         }) | ||||
|         .map_err(|err| { | ||||
|             let medias = Media::for_user(&*conn, user.id).expect("Couldn't list media"); | ||||
|             let medias = Media::for_user(&conn, user.id).expect("Couldn't list media"); | ||||
|             render!(blogs::edit( | ||||
|                 &rockets.to_context(), | ||||
|                 &(&conn, &rockets).to_context(), | ||||
|                 &blog, | ||||
|                 medias, | ||||
|                 &*form, | ||||
| @ -341,31 +346,30 @@ pub fn update( | ||||
| } | ||||
| 
 | ||||
| #[get("/~/<name>/outbox")] | ||||
| pub fn outbox(name: String, rockets: PlumeRocket) -> Option<ActivityStream<OrderedCollection>> { | ||||
|     let blog = Blog::find_by_fqn(&rockets, &name).ok()?; | ||||
|     Some(blog.outbox(&*rockets.conn).ok()?) | ||||
| pub fn outbox(name: String, conn: DbConn) -> Option<ActivityStream<OrderedCollection>> { | ||||
|     let blog = Blog::find_by_fqn(&conn, &name).ok()?; | ||||
|     Some(blog.outbox(&conn).ok()?) | ||||
| } | ||||
| #[allow(unused_variables)] | ||||
| #[get("/~/<name>/outbox?<page>")] | ||||
| pub fn outbox_page( | ||||
|     name: String, | ||||
|     page: Page, | ||||
|     rockets: PlumeRocket, | ||||
|     conn: DbConn, | ||||
| ) -> Option<ActivityStream<OrderedCollectionPage>> { | ||||
|     let blog = Blog::find_by_fqn(&rockets, &name).ok()?; | ||||
|     Some(blog.outbox_page(&*rockets.conn, page.limits()).ok()?) | ||||
|     let blog = Blog::find_by_fqn(&conn, &name).ok()?; | ||||
|     Some(blog.outbox_page(&conn, page.limits()).ok()?) | ||||
| } | ||||
| #[get("/~/<name>/atom.xml")] | ||||
| pub fn atom_feed(name: String, rockets: PlumeRocket) -> Option<Content<String>> { | ||||
|     let blog = Blog::find_by_fqn(&rockets, &name).ok()?; | ||||
|     let conn = &*rockets.conn; | ||||
| pub fn atom_feed(name: String, conn: DbConn) -> Option<Content<String>> { | ||||
|     let blog = Blog::find_by_fqn(&conn, &name).ok()?; | ||||
|     let entries = Post::get_recents_for_blog(&*conn, &blog, 15).ok()?; | ||||
|     let uri = Instance::get_local() | ||||
|         .ok()? | ||||
|         .compute_box("~", &name, "atom.xml"); | ||||
|     let title = &blog.title; | ||||
|     let default_updated = &blog.creation_date; | ||||
|     let feed = super::build_atom_feed(entries, &uri, title, default_updated, conn); | ||||
|     let feed = super::build_atom_feed(entries, &uri, title, default_updated, &conn); | ||||
|     Some(Content( | ||||
|         ContentType::new("application", "atom+xml"), | ||||
|         feed.to_string(), | ||||
|  | ||||
| @ -15,8 +15,9 @@ use plume_common::{ | ||||
|     utils, | ||||
| }; | ||||
| use plume_models::{ | ||||
|     blogs::Blog, comments::*, inbox::inbox, instance::Instance, medias::Media, mentions::Mention, | ||||
|     posts::Post, safe_string::SafeString, tags::Tag, users::User, Error, PlumeRocket, CONFIG, | ||||
|     blogs::Blog, comments::*, db_conn::DbConn, inbox::inbox, instance::Instance, medias::Media, | ||||
|     mentions::Mention, posts::Post, safe_string::SafeString, tags::Tag, users::User, Error, | ||||
|     PlumeRocket, CONFIG, | ||||
| }; | ||||
| 
 | ||||
| #[derive(Default, FromForm, Debug, Validate)] | ||||
| @ -33,11 +34,11 @@ pub fn create( | ||||
|     slug: String, | ||||
|     form: LenientForm<NewCommentForm>, | ||||
|     user: User, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Flash<Redirect>, Ructe> { | ||||
|     let conn = &*rockets.conn; | ||||
|     let blog = Blog::find_by_fqn(&rockets, &blog_name).expect("comments::create: blog error"); | ||||
|     let post = Post::find_by_slug(&*conn, &slug, blog.id).expect("comments::create: post error"); | ||||
|     let blog = Blog::find_by_fqn(&conn, &blog_name).expect("comments::create: blog error"); | ||||
|     let post = Post::find_by_slug(&conn, &slug, blog.id).expect("comments::create: post error"); | ||||
|     form.validate() | ||||
|         .map(|_| { | ||||
|             let (html, mentions, _hashtags) = utils::md_to_html( | ||||
| @ -51,7 +52,7 @@ pub fn create( | ||||
|                 Some(Media::get_media_processor(&conn, vec![&user])), | ||||
|             ); | ||||
|             let comm = Comment::insert( | ||||
|                 &*conn, | ||||
|                 &conn, | ||||
|                 NewComment { | ||||
|                     content: SafeString::new(html.as_ref()), | ||||
|                     in_response_to_id: form.responding_to, | ||||
| @ -65,14 +66,14 @@ pub fn create( | ||||
|             ) | ||||
|             .expect("comments::create: insert error"); | ||||
|             let new_comment = comm | ||||
|                 .create_activity(&rockets) | ||||
|                 .create_activity(&conn) | ||||
|                 .expect("comments::create: activity error"); | ||||
| 
 | ||||
|             // save mentions
 | ||||
|             for ment in mentions { | ||||
|                 Mention::from_activity( | ||||
|                     &*conn, | ||||
|                     &Mention::build_activity(&rockets, &ment) | ||||
|                     &conn, | ||||
|                     &Mention::build_activity(&conn, &ment) | ||||
|                         .expect("comments::create: build mention error"), | ||||
|                     comm.id, | ||||
|                     false, | ||||
| @ -81,10 +82,10 @@ pub fn create( | ||||
|                 .expect("comments::create: mention save error"); | ||||
|             } | ||||
| 
 | ||||
|             comm.notify(&*conn).expect("comments::create: notify error"); | ||||
|             comm.notify(&conn).expect("comments::create: notify error"); | ||||
| 
 | ||||
|             // federate
 | ||||
|             let dest = User::one_by_instance(&*conn).expect("comments::create: dest error"); | ||||
|             let dest = User::one_by_instance(&conn).expect("comments::create: dest error"); | ||||
|             let user_clone = user.clone(); | ||||
|             rockets.worker.execute(move || { | ||||
|                 broadcast(&user_clone, new_comment, dest, CONFIG.proxy().cloned()) | ||||
| @ -101,38 +102,36 @@ pub fn create( | ||||
|         }) | ||||
|         .map_err(|errors| { | ||||
|             // TODO: de-duplicate this code
 | ||||
|             let comments = CommentTree::from_post(&*conn, &post, Some(&user)) | ||||
|             let comments = CommentTree::from_post(&conn, &post, Some(&user)) | ||||
|                 .expect("comments::create: comments error"); | ||||
| 
 | ||||
|             let previous = form | ||||
|                 .responding_to | ||||
|                 .and_then(|r| Comment::get(&*conn, r).ok()); | ||||
|             let previous = form.responding_to.and_then(|r| Comment::get(&conn, r).ok()); | ||||
| 
 | ||||
|             render!(posts::details( | ||||
|                 &rockets.to_context(), | ||||
|                 &(&conn, &rockets).to_context(), | ||||
|                 post.clone(), | ||||
|                 blog, | ||||
|                 &*form, | ||||
|                 errors, | ||||
|                 Tag::for_post(&*conn, post.id).expect("comments::create: tags error"), | ||||
|                 Tag::for_post(&conn, post.id).expect("comments::create: tags error"), | ||||
|                 comments, | ||||
|                 previous, | ||||
|                 post.count_likes(&*conn) | ||||
|                 post.count_likes(&conn) | ||||
|                     .expect("comments::create: count likes error"), | ||||
|                 post.count_reshares(&*conn) | ||||
|                 post.count_reshares(&conn) | ||||
|                     .expect("comments::create: count reshares error"), | ||||
|                 user.has_liked(&*conn, &post) | ||||
|                 user.has_liked(&conn, &post) | ||||
|                     .expect("comments::create: liked error"), | ||||
|                 user.has_reshared(&*conn, &post) | ||||
|                 user.has_reshared(&conn, &post) | ||||
|                     .expect("comments::create: reshared error"), | ||||
|                 user.is_following( | ||||
|                     &*conn, | ||||
|                     post.get_authors(&*conn) | ||||
|                     post.get_authors(&conn) | ||||
|                         .expect("comments::create: authors error")[0] | ||||
|                         .id | ||||
|                 ) | ||||
|                 .expect("comments::create: following error"), | ||||
|                 post.get_authors(&*conn) | ||||
|                 post.get_authors(&conn) | ||||
|                     .expect("comments::create: authors error")[0] | ||||
|                     .clone() | ||||
|             )) | ||||
| @ -145,14 +144,15 @@ pub fn delete( | ||||
|     slug: String, | ||||
|     id: i32, | ||||
|     user: User, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Flash<Redirect>, ErrorPage> { | ||||
|     if let Ok(comment) = Comment::get(&*rockets.conn, id) { | ||||
|     if let Ok(comment) = Comment::get(&conn, id) { | ||||
|         if comment.author_id == user.id { | ||||
|             let dest = User::one_by_instance(&*rockets.conn)?; | ||||
|             let delete_activity = comment.build_delete(&*rockets.conn)?; | ||||
|             let dest = User::one_by_instance(&conn)?; | ||||
|             let delete_activity = comment.build_delete(&conn)?; | ||||
|             inbox( | ||||
|                 &rockets, | ||||
|                 &conn, | ||||
|                 serde_json::to_value(&delete_activity).map_err(Error::from)?, | ||||
|             )?; | ||||
| 
 | ||||
| @ -160,7 +160,6 @@ pub fn delete( | ||||
|             rockets.worker.execute(move || { | ||||
|                 broadcast(&user_c, delete_activity, dest, CONFIG.proxy().cloned()) | ||||
|             }); | ||||
|             let conn = rockets.conn; | ||||
|             rockets | ||||
|                 .worker | ||||
|                 .execute_after(Duration::from_secs(10 * 60), move || { | ||||
| @ -185,10 +184,10 @@ pub fn activity_pub( | ||||
|     _slug: String, | ||||
|     id: i32, | ||||
|     _ap: ApRequest, | ||||
|     rockets: PlumeRocket, | ||||
|     conn: DbConn, | ||||
| ) -> Option<ActivityStream<Note>> { | ||||
|     Comment::get(&*rockets.conn, id) | ||||
|         .and_then(|c| c.to_activity(&rockets)) | ||||
|     Comment::get(&conn, id) | ||||
|         .and_then(|c| c.to_activity(&conn)) | ||||
|         .ok() | ||||
|         .map(ActivityStream::new) | ||||
| } | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| use crate::template_utils::{IntoContext, Ructe}; | ||||
| use plume_models::{Error, PlumeRocket}; | ||||
| use plume_models::{db_conn::DbConn, Error, PlumeRocket}; | ||||
| use rocket::{ | ||||
|     response::{self, Responder}, | ||||
|     Request, | ||||
| @ -17,40 +17,48 @@ impl From<Error> for ErrorPage { | ||||
| 
 | ||||
| impl<'r> Responder<'r> for ErrorPage { | ||||
|     fn respond_to(self, req: &Request<'_>) -> response::Result<'r> { | ||||
|         let conn = req.guard::<DbConn>().unwrap(); | ||||
|         let rockets = req.guard::<PlumeRocket>().unwrap(); | ||||
| 
 | ||||
|         match self.0 { | ||||
|             Error::NotFound => render!(errors::not_found(&rockets.to_context())).respond_to(req), | ||||
|             Error::Unauthorized => { | ||||
|                 render!(errors::not_found(&rockets.to_context())).respond_to(req) | ||||
|             Error::NotFound => { | ||||
|                 render!(errors::not_found(&(&conn, &rockets).to_context())).respond_to(req) | ||||
|             } | ||||
|             _ => render!(errors::not_found(&rockets.to_context())).respond_to(req), | ||||
|             Error::Unauthorized => { | ||||
|                 render!(errors::not_found(&(&conn, &rockets).to_context())).respond_to(req) | ||||
|             } | ||||
|             _ => render!(errors::not_found(&(&conn, &rockets).to_context())).respond_to(req), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[catch(404)] | ||||
| pub fn not_found(req: &Request<'_>) -> Ructe { | ||||
|     let conn = req.guard::<DbConn>().unwrap(); | ||||
|     let rockets = req.guard::<PlumeRocket>().unwrap(); | ||||
|     render!(errors::not_found(&rockets.to_context())) | ||||
|     render!(errors::not_found(&(&conn, &rockets).to_context())) | ||||
| } | ||||
| 
 | ||||
| #[catch(422)] | ||||
| pub fn unprocessable_entity(req: &Request<'_>) -> Ructe { | ||||
|     let conn = req.guard::<DbConn>().unwrap(); | ||||
|     let rockets = req.guard::<PlumeRocket>().unwrap(); | ||||
|     render!(errors::unprocessable_entity(&rockets.to_context())) | ||||
|     render!(errors::unprocessable_entity( | ||||
|         &(&conn, &rockets).to_context() | ||||
|     )) | ||||
| } | ||||
| 
 | ||||
| #[catch(500)] | ||||
| pub fn server_error(req: &Request<'_>) -> Ructe { | ||||
|     let conn = req.guard::<DbConn>().unwrap(); | ||||
|     let rockets = req.guard::<PlumeRocket>().unwrap(); | ||||
|     render!(errors::server_error(&rockets.to_context())) | ||||
|     render!(errors::server_error(&(&conn, &rockets).to_context())) | ||||
| } | ||||
| 
 | ||||
| #[post("/csrf-violation?<target>")] | ||||
| pub fn csrf_violation(target: Option<String>, rockets: PlumeRocket) -> Ructe { | ||||
| pub fn csrf_violation(target: Option<String>, conn: DbConn, rockets: PlumeRocket) -> Ructe { | ||||
|     if let Some(uri) = target { | ||||
|         warn!("Csrf violation while accessing \"{}\"", uri) | ||||
|     } | ||||
|     render!(errors::csrf(&rockets.to_context())) | ||||
|     render!(errors::csrf(&(&conn, &rockets).to_context())) | ||||
| } | ||||
|  | ||||
| @ -27,8 +27,7 @@ use plume_models::{ | ||||
| }; | ||||
| 
 | ||||
| #[get("/")] | ||||
| pub fn index(rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
|     let conn = &*rockets.conn; | ||||
| pub fn index(conn: DbConn, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
|     let inst = Instance::get_local()?; | ||||
|     let timelines = Timeline::list_all_for_user(&conn, rockets.user.clone().map(|u| u.id))? | ||||
|         .into_iter() | ||||
| @ -42,19 +41,19 @@ pub fn index(rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
|         .collect(); | ||||
| 
 | ||||
|     Ok(render!(instance::index( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         inst, | ||||
|         User::count_local(conn)?, | ||||
|         Post::count_local(conn)?, | ||||
|         User::count_local(&conn)?, | ||||
|         Post::count_local(&conn)?, | ||||
|         timelines | ||||
|     ))) | ||||
| } | ||||
| 
 | ||||
| #[get("/admin")] | ||||
| pub fn admin(_admin: Admin, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
| pub fn admin(_admin: Admin, conn: DbConn, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
|     let local_inst = Instance::get_local()?; | ||||
|     Ok(render!(instance::admin( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         local_inst.clone(), | ||||
|         InstanceSettingsForm { | ||||
|             name: local_inst.name.clone(), | ||||
| @ -68,8 +67,8 @@ pub fn admin(_admin: Admin, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
| } | ||||
| 
 | ||||
| #[get("/admin", rank = 2)] | ||||
| pub fn admin_mod(_mod: Moderator, rockets: PlumeRocket) -> Ructe { | ||||
|     render!(instance::admin_mod(&rockets.to_context())) | ||||
| pub fn admin_mod(_mod: Moderator, conn: DbConn, rockets: PlumeRocket) -> Ructe { | ||||
|     render!(instance::admin_mod(&(&conn, &rockets).to_context())) | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, FromForm, Validate)] | ||||
| @ -87,14 +86,14 @@ pub struct InstanceSettingsForm { | ||||
| pub fn update_settings( | ||||
|     _admin: Admin, | ||||
|     form: LenientForm<InstanceSettingsForm>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> RespondOrRedirect { | ||||
|     let conn = &*rockets.conn; | ||||
|     if let Err(e) = form.validate() { | ||||
|         let local_inst = | ||||
|             Instance::get_local().expect("instance::update_settings: local instance error"); | ||||
|         render!(instance::admin( | ||||
|             &rockets.to_context(), | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             local_inst, | ||||
|             form.clone(), | ||||
|             e | ||||
| @ -105,7 +104,7 @@ pub fn update_settings( | ||||
|             Instance::get_local().expect("instance::update_settings: local instance error"); | ||||
|         instance | ||||
|             .update( | ||||
|                 conn, | ||||
|                 &*conn, | ||||
|                 form.name.clone(), | ||||
|                 form.open_registrations, | ||||
|                 form.short_description.clone(), | ||||
| @ -125,16 +124,17 @@ pub fn update_settings( | ||||
| pub fn admin_instances( | ||||
|     _mod: Moderator, | ||||
|     page: Option<Page>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Ructe, ErrorPage> { | ||||
|     let page = page.unwrap_or_default(); | ||||
|     let instances = Instance::page(&*rockets.conn, page.limits())?; | ||||
|     let instances = Instance::page(&conn, page.limits())?; | ||||
|     Ok(render!(instance::list( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         Instance::get_local()?, | ||||
|         instances, | ||||
|         page.0, | ||||
|         Page::total(Instance::count(&*rockets.conn)? as i32) | ||||
|         Page::total(Instance::count(&conn)? as i32) | ||||
|     ))) | ||||
| } | ||||
| 
 | ||||
| @ -145,14 +145,14 @@ pub fn toggle_block( | ||||
|     id: i32, | ||||
|     intl: I18n, | ||||
| ) -> Result<Flash<Redirect>, ErrorPage> { | ||||
|     let inst = Instance::get(&*conn, id)?; | ||||
|     let inst = Instance::get(&conn, id)?; | ||||
|     let message = if inst.blocked { | ||||
|         i18n!(intl.catalog, "{} has been unblocked."; &inst.name) | ||||
|     } else { | ||||
|         i18n!(intl.catalog, "{} has been blocked."; &inst.name) | ||||
|     }; | ||||
| 
 | ||||
|     inst.toggle_block(&*conn)?; | ||||
|     inst.toggle_block(&conn)?; | ||||
|     Ok(Flash::success( | ||||
|         Redirect::to(uri!(admin_instances: page = _)), | ||||
|         message, | ||||
| @ -163,14 +163,15 @@ pub fn toggle_block( | ||||
| pub fn admin_users( | ||||
|     _mod: Moderator, | ||||
|     page: Option<Page>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Ructe, ErrorPage> { | ||||
|     let page = page.unwrap_or_default(); | ||||
|     Ok(render!(instance::users( | ||||
|         &rockets.to_context(), | ||||
|         User::get_local_page(&*rockets.conn, page.limits())?, | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         User::get_local_page(&conn, page.limits())?, | ||||
|         page.0, | ||||
|         Page::total(User::count_local(&*rockets.conn)? as i32) | ||||
|         Page::total(User::count_local(&conn)? as i32) | ||||
|     ))) | ||||
| } | ||||
| pub struct BlocklistEmailDeletion { | ||||
| @ -193,9 +194,10 @@ impl<'f> FromForm<'f> for BlocklistEmailDeletion { | ||||
| pub fn delete_email_blocklist( | ||||
|     _mod: Moderator, | ||||
|     form: Form<BlocklistEmailDeletion>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Flash<Redirect>, ErrorPage> { | ||||
|     BlocklistedEmail::delete_entries(&*rockets.conn, form.0.ids)?; | ||||
|     BlocklistedEmail::delete_entries(&conn, form.0.ids)?; | ||||
|     Ok(Flash::success( | ||||
|         Redirect::to(uri!(admin_email_blocklist: page = None)), | ||||
|         i18n!(rockets.intl.catalog, "Blocks deleted"), | ||||
| @ -206,9 +208,10 @@ pub fn delete_email_blocklist( | ||||
| pub fn add_email_blocklist( | ||||
|     _mod: Moderator, | ||||
|     form: LenientForm<NewBlocklistedEmail>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Flash<Redirect>, ErrorPage> { | ||||
|     let result = BlocklistedEmail::insert(&*rockets.conn, form.0); | ||||
|     let result = BlocklistedEmail::insert(&conn, form.0); | ||||
| 
 | ||||
|     if let Err(Error::Db(_)) = result { | ||||
|         Ok(Flash::error( | ||||
| @ -226,14 +229,15 @@ pub fn add_email_blocklist( | ||||
| pub fn admin_email_blocklist( | ||||
|     _mod: Moderator, | ||||
|     page: Option<Page>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Ructe, ErrorPage> { | ||||
|     let page = page.unwrap_or_default(); | ||||
|     Ok(render!(instance::emailblocklist( | ||||
|         &rockets.to_context(), | ||||
|         BlocklistedEmail::page(&*rockets.conn, page.limits())?, | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         BlocklistedEmail::page(&conn, page.limits())?, | ||||
|         page.0, | ||||
|         Page::total(BlocklistedEmail::count(&*rockets.conn)? as i32) | ||||
|         Page::total(BlocklistedEmail::count(&conn)? as i32) | ||||
|     ))) | ||||
| } | ||||
| 
 | ||||
| @ -303,6 +307,7 @@ impl FromStr for UserActions { | ||||
| pub fn edit_users( | ||||
|     moderator: Moderator, | ||||
|     form: LenientForm<MultiAction<UserActions>>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Flash<Redirect>, ErrorPage> { | ||||
|     // you can't change your own rights
 | ||||
| @ -329,27 +334,26 @@ pub fn edit_users( | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     let conn = &rockets.conn; | ||||
|     let worker = &*rockets.worker; | ||||
|     match form.action { | ||||
|         UserActions::Admin => { | ||||
|             for u in form.ids.clone() { | ||||
|                 User::get(conn, u)?.set_role(conn, Role::Admin)?; | ||||
|                 User::get(&conn, u)?.set_role(&conn, Role::Admin)?; | ||||
|             } | ||||
|         } | ||||
|         UserActions::Moderator => { | ||||
|             for u in form.ids.clone() { | ||||
|                 User::get(conn, u)?.set_role(conn, Role::Moderator)?; | ||||
|                 User::get(&conn, u)?.set_role(&conn, Role::Moderator)?; | ||||
|             } | ||||
|         } | ||||
|         UserActions::RevokeAdmin | UserActions::RevokeModerator => { | ||||
|             for u in form.ids.clone() { | ||||
|                 User::get(conn, u)?.set_role(conn, Role::Normal)?; | ||||
|                 User::get(&conn, u)?.set_role(&conn, Role::Normal)?; | ||||
|             } | ||||
|         } | ||||
|         UserActions::Ban => { | ||||
|             for u in form.ids.clone() { | ||||
|                 ban(u, conn, worker)?; | ||||
|                 ban(u, &conn, worker)?; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @ -387,40 +391,33 @@ fn ban(id: i32, conn: &Connection, worker: &ScheduledThreadPool) -> Result<(), E | ||||
| 
 | ||||
| #[post("/inbox", data = "<data>")] | ||||
| pub fn shared_inbox( | ||||
|     rockets: PlumeRocket, | ||||
|     conn: DbConn, | ||||
|     data: inbox::SignedJson<serde_json::Value>, | ||||
|     headers: Headers<'_>, | ||||
| ) -> Result<String, status::BadRequest<&'static str>> { | ||||
|     inbox::handle_incoming(rockets, data, headers) | ||||
|     inbox::handle_incoming(conn, data, headers) | ||||
| } | ||||
| 
 | ||||
| #[get("/remote_interact?<target>")] | ||||
| pub fn interact(rockets: PlumeRocket, user: Option<User>, target: String) -> Option<Redirect> { | ||||
|     if User::find_by_fqn(&rockets, &target).is_ok() { | ||||
| pub fn interact(conn: DbConn, user: Option<User>, target: String) -> Option<Redirect> { | ||||
|     if User::find_by_fqn(&conn, &target).is_ok() { | ||||
|         return Some(Redirect::to(uri!(super::user::details: name = target))); | ||||
|     } | ||||
| 
 | ||||
|     if let Ok(post) = Post::from_id(&rockets, &target, None, CONFIG.proxy()) { | ||||
|     if let Ok(post) = Post::from_id(&conn, &target, None, CONFIG.proxy()) { | ||||
|         return Some(Redirect::to(uri!( | ||||
|             super::posts::details: blog = post | ||||
|                 .get_blog(&rockets.conn) | ||||
|                 .expect("Can't retrieve blog") | ||||
|                 .fqn, | ||||
|             super::posts::details: blog = post.get_blog(&conn).expect("Can't retrieve blog").fqn, | ||||
|             slug = &post.slug, | ||||
|             responding_to = _ | ||||
|         ))); | ||||
|     } | ||||
| 
 | ||||
|     if let Ok(comment) = Comment::from_id(&rockets, &target, None, CONFIG.proxy()) { | ||||
|         if comment.can_see(&rockets.conn, user.as_ref()) { | ||||
|             let post = comment | ||||
|                 .get_post(&rockets.conn) | ||||
|                 .expect("Can't retrieve post"); | ||||
|     if let Ok(comment) = Comment::from_id(&conn, &target, None, CONFIG.proxy()) { | ||||
|         if comment.can_see(&conn, user.as_ref()) { | ||||
|             let post = comment.get_post(&conn).expect("Can't retrieve post"); | ||||
|             return Some(Redirect::to(uri!( | ||||
|                 super::posts::details: blog = post | ||||
|                     .get_blog(&rockets.conn) | ||||
|                     .expect("Can't retrieve blog") | ||||
|                     .fqn, | ||||
|                 super::posts::details: blog = | ||||
|                     post.get_blog(&conn).expect("Can't retrieve blog").fqn, | ||||
|                 slug = &post.slug, | ||||
|                 responding_to = comment.id | ||||
|             ))); | ||||
| @ -450,10 +447,10 @@ pub fn nodeinfo(conn: DbConn, version: String) -> Result<Json<serde_json::Value> | ||||
|         "openRegistrations": local_inst.open_registrations, | ||||
|         "usage": { | ||||
|             "users": { | ||||
|                 "total": User::count_local(&*conn)? | ||||
|                 "total": User::count_local(&conn)? | ||||
|             }, | ||||
|             "localPosts": Post::count_local(&*conn)?, | ||||
|             "localComments": Comment::count_local(&*conn)? | ||||
|             "localPosts": Post::count_local(&conn)?, | ||||
|             "localComments": Comment::count_local(&conn)? | ||||
|         }, | ||||
|         "metadata": { | ||||
|             "nodeName": local_inst.name, | ||||
| @ -469,21 +466,20 @@ pub fn nodeinfo(conn: DbConn, version: String) -> Result<Json<serde_json::Value> | ||||
| } | ||||
| 
 | ||||
| #[get("/about")] | ||||
| pub fn about(rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
|     let conn = &*rockets.conn; | ||||
| pub fn about(conn: DbConn, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
|     Ok(render!(instance::about( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         Instance::get_local()?, | ||||
|         Instance::get_local()?.main_admin(conn)?, | ||||
|         User::count_local(conn)?, | ||||
|         Post::count_local(conn)?, | ||||
|         Instance::count(conn)? - 1 | ||||
|         Instance::get_local()?.main_admin(&conn)?, | ||||
|         User::count_local(&conn)?, | ||||
|         Post::count_local(&conn)?, | ||||
|         Instance::count(&conn)? - 1 | ||||
|     ))) | ||||
| } | ||||
| 
 | ||||
| #[get("/privacy")] | ||||
| pub fn privacy(rockets: PlumeRocket) -> Ructe { | ||||
|     render!(instance::privacy(&rockets.to_context())) | ||||
| pub fn privacy(conn: DbConn, rockets: PlumeRocket) -> Ructe { | ||||
|     render!(instance::privacy(&(&conn, &rockets).to_context())) | ||||
| } | ||||
| 
 | ||||
| #[get("/manifest.json")] | ||||
|  | ||||
| @ -5,8 +5,8 @@ use crate::routes::errors::ErrorPage; | ||||
| use plume_common::activity_pub::broadcast; | ||||
| use plume_common::utils; | ||||
| use plume_models::{ | ||||
|     blogs::Blog, inbox::inbox, likes, posts::Post, timeline::*, users::User, Error, PlumeRocket, | ||||
|     CONFIG, | ||||
|     blogs::Blog, db_conn::DbConn, inbox::inbox, likes, posts::Post, timeline::*, users::User, | ||||
|     Error, PlumeRocket, CONFIG, | ||||
| }; | ||||
| 
 | ||||
| #[post("/~/<blog>/<slug>/like")] | ||||
| @ -14,17 +14,17 @@ pub fn create( | ||||
|     blog: String, | ||||
|     slug: String, | ||||
|     user: User, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Redirect, ErrorPage> { | ||||
|     let conn = &*rockets.conn; | ||||
|     let b = Blog::find_by_fqn(&rockets, &blog)?; | ||||
|     let post = Post::find_by_slug(&*conn, &slug, b.id)?; | ||||
|     let b = Blog::find_by_fqn(&conn, &blog)?; | ||||
|     let post = Post::find_by_slug(&conn, &slug, b.id)?; | ||||
| 
 | ||||
|     if !user.has_liked(&*conn, &post)? { | ||||
|         let like = likes::Like::insert(&*conn, likes::NewLike::new(&post, &user))?; | ||||
|         like.notify(&*conn)?; | ||||
| 
 | ||||
|         Timeline::add_to_all_timelines(&rockets, &post, Kind::Like(&user))?; | ||||
|         Timeline::add_to_all_timelines(&conn, &post, Kind::Like(&user))?; | ||||
| 
 | ||||
|         let dest = User::one_by_instance(&*conn)?; | ||||
|         let act = like.to_activity(&*conn)?; | ||||
| @ -32,14 +32,14 @@ pub fn create( | ||||
|             .worker | ||||
|             .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); | ||||
|     } else { | ||||
|         let like = likes::Like::find_by_user_on_post(&*conn, user.id, post.id)?; | ||||
|         let delete_act = like.build_undo(&*conn)?; | ||||
|         let like = likes::Like::find_by_user_on_post(&conn, user.id, post.id)?; | ||||
|         let delete_act = like.build_undo(&conn)?; | ||||
|         inbox( | ||||
|             &rockets, | ||||
|             &conn, | ||||
|             serde_json::to_value(&delete_act).map_err(Error::from)?, | ||||
|         )?; | ||||
| 
 | ||||
|         let dest = User::one_by_instance(&*conn)?; | ||||
|         let dest = User::one_by_instance(&conn)?; | ||||
|         rockets | ||||
|             .worker | ||||
|             .execute(move || broadcast(&user, delete_act, dest, CONFIG.proxy().cloned())); | ||||
|  | ||||
| @ -15,20 +15,25 @@ use rocket_i18n::I18n; | ||||
| use std::fs; | ||||
| 
 | ||||
| #[get("/medias?<page>")] | ||||
| pub fn list(user: User, page: Option<Page>, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
| pub fn list( | ||||
|     user: User, | ||||
|     page: Option<Page>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Ructe, ErrorPage> { | ||||
|     let page = page.unwrap_or_default(); | ||||
|     let medias = Media::page_for_user(&*rockets.conn, &user, page.limits())?; | ||||
|     let medias = Media::page_for_user(&conn, &user, page.limits())?; | ||||
|     Ok(render!(medias::index( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         medias, | ||||
|         page.0, | ||||
|         Page::total(Media::count_for_user(&*rockets.conn, &user)? as i32) | ||||
|         Page::total(Media::count_for_user(&conn, &user)? as i32) | ||||
|     ))) | ||||
| } | ||||
| 
 | ||||
| #[get("/medias/new")] | ||||
| pub fn new(_user: User, rockets: PlumeRocket) -> Ructe { | ||||
|     render!(medias::new(&rockets.to_context())) | ||||
| pub fn new(_user: User, conn: DbConn, rockets: PlumeRocket) -> Ructe { | ||||
|     render!(medias::new(&(&conn, &rockets).to_context())) | ||||
| } | ||||
| 
 | ||||
| #[post("/medias/new", data = "<data>")] | ||||
| @ -95,7 +100,7 @@ pub fn upload( | ||||
|             .map(|cw| cw.is_empty()) | ||||
|             .unwrap_or(false); | ||||
|         let media = Media::insert( | ||||
|             &*conn, | ||||
|             &conn, | ||||
|             NewMedia { | ||||
|                 file_path: dest, | ||||
|                 alt_text: read(&fields["alt"][0].data)?, | ||||
| @ -126,10 +131,18 @@ fn read(data: &SavedData) -> Result<String, status::BadRequest<&'static str>> { | ||||
| } | ||||
| 
 | ||||
| #[get("/medias/<id>")] | ||||
| pub fn details(id: i32, user: User, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
|     let media = Media::get(&*rockets.conn, id)?; | ||||
| pub fn details( | ||||
|     id: i32, | ||||
|     user: User, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Ructe, ErrorPage> { | ||||
|     let media = Media::get(&conn, id)?; | ||||
|     if media.owner_id == user.id { | ||||
|         Ok(render!(medias::details(&rockets.to_context(), media))) | ||||
|         Ok(render!(medias::details( | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             media | ||||
|         ))) | ||||
|     } else { | ||||
|         Err(Error::Unauthorized.into()) | ||||
|     } | ||||
|  | ||||
| @ -4,20 +4,21 @@ use rocket_i18n::I18n; | ||||
| use crate::routes::{errors::ErrorPage, Page}; | ||||
| use crate::template_utils::{IntoContext, Ructe}; | ||||
| use plume_common::utils; | ||||
| use plume_models::{notifications::Notification, users::User, PlumeRocket}; | ||||
| use plume_models::{db_conn::DbConn, notifications::Notification, users::User, PlumeRocket}; | ||||
| 
 | ||||
| #[get("/notifications?<page>")] | ||||
| pub fn notifications( | ||||
|     user: User, | ||||
|     page: Option<Page>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Ructe, ErrorPage> { | ||||
|     let page = page.unwrap_or_default(); | ||||
|     Ok(render!(notifications::index( | ||||
|         &rockets.to_context(), | ||||
|         Notification::page_for_user(&*rockets.conn, &user, page.limits())?, | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         Notification::page_for_user(&conn, &user, page.limits())?, | ||||
|         page.0, | ||||
|         Page::total(Notification::count_for_user(&*rockets.conn, &user)? as i32) | ||||
|         Page::total(Notification::count_for_user(&conn, &user)? as i32) | ||||
|     ))) | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -20,6 +20,7 @@ use plume_common::utils; | ||||
| use plume_models::{ | ||||
|     blogs::*, | ||||
|     comments::{Comment, CommentTree}, | ||||
|     db_conn::DbConn, | ||||
|     inbox::inbox, | ||||
|     instance::Instance, | ||||
|     medias::Media, | ||||
| @ -38,42 +39,42 @@ pub fn details( | ||||
|     blog: String, | ||||
|     slug: String, | ||||
|     responding_to: Option<i32>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Ructe, ErrorPage> { | ||||
|     let conn = &*rockets.conn; | ||||
|     let user = rockets.user.clone(); | ||||
|     let blog = Blog::find_by_fqn(&rockets, &blog)?; | ||||
|     let post = Post::find_by_slug(&*conn, &slug, blog.id)?; | ||||
|     let blog = Blog::find_by_fqn(&conn, &blog)?; | ||||
|     let post = Post::find_by_slug(&conn, &slug, blog.id)?; | ||||
|     if !(post.published | ||||
|         || post | ||||
|             .get_authors(&*conn)? | ||||
|             .get_authors(&conn)? | ||||
|             .into_iter() | ||||
|             .any(|a| a.id == user.clone().map(|u| u.id).unwrap_or(0))) | ||||
|     { | ||||
|         return Ok(render!(errors::not_authorized( | ||||
|             &rockets.to_context(), | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             i18n!(rockets.intl.catalog, "This post isn't published yet.") | ||||
|         ))); | ||||
|     } | ||||
| 
 | ||||
|     let comments = CommentTree::from_post(&*conn, &post, user.as_ref())?; | ||||
|     let comments = CommentTree::from_post(&conn, &post, user.as_ref())?; | ||||
| 
 | ||||
|     let previous = responding_to.and_then(|r| Comment::get(&*conn, r).ok()); | ||||
|     let previous = responding_to.and_then(|r| Comment::get(&conn, r).ok()); | ||||
| 
 | ||||
|     Ok(render!(posts::details( | ||||
|             &rockets.to_context(), | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             post.clone(), | ||||
|             blog, | ||||
|             &NewCommentForm { | ||||
|                 warning: previous.clone().map(|p| p.spoiler_text).unwrap_or_default(), | ||||
|                 content: previous.clone().and_then(|p| Some(format!( | ||||
|                     "@{} {}", | ||||
|                     p.get_author(&*conn).ok()?.fqn, | ||||
|                     Mention::list_for_comment(&*conn, p.id).ok()? | ||||
|                     p.get_author(&conn).ok()?.fqn, | ||||
|                     Mention::list_for_comment(&conn, p.id).ok()? | ||||
|                         .into_iter() | ||||
|                         .filter_map(|m| { | ||||
|                             let user = user.clone(); | ||||
|                             if let Ok(mentioned) = m.get_mentioned(&*conn) { | ||||
|                             if let Ok(mentioned) = m.get_mentioned(&conn) { | ||||
|                                 if user.is_none() || mentioned.id != user.expect("posts::details_response: user error while listing mentions").id { | ||||
|                                     Some(format!("@{}", mentioned.fqn)) | ||||
|                                 } else { | ||||
| @ -87,15 +88,15 @@ pub fn details( | ||||
|                 ..NewCommentForm::default() | ||||
|             }, | ||||
|             ValidationErrors::default(), | ||||
|             Tag::for_post(&*conn, post.id)?, | ||||
|             Tag::for_post(&conn, post.id)?, | ||||
|             comments, | ||||
|             previous, | ||||
|             post.count_likes(&*conn)?, | ||||
|             post.count_reshares(&*conn)?, | ||||
|             user.clone().and_then(|u| u.has_liked(&*conn, &post).ok()).unwrap_or(false), | ||||
|             user.clone().and_then(|u| u.has_reshared(&*conn, &post).ok()).unwrap_or(false), | ||||
|             user.and_then(|u| u.is_following(&*conn, post.get_authors(&*conn).ok()?[0].id).ok()).unwrap_or(false), | ||||
|             post.get_authors(&*conn)?[0].clone() | ||||
|             post.count_likes(&conn)?, | ||||
|             post.count_reshares(&conn)?, | ||||
|             user.clone().and_then(|u| u.has_liked(&conn, &post).ok()).unwrap_or(false), | ||||
|             user.clone().and_then(|u| u.has_reshared(&conn, &post).ok()).unwrap_or(false), | ||||
|             user.and_then(|u| u.is_following(&conn, post.get_authors(&conn).ok()?[0].id).ok()).unwrap_or(false), | ||||
|             post.get_authors(&conn)?[0].clone() | ||||
|         ))) | ||||
| } | ||||
| 
 | ||||
| @ -104,14 +105,13 @@ pub fn activity_details( | ||||
|     blog: String, | ||||
|     slug: String, | ||||
|     _ap: ApRequest, | ||||
|     rockets: PlumeRocket, | ||||
|     conn: DbConn, | ||||
| ) -> Result<ActivityStream<LicensedArticle>, Option<String>> { | ||||
|     let conn = &*rockets.conn; | ||||
|     let blog = Blog::find_by_fqn(&rockets, &blog).map_err(|_| None)?; | ||||
|     let post = Post::find_by_slug(&*conn, &slug, blog.id).map_err(|_| None)?; | ||||
|     let blog = Blog::find_by_fqn(&conn, &blog).map_err(|_| None)?; | ||||
|     let post = Post::find_by_slug(&conn, &slug, blog.id).map_err(|_| None)?; | ||||
|     if post.published { | ||||
|         Ok(ActivityStream::new( | ||||
|             post.to_activity(&*conn) | ||||
|             post.to_activity(&conn) | ||||
|                 .map_err(|_| String::from("Post serialization error"))?, | ||||
|         )) | ||||
|     } else { | ||||
| @ -131,22 +131,26 @@ pub fn new_auth(blog: String, i18n: I18n) -> Flash<Redirect> { | ||||
| } | ||||
| 
 | ||||
| #[get("/~/<blog>/new", rank = 1)] | ||||
| pub fn new(blog: String, cl: ContentLen, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
|     let conn = &*rockets.conn; | ||||
|     let b = Blog::find_by_fqn(&rockets, &blog)?; | ||||
| pub fn new( | ||||
|     blog: String, | ||||
|     cl: ContentLen, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Ructe, ErrorPage> { | ||||
|     let b = Blog::find_by_fqn(&conn, &blog)?; | ||||
|     let user = rockets.user.clone().unwrap(); | ||||
| 
 | ||||
|     if !user.is_author_in(&*conn, &b)? { | ||||
|     if !user.is_author_in(&conn, &b)? { | ||||
|         // TODO actually return 403 error code
 | ||||
|         return Ok(render!(errors::not_authorized( | ||||
|             &rockets.to_context(), | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             i18n!(rockets.intl.catalog, "You are not an author of this blog.") | ||||
|         ))); | ||||
|     } | ||||
| 
 | ||||
|     let medias = Media::for_user(&*conn, user.id)?; | ||||
|     let medias = Media::for_user(&conn, user.id)?; | ||||
|     Ok(render!(posts::new( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         i18n!(rockets.intl.catalog, "New post"), | ||||
|         b, | ||||
|         false, | ||||
| @ -167,17 +171,17 @@ pub fn edit( | ||||
|     blog: String, | ||||
|     slug: String, | ||||
|     cl: ContentLen, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Ructe, ErrorPage> { | ||||
|     let conn = &*rockets.conn; | ||||
|     let intl = &rockets.intl.catalog; | ||||
|     let b = Blog::find_by_fqn(&rockets, &blog)?; | ||||
|     let post = Post::find_by_slug(&*conn, &slug, b.id)?; | ||||
|     let b = Blog::find_by_fqn(&conn, &blog)?; | ||||
|     let post = Post::find_by_slug(&conn, &slug, b.id)?; | ||||
|     let user = rockets.user.clone().unwrap(); | ||||
| 
 | ||||
|     if !user.is_author_in(&*conn, &b)? { | ||||
|     if !user.is_author_in(&conn, &b)? { | ||||
|         return Ok(render!(errors::not_authorized( | ||||
|             &rockets.to_context(), | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             i18n!(intl, "You are not an author of this blog.") | ||||
|         ))); | ||||
|     } | ||||
| @ -188,10 +192,10 @@ pub fn edit( | ||||
|         post.content.get().clone() // fallback to HTML if the markdown was not stored
 | ||||
|     }; | ||||
| 
 | ||||
|     let medias = Media::for_user(&*conn, user.id)?; | ||||
|     let medias = Media::for_user(&conn, user.id)?; | ||||
|     let title = post.title.clone(); | ||||
|     Ok(render!(posts::new( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         i18n!(intl, "Edit {0}"; &title), | ||||
|         b, | ||||
|         true, | ||||
| @ -199,7 +203,7 @@ pub fn edit( | ||||
|             title: post.title.clone(), | ||||
|             subtitle: post.subtitle.clone(), | ||||
|             content: source, | ||||
|             tags: Tag::for_post(&*conn, post.id)? | ||||
|             tags: Tag::for_post(&conn, post.id)? | ||||
|                 .into_iter() | ||||
|                 .filter_map(|t| if !t.is_hashtag { Some(t.tag) } else { None }) | ||||
|                 .collect::<Vec<String>>() | ||||
| @ -222,12 +226,12 @@ pub fn update( | ||||
|     slug: String, | ||||
|     cl: ContentLen, | ||||
|     form: LenientForm<NewPostForm>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> RespondOrRedirect { | ||||
|     let conn = &*rockets.conn; | ||||
|     let b = Blog::find_by_fqn(&rockets, &blog).expect("post::update: blog error"); | ||||
|     let b = Blog::find_by_fqn(&conn, &blog).expect("post::update: blog error"); | ||||
|     let mut post = | ||||
|         Post::find_by_slug(&*conn, &slug, b.id).expect("post::update: find by slug error"); | ||||
|         Post::find_by_slug(&conn, &slug, b.id).expect("post::update: find by slug error"); | ||||
|     let user = rockets.user.clone().unwrap(); | ||||
|     let intl = &rockets.intl.catalog; | ||||
| 
 | ||||
| @ -242,7 +246,7 @@ pub fn update( | ||||
|         Err(e) => e, | ||||
|     }; | ||||
| 
 | ||||
|     if new_slug != slug && Post::find_by_slug(&*conn, &new_slug, b.id).is_ok() { | ||||
|     if new_slug != slug && Post::find_by_slug(&conn, &new_slug, b.id).is_ok() { | ||||
|         errors.add( | ||||
|             "title", | ||||
|             ValidationError { | ||||
| @ -255,7 +259,7 @@ pub fn update( | ||||
| 
 | ||||
|     if errors.is_empty() { | ||||
|         if !user | ||||
|             .is_author_in(&*conn, &b) | ||||
|             .is_author_in(&conn, &b) | ||||
|             .expect("posts::update: is author in error") | ||||
|         { | ||||
|             // actually it's not "Ok"…
 | ||||
| @ -298,14 +302,14 @@ pub fn update( | ||||
|             post.source = form.content.clone(); | ||||
|             post.license = form.license.clone(); | ||||
|             post.cover_id = form.cover; | ||||
|             post.update(&*conn).expect("post::update: update error"); | ||||
|             post.update(&conn).expect("post::update: update error"); | ||||
| 
 | ||||
|             if post.published { | ||||
|                 post.update_mentions( | ||||
|                     &conn, | ||||
|                     mentions | ||||
|                         .into_iter() | ||||
|                         .filter_map(|m| Mention::build_activity(&rockets, &m).ok()) | ||||
|                         .filter_map(|m| Mention::build_activity(&conn, &m).ok()) | ||||
|                         .collect(), | ||||
|                 ) | ||||
|                 .expect("post::update: mentions error"); | ||||
| @ -337,17 +341,17 @@ pub fn update( | ||||
|                     let act = post | ||||
|                         .create_activity(&conn) | ||||
|                         .expect("post::update: act error"); | ||||
|                     let dest = User::one_by_instance(&*conn).expect("post::update: dest error"); | ||||
|                     let dest = User::one_by_instance(&conn).expect("post::update: dest error"); | ||||
|                     rockets | ||||
|                         .worker | ||||
|                         .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); | ||||
| 
 | ||||
|                     Timeline::add_to_all_timelines(&rockets, &post, Kind::Original).ok(); | ||||
|                     Timeline::add_to_all_timelines(&conn, &post, Kind::Original).ok(); | ||||
|                 } else { | ||||
|                     let act = post | ||||
|                         .update_activity(&*conn) | ||||
|                         .update_activity(&conn) | ||||
|                         .expect("post::update: act error"); | ||||
|                     let dest = User::one_by_instance(&*conn).expect("posts::update: dest error"); | ||||
|                     let dest = User::one_by_instance(&conn).expect("posts::update: dest error"); | ||||
|                     rockets | ||||
|                         .worker | ||||
|                         .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); | ||||
| @ -365,9 +369,9 @@ pub fn update( | ||||
|             .into() | ||||
|         } | ||||
|     } else { | ||||
|         let medias = Media::for_user(&*conn, user.id).expect("posts:update: medias error"); | ||||
|         let medias = Media::for_user(&conn, user.id).expect("posts:update: medias error"); | ||||
|         render!(posts::new( | ||||
|             &rockets.to_context(), | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             i18n!(intl, "Edit {0}"; &form.title), | ||||
|             b, | ||||
|             true, | ||||
| @ -410,10 +414,10 @@ pub fn create( | ||||
|     blog_name: String, | ||||
|     form: LenientForm<NewPostForm>, | ||||
|     cl: ContentLen, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<RespondOrRedirect, ErrorPage> { | ||||
|     let conn = &*rockets.conn; | ||||
|     let blog = Blog::find_by_fqn(&rockets, &blog_name).expect("post::create: blog error"); | ||||
|     let blog = Blog::find_by_fqn(&conn, &blog_name).expect("post::create: blog error"); | ||||
|     let slug = form.title.to_string().to_kebab_case(); | ||||
|     let user = rockets.user.clone().unwrap(); | ||||
| 
 | ||||
| @ -421,7 +425,7 @@ pub fn create( | ||||
|         Ok(_) => ValidationErrors::new(), | ||||
|         Err(e) => e, | ||||
|     }; | ||||
|     if Post::find_by_slug(&*conn, &slug, blog.id).is_ok() { | ||||
|     if Post::find_by_slug(&conn, &slug, blog.id).is_ok() { | ||||
|         errors.add( | ||||
|             "title", | ||||
|             ValidationError { | ||||
| @ -434,7 +438,7 @@ pub fn create( | ||||
| 
 | ||||
|     if errors.is_empty() { | ||||
|         if !user | ||||
|             .is_author_in(&*conn, &blog) | ||||
|             .is_author_in(&conn, &blog) | ||||
|             .expect("post::create: is author in error") | ||||
|         { | ||||
|             // actually it's not "Ok"…
 | ||||
| @ -466,7 +470,7 @@ pub fn create( | ||||
|         ); | ||||
| 
 | ||||
|         let post = Post::insert( | ||||
|             &*conn, | ||||
|             &conn, | ||||
|             NewPost { | ||||
|                 blog_id: blog.id, | ||||
|                 slug: slug.to_string(), | ||||
| @ -484,7 +488,7 @@ pub fn create( | ||||
|         .expect("post::create: post save error"); | ||||
| 
 | ||||
|         PostAuthor::insert( | ||||
|             &*conn, | ||||
|             &conn, | ||||
|             NewPostAuthor { | ||||
|                 post_id: post.id, | ||||
|                 author_id: user.id, | ||||
| @ -500,7 +504,7 @@ pub fn create( | ||||
|             .collect::<HashSet<_>>(); | ||||
|         for tag in tags { | ||||
|             Tag::insert( | ||||
|                 &*conn, | ||||
|                 &conn, | ||||
|                 NewTag { | ||||
|                     tag: tag.to_string(), | ||||
|                     is_hashtag: false, | ||||
| @ -511,7 +515,7 @@ pub fn create( | ||||
|         } | ||||
|         for hashtag in hashtags { | ||||
|             Tag::insert( | ||||
|                 &*conn, | ||||
|                 &conn, | ||||
|                 NewTag { | ||||
|                     tag: hashtag, | ||||
|                     is_hashtag: true, | ||||
| @ -524,9 +528,8 @@ pub fn create( | ||||
|         if post.published { | ||||
|             for m in mentions { | ||||
|                 Mention::from_activity( | ||||
|                     &*conn, | ||||
|                     &Mention::build_activity(&rockets, &m) | ||||
|                         .expect("post::create: mention build error"), | ||||
|                     &conn, | ||||
|                     &Mention::build_activity(&conn, &m).expect("post::create: mention build error"), | ||||
|                     post.id, | ||||
|                     true, | ||||
|                     true, | ||||
| @ -535,13 +538,13 @@ pub fn create( | ||||
|             } | ||||
| 
 | ||||
|             let act = post | ||||
|                 .create_activity(&*conn) | ||||
|                 .create_activity(&conn) | ||||
|                 .expect("posts::create: activity error"); | ||||
|             let dest = User::one_by_instance(&*conn).expect("posts::create: dest error"); | ||||
|             let dest = User::one_by_instance(&conn).expect("posts::create: dest error"); | ||||
|             let worker = &rockets.worker; | ||||
|             worker.execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); | ||||
| 
 | ||||
|             Timeline::add_to_all_timelines(&rockets, &post, Kind::Original)?; | ||||
|             Timeline::add_to_all_timelines(&conn, &post, Kind::Original)?; | ||||
|         } | ||||
| 
 | ||||
|         Ok(Flash::success( | ||||
| @ -554,9 +557,9 @@ pub fn create( | ||||
|         ) | ||||
|         .into()) | ||||
|     } else { | ||||
|         let medias = Media::for_user(&*conn, user.id).expect("posts::create: medias error"); | ||||
|         let medias = Media::for_user(&conn, user.id).expect("posts::create: medias error"); | ||||
|         Ok(render!(posts::new( | ||||
|             &rockets.to_context(), | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             i18n!(rockets.intl.catalog, "New article"), | ||||
|             blog, | ||||
|             false, | ||||
| @ -575,16 +578,17 @@ pub fn create( | ||||
| pub fn delete( | ||||
|     blog_name: String, | ||||
|     slug: String, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
|     intl: I18n, | ||||
| ) -> Result<Flash<Redirect>, ErrorPage> { | ||||
|     let user = rockets.user.clone().unwrap(); | ||||
|     let post = Blog::find_by_fqn(&rockets, &blog_name) | ||||
|         .and_then(|blog| Post::find_by_slug(&*rockets.conn, &slug, blog.id)); | ||||
|     let post = Blog::find_by_fqn(&conn, &blog_name) | ||||
|         .and_then(|blog| Post::find_by_slug(&conn, &slug, blog.id)); | ||||
| 
 | ||||
|     if let Ok(post) = post { | ||||
|         if !post | ||||
|             .get_authors(&*rockets.conn)? | ||||
|             .get_authors(&conn)? | ||||
|             .into_iter() | ||||
|             .any(|a| a.id == user.id) | ||||
|         { | ||||
| @ -598,10 +602,10 @@ pub fn delete( | ||||
|             )); | ||||
|         } | ||||
| 
 | ||||
|         let dest = User::one_by_instance(&*rockets.conn)?; | ||||
|         let delete_activity = post.build_delete(&*rockets.conn)?; | ||||
|         let dest = User::one_by_instance(&conn)?; | ||||
|         let delete_activity = post.build_delete(&conn)?; | ||||
|         inbox( | ||||
|             &rockets, | ||||
|             &conn, | ||||
|             serde_json::to_value(&delete_activity).map_err(Error::from)?, | ||||
|         )?; | ||||
| 
 | ||||
| @ -609,11 +613,10 @@ pub fn delete( | ||||
|         rockets | ||||
|             .worker | ||||
|             .execute(move || broadcast(&user_c, delete_activity, dest, CONFIG.proxy().cloned())); | ||||
|         let conn = rockets.conn; | ||||
|         rockets | ||||
|             .worker | ||||
|             .execute_after(Duration::from_secs(10 * 60), move || { | ||||
|                 user.rotate_keypair(&*conn) | ||||
|                 user.rotate_keypair(&conn) | ||||
|                     .expect("Failed to rotate keypair"); | ||||
|             }); | ||||
| 
 | ||||
| @ -630,14 +633,15 @@ pub fn delete( | ||||
| 
 | ||||
| #[get("/~/<blog_name>/<slug>/remote_interact")] | ||||
| pub fn remote_interact( | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
|     blog_name: String, | ||||
|     slug: String, | ||||
| ) -> Result<Ructe, ErrorPage> { | ||||
|     let target = Blog::find_by_fqn(&rockets, &blog_name) | ||||
|         .and_then(|blog| Post::find_by_slug(&rockets.conn, &slug, blog.id))?; | ||||
|     let target = Blog::find_by_fqn(&conn, &blog_name) | ||||
|         .and_then(|blog| Post::find_by_slug(&conn, &slug, blog.id))?; | ||||
|     Ok(render!(posts::remote_interact( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         target, | ||||
|         super::session::LoginForm::default(), | ||||
|         ValidationErrors::default(), | ||||
| @ -648,13 +652,14 @@ pub fn remote_interact( | ||||
| 
 | ||||
| #[post("/~/<blog_name>/<slug>/remote_interact", data = "<remote>")] | ||||
| pub fn remote_interact_post( | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
|     blog_name: String, | ||||
|     slug: String, | ||||
|     remote: LenientForm<RemoteForm>, | ||||
| ) -> Result<RespondOrRedirect, ErrorPage> { | ||||
|     let target = Blog::find_by_fqn(&rockets, &blog_name) | ||||
|         .and_then(|blog| Post::find_by_slug(&rockets.conn, &slug, blog.id))?; | ||||
|     let target = Blog::find_by_fqn(&conn, &blog_name) | ||||
|         .and_then(|blog| Post::find_by_slug(&conn, &slug, blog.id))?; | ||||
|     if let Some(uri) = User::fetch_remote_interact_uri(&remote.remote) | ||||
|         .ok() | ||||
|         .map(|uri| uri.replace("{uri}", &Uri::percent_encode(&target.ap_url))) | ||||
| @ -669,7 +674,7 @@ pub fn remote_interact_post( | ||||
|         }); | ||||
|         //could not get your remote url?
 | ||||
|         Ok(render!(posts::remote_interact( | ||||
|             &rockets.to_context(), | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             target, | ||||
|             super::session::LoginForm::default(), | ||||
|             ValidationErrors::default(), | ||||
|  | ||||
| @ -5,8 +5,8 @@ use crate::routes::errors::ErrorPage; | ||||
| use plume_common::activity_pub::broadcast; | ||||
| use plume_common::utils; | ||||
| use plume_models::{ | ||||
|     blogs::Blog, inbox::inbox, posts::Post, reshares::*, timeline::*, users::User, Error, | ||||
|     PlumeRocket, CONFIG, | ||||
|     blogs::Blog, db_conn::DbConn, inbox::inbox, posts::Post, reshares::*, timeline::*, users::User, | ||||
|     Error, PlumeRocket, CONFIG, | ||||
| }; | ||||
| 
 | ||||
| #[post("/~/<blog>/<slug>/reshare")] | ||||
| @ -14,32 +14,32 @@ pub fn create( | ||||
|     blog: String, | ||||
|     slug: String, | ||||
|     user: User, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Redirect, ErrorPage> { | ||||
|     let conn = &*rockets.conn; | ||||
|     let b = Blog::find_by_fqn(&rockets, &blog)?; | ||||
|     let post = Post::find_by_slug(&*conn, &slug, b.id)?; | ||||
|     let b = Blog::find_by_fqn(&conn, &blog)?; | ||||
|     let post = Post::find_by_slug(&conn, &slug, b.id)?; | ||||
| 
 | ||||
|     if !user.has_reshared(&*conn, &post)? { | ||||
|         let reshare = Reshare::insert(&*conn, NewReshare::new(&post, &user))?; | ||||
|         reshare.notify(&*conn)?; | ||||
|     if !user.has_reshared(&conn, &post)? { | ||||
|         let reshare = Reshare::insert(&conn, NewReshare::new(&post, &user))?; | ||||
|         reshare.notify(&conn)?; | ||||
| 
 | ||||
|         Timeline::add_to_all_timelines(&rockets, &post, Kind::Reshare(&user))?; | ||||
|         Timeline::add_to_all_timelines(&conn, &post, Kind::Reshare(&user))?; | ||||
| 
 | ||||
|         let dest = User::one_by_instance(&*conn)?; | ||||
|         let act = reshare.to_activity(&*conn)?; | ||||
|         let dest = User::one_by_instance(&conn)?; | ||||
|         let act = reshare.to_activity(&conn)?; | ||||
|         rockets | ||||
|             .worker | ||||
|             .execute(move || broadcast(&user, act, dest, CONFIG.proxy().cloned())); | ||||
|     } else { | ||||
|         let reshare = Reshare::find_by_user_on_post(&*conn, user.id, post.id)?; | ||||
|         let delete_act = reshare.build_undo(&*conn)?; | ||||
|         let reshare = Reshare::find_by_user_on_post(&conn, user.id, post.id)?; | ||||
|         let delete_act = reshare.build_undo(&conn)?; | ||||
|         inbox( | ||||
|             &rockets, | ||||
|             &conn, | ||||
|             serde_json::to_value(&delete_act).map_err(Error::from)?, | ||||
|         )?; | ||||
| 
 | ||||
|         let dest = User::one_by_instance(&*conn)?; | ||||
|         let dest = User::one_by_instance(&conn)?; | ||||
|         rockets | ||||
|             .worker | ||||
|             .execute(move || broadcast(&user, delete_act, dest, CONFIG.proxy().cloned())); | ||||
|  | ||||
| @ -3,7 +3,7 @@ use rocket::request::Form; | ||||
| 
 | ||||
| use crate::routes::Page; | ||||
| use crate::template_utils::{IntoContext, Ructe}; | ||||
| use plume_models::{search::Query, PlumeRocket}; | ||||
| use plume_models::{db_conn::DbConn, search::Query, PlumeRocket}; | ||||
| use std::str::FromStr; | ||||
| 
 | ||||
| #[derive(Default, FromForm)] | ||||
| @ -50,8 +50,7 @@ macro_rules! param_to_query { | ||||
| } | ||||
| 
 | ||||
| #[get("/search?<query..>")] | ||||
| pub fn search(query: Option<Form<SearchQuery>>, rockets: PlumeRocket) -> Ructe { | ||||
|     let conn = &*rockets.conn; | ||||
| pub fn search(query: Option<Form<SearchQuery>>, conn: DbConn, rockets: PlumeRocket) -> Ructe { | ||||
|     let query = query.map(Form::into_inner).unwrap_or_default(); | ||||
|     let page = query.page.unwrap_or_default(); | ||||
|     let mut parsed_query = | ||||
| @ -65,7 +64,7 @@ pub fn search(query: Option<Form<SearchQuery>>, rockets: PlumeRocket) -> Ructe { | ||||
| 
 | ||||
|     if str_query.is_empty() { | ||||
|         render!(search::index( | ||||
|             &rockets.to_context(), | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             &format!("{}", Utc::today().format("%Y-%m-d")) | ||||
|         )) | ||||
|     } else { | ||||
| @ -74,7 +73,7 @@ pub fn search(query: Option<Form<SearchQuery>>, rockets: PlumeRocket) -> Ructe { | ||||
|             .search_document(&conn, parsed_query, page.limits()); | ||||
|         let next_page = if res.is_empty() { 0 } else { page.0 + 1 }; | ||||
|         render!(search::result( | ||||
|             &rockets.to_context(), | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             &str_query, | ||||
|             res, | ||||
|             page.0, | ||||
|  | ||||
| @ -19,15 +19,16 @@ use validator::{Validate, ValidationError, ValidationErrors}; | ||||
| use crate::mail::{build_mail, Mailer}; | ||||
| use crate::template_utils::{IntoContext, Ructe}; | ||||
| use plume_models::{ | ||||
|     db_conn::DbConn, | ||||
|     password_reset_requests::*, | ||||
|     users::{User, AUTH_COOKIE}, | ||||
|     Error, PlumeRocket, CONFIG, | ||||
| }; | ||||
| 
 | ||||
| #[get("/login?<m>")] | ||||
| pub fn new(m: Option<String>, rockets: PlumeRocket) -> Ructe { | ||||
| pub fn new(m: Option<String>, conn: DbConn, rockets: PlumeRocket) -> Ructe { | ||||
|     render!(session::login( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         m, | ||||
|         &LoginForm::default(), | ||||
|         ValidationErrors::default() | ||||
| @ -46,21 +47,27 @@ pub struct LoginForm { | ||||
| pub fn create( | ||||
|     form: LenientForm<LoginForm>, | ||||
|     mut cookies: Cookies<'_>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> RespondOrRedirect { | ||||
|     let conn = &*rockets.conn; | ||||
|     let mut errors = match form.validate() { | ||||
|         Ok(_) => ValidationErrors::new(), | ||||
|         Err(e) => e, | ||||
|     }; | ||||
|     let user = User::login(conn, &form.email_or_name, &form.password); | ||||
|     let user = User::login(&conn, &form.email_or_name, &form.password); | ||||
|     let user_id = if let Ok(user) = user { | ||||
|         user.id.to_string() | ||||
|     } else { | ||||
|         let mut err = ValidationError::new("invalid_login"); | ||||
|         err.message = Some(Cow::from("Invalid username, or password")); | ||||
|         errors.add("email_or_name", err); | ||||
|         return render!(session::login(&rockets.to_context(), None, &*form, errors)).into(); | ||||
|         return render!(session::login( | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             None, | ||||
|             &*form, | ||||
|             errors | ||||
|         )) | ||||
|         .into(); | ||||
|     }; | ||||
| 
 | ||||
|     cookies.add_private( | ||||
| @ -90,7 +97,7 @@ pub fn create( | ||||
|         .into() | ||||
|     } else { | ||||
|         render!(session::login( | ||||
|             &(conn, &rockets.intl.catalog, None, None), | ||||
|             &(&conn, &rockets.intl.catalog, None, None), | ||||
|             None, | ||||
|             &*form, | ||||
|             errors | ||||
| @ -124,9 +131,9 @@ impl PartialEq for ResetRequest { | ||||
| } | ||||
| 
 | ||||
| #[get("/password-reset")] | ||||
| pub fn password_reset_request_form(rockets: PlumeRocket) -> Ructe { | ||||
| pub fn password_reset_request_form(conn: DbConn, rockets: PlumeRocket) -> Ructe { | ||||
|     render!(session::password_reset_request( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         &ResetForm::default(), | ||||
|         ValidationErrors::default() | ||||
|     )) | ||||
| @ -142,10 +149,11 @@ pub struct ResetForm { | ||||
| pub fn password_reset_request( | ||||
|     mail: State<'_, Arc<Mutex<Mailer>>>, | ||||
|     form: LenientForm<ResetForm>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Ructe { | ||||
|     if User::find_by_email(&*rockets.conn, &form.email).is_ok() { | ||||
|         let token = PasswordResetRequest::insert(&*rockets.conn, &form.email) | ||||
|     if User::find_by_email(&conn, &form.email).is_ok() { | ||||
|         let token = PasswordResetRequest::insert(&conn, &form.email) | ||||
|             .expect("password_reset_request::insert: error"); | ||||
| 
 | ||||
|         let url = format!("https://{}/password-reset/{}", CONFIG.base_url, token); | ||||
| @ -161,16 +169,22 @@ pub fn password_reset_request( | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     render!(session::password_reset_request_ok(&rockets.to_context())) | ||||
|     render!(session::password_reset_request_ok( | ||||
|         &(&conn, &rockets).to_context() | ||||
|     )) | ||||
| } | ||||
| 
 | ||||
| #[get("/password-reset/<token>")] | ||||
| pub fn password_reset_form(token: String, rockets: PlumeRocket) -> Result<Ructe, Ructe> { | ||||
|     PasswordResetRequest::find_by_token(&*rockets.conn, &token) | ||||
|         .map_err(|err| password_reset_error_response(err, &rockets))?; | ||||
| pub fn password_reset_form( | ||||
|     token: String, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Ructe, Ructe> { | ||||
|     PasswordResetRequest::find_by_token(&conn, &token) | ||||
|         .map_err(|err| password_reset_error_response(err, &conn, &rockets))?; | ||||
| 
 | ||||
|     Ok(render!(session::password_reset( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         &NewPasswordForm::default(), | ||||
|         ValidationErrors::default() | ||||
|     ))) | ||||
| @ -199,15 +213,21 @@ fn passwords_match(form: &NewPasswordForm) -> Result<(), ValidationError> { | ||||
| pub fn password_reset( | ||||
|     token: String, | ||||
|     form: LenientForm<NewPasswordForm>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Flash<Redirect>, Ructe> { | ||||
|     form.validate() | ||||
|         .map_err(|err| render!(session::password_reset(&rockets.to_context(), &form, err)))?; | ||||
|     form.validate().map_err(|err| { | ||||
|         render!(session::password_reset( | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             &form, | ||||
|             err | ||||
|         )) | ||||
|     })?; | ||||
| 
 | ||||
|     PasswordResetRequest::find_and_delete_by_token(&*rockets.conn, &token) | ||||
|         .and_then(|request| User::find_by_email(&*rockets.conn, &request.email)) | ||||
|         .and_then(|user| user.reset_password(&*rockets.conn, &form.password)) | ||||
|         .map_err(|err| password_reset_error_response(err, &rockets))?; | ||||
|     PasswordResetRequest::find_and_delete_by_token(&conn, &token) | ||||
|         .and_then(|request| User::find_by_email(&conn, &request.email)) | ||||
|         .and_then(|user| user.reset_password(&conn, &form.password)) | ||||
|         .map_err(|err| password_reset_error_response(err, &conn, &rockets))?; | ||||
| 
 | ||||
|     Ok(Flash::success( | ||||
|         Redirect::to(uri!(new: m = _)), | ||||
| @ -218,11 +238,11 @@ pub fn password_reset( | ||||
|     )) | ||||
| } | ||||
| 
 | ||||
| fn password_reset_error_response(err: Error, rockets: &PlumeRocket) -> Ructe { | ||||
| fn password_reset_error_response(err: Error, conn: &DbConn, rockets: &PlumeRocket) -> Ructe { | ||||
|     match err { | ||||
|         Error::Expired => render!(session::password_reset_request_expired( | ||||
|             &rockets.to_context() | ||||
|             &(conn, rockets).to_context() | ||||
|         )), | ||||
|         _ => render!(errors::not_found(&rockets.to_context())), | ||||
|         _ => render!(errors::not_found(&(conn, rockets).to_context())), | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,16 +1,21 @@ | ||||
| use crate::routes::{errors::ErrorPage, Page}; | ||||
| use crate::template_utils::{IntoContext, Ructe}; | ||||
| use plume_models::{posts::Post, PlumeRocket}; | ||||
| use plume_models::{db_conn::DbConn, posts::Post, PlumeRocket}; | ||||
| 
 | ||||
| #[get("/tag/<name>?<page>")] | ||||
| pub fn tag(name: String, page: Option<Page>, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
| pub fn tag( | ||||
|     name: String, | ||||
|     page: Option<Page>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Ructe, ErrorPage> { | ||||
|     let page = page.unwrap_or_default(); | ||||
|     let posts = Post::list_by_tag(&*rockets.conn, name.clone(), page.limits())?; | ||||
|     let posts = Post::list_by_tag(&conn, name.clone(), page.limits())?; | ||||
|     Ok(render!(tags::index( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         name.clone(), | ||||
|         posts, | ||||
|         page.0, | ||||
|         Page::total(Post::count_for_tag(&*rockets.conn, name)? as i32) | ||||
|         Page::total(Post::count_for_tag(&conn, name)? as i32) | ||||
|     ))) | ||||
| } | ||||
|  | ||||
| @ -3,18 +3,23 @@ | ||||
| use crate::routes::Page; | ||||
| use crate::template_utils::IntoContext; | ||||
| use crate::{routes::errors::ErrorPage, template_utils::Ructe}; | ||||
| use plume_models::{timeline::*, PlumeRocket}; | ||||
| use plume_models::{db_conn::DbConn, timeline::*, PlumeRocket}; | ||||
| use rocket::response::Redirect; | ||||
| 
 | ||||
| #[get("/timeline/<id>?<page>")] | ||||
| pub fn details(id: i32, rockets: PlumeRocket, page: Option<Page>) -> Result<Ructe, ErrorPage> { | ||||
| pub fn details( | ||||
|     id: i32, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
|     page: Option<Page>, | ||||
| ) -> Result<Ructe, ErrorPage> { | ||||
|     let page = page.unwrap_or_default(); | ||||
|     let all_tl = Timeline::list_all_for_user(&rockets.conn, rockets.user.clone().map(|u| u.id))?; | ||||
|     let tl = Timeline::get(&rockets.conn, id)?; | ||||
|     let posts = tl.get_page(&rockets.conn, page.limits())?; | ||||
|     let total_posts = tl.count_posts(&rockets.conn)?; | ||||
|     let all_tl = Timeline::list_all_for_user(&conn, rockets.user.clone().map(|u| u.id))?; | ||||
|     let tl = Timeline::get(&conn, id)?; | ||||
|     let posts = tl.get_page(&conn, page.limits())?; | ||||
|     let total_posts = tl.count_posts(&conn)?; | ||||
|     Ok(render!(timelines::details( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         tl, | ||||
|         posts, | ||||
|         all_tl, | ||||
|  | ||||
| @ -45,12 +45,12 @@ pub fn me(user: Option<User>) -> RespondOrRedirect { | ||||
| pub fn details( | ||||
|     name: String, | ||||
|     rockets: PlumeRocket, | ||||
|     fetch_rockets: PlumeRocket, | ||||
|     fetch_followers_rockets: PlumeRocket, | ||||
|     conn: DbConn, | ||||
|     fetch_rockets: DbConn, | ||||
|     fetch_followers_rockets: DbConn, | ||||
|     update_conn: DbConn, | ||||
| ) -> Result<Ructe, ErrorPage> { | ||||
|     let conn = &*rockets.conn; | ||||
|     let user = User::find_by_fqn(&rockets, &name)?; | ||||
|     let user = User::find_by_fqn(&conn, &name)?; | ||||
|     let recents = Post::get_recents_for_author(&*conn, &user, 6)?; | ||||
|     let reshares = Reshare::get_recents_for_author(&*conn, &user, 6)?; | ||||
|     let worker = &rockets.worker; | ||||
| @ -85,7 +85,7 @@ pub fn details( | ||||
|                     User::from_id(&fetch_followers_rockets, &user_id, None, CONFIG.proxy()) | ||||
|                         .expect("user::details: Couldn't fetch follower"); | ||||
|                 follows::Follow::insert( | ||||
|                     &*fetch_followers_rockets.conn, | ||||
|                     &*fetch_followers_rockets, | ||||
|                     follows::NewFollow { | ||||
|                         follower_id: follower.id, | ||||
|                         following_id: user_clone.id, | ||||
| @ -108,7 +108,7 @@ pub fn details( | ||||
|     } | ||||
| 
 | ||||
|     Ok(render!(users::details( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         user.clone(), | ||||
|         rockets | ||||
|             .user | ||||
| @ -126,12 +126,12 @@ pub fn details( | ||||
| } | ||||
| 
 | ||||
| #[get("/dashboard")] | ||||
| pub fn dashboard(user: User, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
|     let blogs = Blog::find_for_author(&*rockets.conn, &user)?; | ||||
| pub fn dashboard(user: User, conn: DbConn, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
|     let blogs = Blog::find_for_author(&conn, &user)?; | ||||
|     Ok(render!(users::dashboard( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         blogs, | ||||
|         Post::drafts_by_author(&*rockets.conn, &user)? | ||||
|         Post::drafts_by_author(&conn, &user)? | ||||
|     ))) | ||||
| } | ||||
| 
 | ||||
| @ -150,14 +150,14 @@ pub fn dashboard_auth(i18n: I18n) -> Flash<Redirect> { | ||||
| pub fn follow( | ||||
|     name: String, | ||||
|     user: User, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Flash<Redirect>, ErrorPage> { | ||||
|     let conn = &*rockets.conn; | ||||
|     let target = User::find_by_fqn(&rockets, &name)?; | ||||
|     let message = if let Ok(follow) = follows::Follow::find(&*conn, user.id, target.id) { | ||||
|         let delete_act = follow.build_undo(&*conn)?; | ||||
|     let target = User::find_by_fqn(&conn, &name)?; | ||||
|     let message = if let Ok(follow) = follows::Follow::find(&conn, user.id, target.id) { | ||||
|         let delete_act = follow.build_undo(&conn)?; | ||||
|         local_inbox( | ||||
|             &rockets, | ||||
|             &conn, | ||||
|             serde_json::to_value(&delete_act).map_err(Error::from)?, | ||||
|         )?; | ||||
| 
 | ||||
| @ -168,16 +168,16 @@ pub fn follow( | ||||
|         msg | ||||
|     } else { | ||||
|         let f = follows::Follow::insert( | ||||
|             &*conn, | ||||
|             &conn, | ||||
|             follows::NewFollow { | ||||
|                 follower_id: user.id, | ||||
|                 following_id: target.id, | ||||
|                 ap_url: String::new(), | ||||
|             }, | ||||
|         )?; | ||||
|         f.notify(&*conn)?; | ||||
|         f.notify(&conn)?; | ||||
| 
 | ||||
|         let act = f.to_activity(&*conn)?; | ||||
|         let act = f.to_activity(&conn)?; | ||||
|         let msg = i18n!(rockets.intl.catalog, "You are now following {}."; target.name()); | ||||
|         rockets | ||||
|             .worker | ||||
| @ -192,12 +192,13 @@ pub fn follow( | ||||
| 
 | ||||
| #[post("/@/<name>/follow", data = "<remote_form>", rank = 2)] | ||||
| pub fn follow_not_connected( | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
|     name: String, | ||||
|     remote_form: Option<LenientForm<RemoteForm>>, | ||||
|     i18n: I18n, | ||||
| ) -> Result<RespondOrRedirect, ErrorPage> { | ||||
|     let target = User::find_by_fqn(&rockets, &name)?; | ||||
|     let target = User::find_by_fqn(&conn, &name)?; | ||||
|     if let Some(remote_form) = remote_form { | ||||
|         if let Some(uri) = User::fetch_remote_interact_uri(&remote_form) | ||||
|             .ok() | ||||
| @ -207,7 +208,7 @@ pub fn follow_not_connected( | ||||
|                     &format!( | ||||
|                         "{}@{}", | ||||
|                         target.fqn, | ||||
|                         target.get_instance(&rockets.conn).ok()?.public_domain | ||||
|                         target.get_instance(&conn).ok()?.public_domain | ||||
|                     ), | ||||
|                 )) | ||||
|             }) | ||||
| @ -224,7 +225,7 @@ pub fn follow_not_connected( | ||||
|             ); | ||||
|             Ok(Flash::new( | ||||
|                 render!(users::follow_remote( | ||||
|                     &rockets.to_context(), | ||||
|                     &(&conn, &rockets).to_context(), | ||||
|                     target, | ||||
|                     super::session::LoginForm::default(), | ||||
|                     ValidationErrors::default(), | ||||
| @ -239,7 +240,7 @@ pub fn follow_not_connected( | ||||
|     } else { | ||||
|         Ok(Flash::new( | ||||
|             render!(users::follow_remote( | ||||
|                 &rockets.to_context(), | ||||
|                 &(&conn, &rockets).to_context(), | ||||
|                 target, | ||||
|                 super::session::LoginForm::default(), | ||||
|                 ValidationErrors::default(), | ||||
| @ -269,24 +270,24 @@ pub fn follow_auth(name: String, i18n: I18n) -> Flash<Redirect> { | ||||
| pub fn followers( | ||||
|     name: String, | ||||
|     page: Option<Page>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Ructe, ErrorPage> { | ||||
|     let conn = &*rockets.conn; | ||||
|     let page = page.unwrap_or_default(); | ||||
|     let user = User::find_by_fqn(&rockets, &name)?; | ||||
|     let followers_count = user.count_followers(&*conn)?; | ||||
|     let user = User::find_by_fqn(&conn, &name)?; | ||||
|     let followers_count = user.count_followers(&conn)?; | ||||
| 
 | ||||
|     Ok(render!(users::followers( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         user.clone(), | ||||
|         rockets | ||||
|             .user | ||||
|             .clone() | ||||
|             .and_then(|x| x.is_following(&*conn, user.id).ok()) | ||||
|             .and_then(|x| x.is_following(&conn, user.id).ok()) | ||||
|             .unwrap_or(false), | ||||
|         user.instance_id != Instance::get_local()?.id, | ||||
|         user.get_instance(&*conn)?.public_domain, | ||||
|         user.get_followers_page(&*conn, page.limits())?, | ||||
|         user.get_instance(&conn)?.public_domain, | ||||
|         user.get_followers_page(&conn, page.limits())?, | ||||
|         page.0, | ||||
|         Page::total(followers_count as i32) | ||||
|     ))) | ||||
| @ -296,24 +297,24 @@ pub fn followers( | ||||
| pub fn followed( | ||||
|     name: String, | ||||
|     page: Option<Page>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Ructe, ErrorPage> { | ||||
|     let conn = &*rockets.conn; | ||||
|     let page = page.unwrap_or_default(); | ||||
|     let user = User::find_by_fqn(&rockets, &name)?; | ||||
|     let followed_count = user.count_followed(conn)?; | ||||
|     let user = User::find_by_fqn(&conn, &name)?; | ||||
|     let followed_count = user.count_followed(&conn)?; | ||||
| 
 | ||||
|     Ok(render!(users::followed( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         user.clone(), | ||||
|         rockets | ||||
|             .user | ||||
|             .clone() | ||||
|             .and_then(|x| x.is_following(conn, user.id).ok()) | ||||
|             .and_then(|x| x.is_following(&conn, user.id).ok()) | ||||
|             .unwrap_or(false), | ||||
|         user.instance_id != Instance::get_local()?.id, | ||||
|         user.get_instance(conn)?.public_domain, | ||||
|         user.get_followed_page(conn, page.limits())?, | ||||
|         user.get_instance(&conn)?.public_domain, | ||||
|         user.get_followed_page(&conn, page.limits())?, | ||||
|         page.0, | ||||
|         Page::total(followed_count as i32) | ||||
|     ))) | ||||
| @ -322,17 +323,17 @@ pub fn followed( | ||||
| #[get("/@/<name>", rank = 1)] | ||||
| pub fn activity_details( | ||||
|     name: String, | ||||
|     rockets: PlumeRocket, | ||||
|     conn: DbConn, | ||||
|     _ap: ApRequest, | ||||
| ) -> Option<ActivityStream<CustomPerson>> { | ||||
|     let user = User::find_by_fqn(&rockets, &name).ok()?; | ||||
|     Some(ActivityStream::new(user.to_activity(&*rockets.conn).ok()?)) | ||||
|     let user = User::find_by_fqn(&conn, &name).ok()?; | ||||
|     Some(ActivityStream::new(user.to_activity(&conn).ok()?)) | ||||
| } | ||||
| 
 | ||||
| #[get("/users/new")] | ||||
| pub fn new(rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
| pub fn new(conn: DbConn, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
|     Ok(render!(users::new( | ||||
|         &rockets.to_context(), | ||||
|         &(&conn, &rockets).to_context(), | ||||
|         Instance::get_local()?.open_registrations, | ||||
|         &NewUserForm::default(), | ||||
|         ValidationErrors::default() | ||||
| @ -340,10 +341,15 @@ pub fn new(rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
| } | ||||
| 
 | ||||
| #[get("/@/<name>/edit")] | ||||
| pub fn edit(name: String, user: User, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
| pub fn edit( | ||||
|     name: String, | ||||
|     user: User, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Ructe, ErrorPage> { | ||||
|     if user.username == name && !name.contains('@') { | ||||
|         Ok(render!(users::edit( | ||||
|             &rockets.to_context(), | ||||
|             &(&conn, &rockets).to_context(), | ||||
|             UpdateUserForm { | ||||
|                 display_name: user.display_name.clone(), | ||||
|                 email: user.email.clone().unwrap_or_default(), | ||||
| @ -417,14 +423,15 @@ pub fn delete( | ||||
|     name: String, | ||||
|     user: User, | ||||
|     mut cookies: Cookies<'_>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Flash<Redirect>, ErrorPage> { | ||||
|     let account = User::find_by_fqn(&rockets, &name)?; | ||||
|     let account = User::find_by_fqn(&conn, &name)?; | ||||
|     if user.id == account.id { | ||||
|         account.delete(&*rockets.conn)?; | ||||
|         account.delete(&conn)?; | ||||
| 
 | ||||
|         let target = User::one_by_instance(&*rockets.conn)?; | ||||
|         let delete_act = account.delete_activity(&*rockets.conn)?; | ||||
|         let target = User::one_by_instance(&conn)?; | ||||
|         let delete_act = account.delete_activity(&conn)?; | ||||
|         rockets | ||||
|             .worker | ||||
|             .execute(move || broadcast(&account, delete_act, target, CONFIG.proxy().cloned())); | ||||
| @ -515,9 +522,9 @@ fn to_validation(x: Error) -> ValidationErrors { | ||||
| #[post("/users/new", data = "<form>")] | ||||
| pub fn create( | ||||
|     form: LenientForm<NewUserForm>, | ||||
|     conn: DbConn, | ||||
|     rockets: PlumeRocket, | ||||
| ) -> Result<Flash<Redirect>, Ructe> { | ||||
|     let conn = &*rockets.conn; | ||||
|     if !Instance::get_local() | ||||
|         .map(|i| i.open_registrations) | ||||
|         .unwrap_or(true) | ||||
| @ -537,7 +544,7 @@ pub fn create( | ||||
|     form.validate() | ||||
|         .and_then(|_| { | ||||
|             NewUser::new_local( | ||||
|                 conn, | ||||
|                 &conn, | ||||
|                 form.username.to_string(), | ||||
|                 form.username.to_string(), | ||||
|                 Role::Normal, | ||||
| @ -555,7 +562,7 @@ pub fn create( | ||||
|         }) | ||||
|         .map_err(|err| { | ||||
|             render!(users::new( | ||||
|                 &rockets.to_context(), | ||||
|                 &(&conn, &rockets).to_context(), | ||||
|                 Instance::get_local() | ||||
|                     .map(|i| i.open_registrations) | ||||
|                     .unwrap_or(true), | ||||
| @ -566,39 +573,39 @@ pub fn create( | ||||
| } | ||||
| 
 | ||||
| #[get("/@/<name>/outbox")] | ||||
| pub fn outbox(name: String, rockets: PlumeRocket) -> Option<ActivityStream<OrderedCollection>> { | ||||
|     let user = User::find_by_fqn(&rockets, &name).ok()?; | ||||
|     user.outbox(&*rockets.conn).ok() | ||||
| pub fn outbox(name: String, conn: DbConn) -> Option<ActivityStream<OrderedCollection>> { | ||||
|     let user = User::find_by_fqn(&conn, &name).ok()?; | ||||
|     user.outbox(&conn).ok() | ||||
| } | ||||
| #[get("/@/<name>/outbox?<page>")] | ||||
| pub fn outbox_page( | ||||
|     name: String, | ||||
|     page: Page, | ||||
|     rockets: PlumeRocket, | ||||
|     conn: DbConn, | ||||
| ) -> Option<ActivityStream<OrderedCollectionPage>> { | ||||
|     let user = User::find_by_fqn(&rockets, &name).ok()?; | ||||
|     user.outbox_page(&*rockets.conn, page.limits()).ok() | ||||
|     let user = User::find_by_fqn(&conn, &name).ok()?; | ||||
|     user.outbox_page(&conn, page.limits()).ok() | ||||
| } | ||||
| #[post("/@/<name>/inbox", data = "<data>")] | ||||
| pub fn inbox( | ||||
|     name: String, | ||||
|     data: inbox::SignedJson<serde_json::Value>, | ||||
|     headers: Headers<'_>, | ||||
|     rockets: PlumeRocket, | ||||
|     conn: DbConn, | ||||
| ) -> Result<String, status::BadRequest<&'static str>> { | ||||
|     User::find_by_fqn(&rockets, &name).map_err(|_| status::BadRequest(Some("User not found")))?; | ||||
|     inbox::handle_incoming(rockets, data, headers) | ||||
|     User::find_by_fqn(&conn, &name).map_err(|_| status::BadRequest(Some("User not found")))?; | ||||
|     inbox::handle_incoming(conn, data, headers) | ||||
| } | ||||
| 
 | ||||
| #[get("/@/<name>/followers", rank = 1)] | ||||
| pub fn ap_followers( | ||||
|     name: String, | ||||
|     rockets: PlumeRocket, | ||||
|     conn: DbConn, | ||||
|     _ap: ApRequest, | ||||
| ) -> Option<ActivityStream<OrderedCollection>> { | ||||
|     let user = User::find_by_fqn(&rockets, &name).ok()?; | ||||
|     let user = User::find_by_fqn(&conn, &name).ok()?; | ||||
|     let followers = user | ||||
|         .get_followers(&*rockets.conn) | ||||
|         .get_followers(&conn) | ||||
|         .ok()? | ||||
|         .into_iter() | ||||
|         .map(|f| Id::new(f.ap_url)) | ||||
| @ -616,16 +623,16 @@ pub fn ap_followers( | ||||
| } | ||||
| 
 | ||||
| #[get("/@/<name>/atom.xml")] | ||||
| pub fn atom_feed(name: String, rockets: PlumeRocket) -> Option<Content<String>> { | ||||
|     let conn = &*rockets.conn; | ||||
|     let author = User::find_by_fqn(&rockets, &name).ok()?; | ||||
|     let entries = Post::get_recents_for_author(conn, &author, 15).ok()?; | ||||
| pub fn atom_feed(name: String, conn: DbConn) -> Option<Content<String>> { | ||||
|     let conn = &conn; | ||||
|     let author = User::find_by_fqn(&conn, &name).ok()?; | ||||
|     let entries = Post::get_recents_for_author(&conn, &author, 15).ok()?; | ||||
|     let uri = Instance::get_local() | ||||
|         .ok()? | ||||
|         .compute_box("@", &name, "atom.xml"); | ||||
|     let title = &author.display_name; | ||||
|     let default_updated = &author.creation_date; | ||||
|     let feed = super::build_atom_feed(entries, &uri, title, default_updated, conn); | ||||
|     let feed = super::build_atom_feed(entries, &uri, title, default_updated, &conn); | ||||
|     Some(Content( | ||||
|         ContentType::new("application", "atom+xml"), | ||||
|         feed.to_string(), | ||||
|  | ||||
| @ -2,7 +2,7 @@ use rocket::http::ContentType; | ||||
| use rocket::response::Content; | ||||
| use webfinger::*; | ||||
| 
 | ||||
| use plume_models::{ap_url, blogs::Blog, users::User, PlumeRocket, CONFIG}; | ||||
| use plume_models::{ap_url, blogs::Blog, db_conn::DbConn, users::User, CONFIG}; | ||||
| 
 | ||||
| #[get("/.well-known/nodeinfo")] | ||||
| pub fn nodeinfo() -> Content<String> { | ||||
| @ -42,18 +42,18 @@ pub fn host_meta() -> String { | ||||
| 
 | ||||
| struct WebfingerResolver; | ||||
| 
 | ||||
| impl Resolver<PlumeRocket> for WebfingerResolver { | ||||
| impl Resolver<DbConn> for WebfingerResolver { | ||||
|     fn instance_domain<'a>() -> &'a str { | ||||
|         CONFIG.base_url.as_str() | ||||
|     } | ||||
| 
 | ||||
|     fn find(prefix: Prefix, acct: String, ctx: PlumeRocket) -> Result<Webfinger, ResolverError> { | ||||
|     fn find(prefix: Prefix, acct: String, conn: DbConn) -> Result<Webfinger, ResolverError> { | ||||
|         match prefix { | ||||
|             Prefix::Acct => User::find_by_fqn(&ctx, &acct) | ||||
|                 .and_then(|usr| usr.webfinger(&*ctx.conn)) | ||||
|             Prefix::Acct => User::find_by_fqn(&conn, &acct) | ||||
|                 .and_then(|usr| usr.webfinger(&*conn)) | ||||
|                 .or(Err(ResolverError::NotFound)), | ||||
|             Prefix::Group => Blog::find_by_fqn(&ctx, &acct) | ||||
|                 .and_then(|blog| blog.webfinger(&*ctx.conn)) | ||||
|             Prefix::Group => Blog::find_by_fqn(&conn, &acct) | ||||
|                 .and_then(|blog| blog.webfinger(&*conn)) | ||||
|                 .or(Err(ResolverError::NotFound)), | ||||
|             Prefix::Custom(_) => Err(ResolverError::NotFound), | ||||
|         } | ||||
| @ -61,8 +61,8 @@ impl Resolver<PlumeRocket> for WebfingerResolver { | ||||
| } | ||||
| 
 | ||||
| #[get("/.well-known/webfinger?<resource>")] | ||||
| pub fn webfinger(resource: String, rockets: PlumeRocket) -> Content<String> { | ||||
|     match WebfingerResolver::endpoint(resource, rockets) | ||||
| pub fn webfinger(resource: String, conn: DbConn) -> Content<String> { | ||||
|     match WebfingerResolver::endpoint(resource, conn) | ||||
|         .and_then(|wf| serde_json::to_string(&wf).map_err(|_| ResolverError::NotFound)) | ||||
|     { | ||||
|         Ok(wf) => Content(ContentType::new("application", "jrd+json"), wf), | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| use plume_models::{notifications::*, users::User, Connection, PlumeRocket}; | ||||
| use plume_models::{db_conn::DbConn, notifications::*, users::User, Connection, PlumeRocket}; | ||||
| 
 | ||||
| use crate::templates::Html; | ||||
| use rocket::http::hyper::header::{ETag, EntityTag}; | ||||
| @ -31,7 +31,7 @@ pub trait IntoContext { | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| impl IntoContext for PlumeRocket { | ||||
| impl IntoContext for (&DbConn, &PlumeRocket) { | ||||
|     fn to_context( | ||||
|         &self, | ||||
|     ) -> ( | ||||
| @ -41,10 +41,10 @@ impl IntoContext for PlumeRocket { | ||||
|         Option<(String, String)>, | ||||
|     ) { | ||||
|         ( | ||||
|             &*self.conn, | ||||
|             &self.intl.catalog, | ||||
|             self.user.clone(), | ||||
|             self.flash_msg.clone(), | ||||
|             &self.0, | ||||
|             &self.1.intl.catalog, | ||||
|             self.1.user.clone(), | ||||
|             self.1.flash_msg.clone(), | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user