Make post/profile page redirection work when web client service is enabled

This commit is contained in:
silverpill 2022-12-24 16:41:29 +00:00
parent dea6bcad2a
commit 7494d62858
3 changed files with 68 additions and 45 deletions

View file

@ -14,7 +14,7 @@ use crate::database::{get_database_client, DbPool};
use crate::errors::HttpError;
use crate::models::posts::helpers::{add_related_posts, can_view_post};
use crate::models::posts::queries::{get_post_by_id, get_posts_by_author};
use crate::models::users::queries::{get_user_by_id, get_user_by_name};
use crate::models::users::queries::get_user_by_name;
use crate::web_client::urls::{get_post_page_url, get_profile_page_url};
use super::actors::types::{get_local_actor, get_instance_actor};
use super::builders::create_note::{build_note, build_create_note};
@ -27,10 +27,8 @@ use super::constants::{AP_MEDIA_TYPE, AS_MEDIA_TYPE};
use super::identifiers::{
local_actor_followers,
local_actor_following,
local_actor_id,
local_actor_subscribers,
local_actor_outbox,
local_object_id,
};
use super::receiver::receive_activity;
@ -330,39 +328,6 @@ pub async fn object_view(
Ok(response)
}
#[get("/profile/{profile_id}")]
pub async fn frontend_profile_redirect(
config: web::Data<Config>,
db_pool: web::Data<DbPool>,
profile_id: web::Path<Uuid>,
) -> Result<HttpResponse, HttpError> {
let db_client = &**get_database_client(&db_pool).await?;
let user = get_user_by_id(db_client, &profile_id).await?;
let actor_id = local_actor_id(
&config.instance_url(),
&user.profile.username,
);
let response = HttpResponse::Found()
.append_header(("Location", actor_id))
.finish();
Ok(response)
}
#[get("/post/{object_id}")]
pub async fn frontend_post_redirect(
config: web::Data<Config>,
internal_object_id: web::Path<Uuid>,
) -> Result<HttpResponse, HttpError> {
let object_id = local_object_id(
&config.instance_url(),
&internal_object_id,
);
let response = HttpResponse::Found()
.append_header(("Location", object_id))
.finish();
Ok(response)
}
#[cfg(test)]
mod tests {
use actix_web::http::{

View file

@ -33,7 +33,7 @@ use mitra::mastodon_api::timelines::views::timeline_api_scope;
use mitra::mastodon_api::UPLOAD_MAX_SIZE;
use mitra::nodeinfo::views as nodeinfo;
use mitra::webfinger::views as webfinger;
use mitra::web_client::views::web_client_service;
use mitra::web_client::views as web_client;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
@ -158,7 +158,9 @@ async fn main() -> std::io::Result<()> {
.service(activitypub::object_view)
.service(atom::get_atom_feed)
.service(nodeinfo::get_nodeinfo)
.service(nodeinfo::get_nodeinfo_2_0);
.service(nodeinfo::get_nodeinfo_2_0)
.service(web_client::profile_page_redirect())
.service(web_client::post_page_redirect());
if let Some(blockchain_config) = config.blockchain() {
if let Some(ethereum_config) = blockchain_config.ethereum_config() {
// Serve artifacts if available
@ -169,12 +171,7 @@ async fn main() -> std::io::Result<()> {
};
};
if let Some(ref web_client_dir) = config.web_client_dir {
app = app.service(web_client_service(web_client_dir));
} else {
// Enable redirects only when serving of web client is disabled
app = app
.service(activitypub::frontend_profile_redirect)
.service(activitypub::frontend_post_redirect)
app = app.service(web_client::static_service(web_client_dir));
};
app
})

View file

@ -2,13 +2,25 @@ use std::path::Path;
use actix_files::{Files, NamedFile};
use actix_web::{
guard,
web,
HttpResponse,
Resource,
dev::{fn_service, ServiceRequest, ServiceResponse},
web::Data,
};
use uuid::Uuid;
use crate::activitypub::{
constants::{AP_MEDIA_TYPE, AS_MEDIA_TYPE},
identifiers::{local_actor_id, local_object_id},
};
use crate::config::Config;
use crate::database::{get_database_client, DbPool};
use crate::errors::HttpError;
use crate::models::users::queries::get_user_by_id;
pub fn web_client_service(web_client_dir: &Path) -> Files {
pub fn static_service(web_client_dir: &Path) -> Files {
Files::new("/", web_client_dir)
.index_file("index.html")
.prefer_utf8(true)
@ -27,3 +39,52 @@ pub fn web_client_service(web_client_dir: &Path) -> Files {
}
}))
}
async fn profile_page_redirect_view(
config: web::Data<Config>,
db_pool: web::Data<DbPool>,
profile_id: web::Path<Uuid>,
) -> Result<HttpResponse, HttpError> {
let db_client = &**get_database_client(&db_pool).await?;
let user = get_user_by_id(db_client, &profile_id).await?;
let actor_id = local_actor_id(
&config.instance_url(),
&user.profile.username,
);
let response = HttpResponse::Found()
.append_header(("Location", actor_id))
.finish();
Ok(response)
}
pub fn profile_page_redirect() -> Resource {
web::resource("/profile/{profile_id}")
.guard(
guard::Any(guard::Header("Accept", AP_MEDIA_TYPE))
.or(guard::Header("Accept", AS_MEDIA_TYPE))
)
.route(web::get().to(profile_page_redirect_view))
}
async fn post_page_redirect_view(
config: web::Data<Config>,
internal_object_id: web::Path<Uuid>,
) -> Result<HttpResponse, HttpError> {
let object_id = local_object_id(
&config.instance_url(),
&internal_object_id,
);
let response = HttpResponse::Found()
.append_header(("Location", object_id))
.finish();
Ok(response)
}
pub fn post_page_redirect() -> Resource {
web::resource("/post/{object_id}")
.guard(
guard::Any(guard::Header("Accept", AP_MEDIA_TYPE))
.or(guard::Header("Accept", AS_MEDIA_TYPE))
)
.route(web::get().to(post_page_redirect_view))
}