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