2024-06-27 05:13:38 +02:00
|
|
|
use activitypub_federation::{
|
2024-07-16 19:35:04 +02:00
|
|
|
fetch::{object_id::ObjectId, webfinger::webfinger_resolve_actor},
|
|
|
|
|
protocol::context::WithContext,
|
|
|
|
|
traits::Object,
|
|
|
|
|
FEDERATION_CONTENT_TYPE,
|
2024-06-27 05:13:38 +02:00
|
|
|
};
|
|
|
|
|
use activitystreams_kinds::{activity::CreateType, object};
|
2024-06-15 02:06:01 +02:00
|
|
|
use actix_web::{get, web, HttpResponse};
|
2024-07-16 19:35:04 +02:00
|
|
|
use sea_orm::{query, ColumnTrait, EntityTrait, QueryFilter};
|
|
|
|
|
use url::Url;
|
2024-06-15 02:06:01 +02:00
|
|
|
|
2024-06-18 03:43:59 +02:00
|
|
|
use crate::{
|
|
|
|
|
database::State,
|
|
|
|
|
entities::{
|
|
|
|
|
post::{self, Entity},
|
2024-07-16 19:35:04 +02:00
|
|
|
prelude, user,
|
2024-06-18 03:43:59 +02:00
|
|
|
},
|
2024-07-16 19:35:04 +02:00
|
|
|
error,
|
|
|
|
|
lysand::conversion::{lysand_post_from_db, lysand_user_from_db},
|
|
|
|
|
objects,
|
2024-06-27 05:13:38 +02:00
|
|
|
utils::{base_url_decode, generate_create_id},
|
|
|
|
|
Response, DB, FEDERATION_CONFIG,
|
2024-06-18 03:43:59 +02:00
|
|
|
};
|
2024-06-15 02:06:01 +02:00
|
|
|
|
2024-07-16 19:35:04 +02:00
|
|
|
#[derive(serde::Deserialize)]
|
|
|
|
|
struct LysandQuery {
|
|
|
|
|
// Post url
|
|
|
|
|
url: Option<Url>,
|
|
|
|
|
// User handle
|
|
|
|
|
user: Option<String>,
|
|
|
|
|
// User URL
|
|
|
|
|
user_url: Option<Url>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[get("/apbridge/lysand/query")]
|
|
|
|
|
async fn query_post(
|
|
|
|
|
query: web::Query<LysandQuery>,
|
|
|
|
|
state: web::Data<State>,
|
|
|
|
|
) -> actix_web::Result<HttpResponse, error::Error> {
|
|
|
|
|
if query.url.is_none() && query.user.is_none() && query.user_url.is_none() {
|
|
|
|
|
return Ok(
|
|
|
|
|
HttpResponse::BadRequest().body("Bad Request. Error code: mrrrmrrrmrrawwawwawwa")
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let db = DB.get().unwrap();
|
|
|
|
|
let data = FEDERATION_CONFIG.get().unwrap();
|
|
|
|
|
|
|
|
|
|
if let Some(user) = query.user.clone() {
|
|
|
|
|
let target =
|
|
|
|
|
webfinger_resolve_actor::<State, user::Model>(user.as_str(), &data.to_request_data())
|
|
|
|
|
.await?;
|
|
|
|
|
let lysand_user = lysand_user_from_db(target).await?;
|
|
|
|
|
|
|
|
|
|
return Ok(HttpResponse::Ok()
|
|
|
|
|
.content_type("application/json")
|
|
|
|
|
.json(lysand_user));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if let Some(user) = query.user_url.clone() {
|
2024-07-17 01:07:23 +02:00
|
|
|
let opt_model = prelude::User::find()
|
|
|
|
|
.filter(user::Column::Url.eq(user.as_str()))
|
|
|
|
|
.one(db)
|
2024-07-16 19:35:04 +02:00
|
|
|
.await?;
|
2024-07-17 01:07:23 +02:00
|
|
|
let target;
|
|
|
|
|
if let Some(model) = opt_model {
|
|
|
|
|
target = model;
|
|
|
|
|
} else {
|
|
|
|
|
target = ObjectId::<user::Model>::from(user)
|
|
|
|
|
.dereference(&data.to_request_data())
|
|
|
|
|
.await?;
|
|
|
|
|
}
|
2024-07-16 19:35:04 +02:00
|
|
|
let lysand_user = lysand_user_from_db(target).await?;
|
|
|
|
|
|
|
|
|
|
return Ok(HttpResponse::Ok()
|
|
|
|
|
.content_type("application/json")
|
|
|
|
|
.json(lysand_user));
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-17 01:13:10 +02:00
|
|
|
let opt_model = prelude::Post::find()
|
|
|
|
|
.filter(post::Column::Url.eq(query.url.clone().unwrap().as_str()))
|
|
|
|
|
.one(db)
|
|
|
|
|
.await?;
|
|
|
|
|
let target;
|
|
|
|
|
if let Some(model) = opt_model {
|
|
|
|
|
target = model;
|
|
|
|
|
} else {
|
|
|
|
|
target = ObjectId::<post::Model>::from(Url::parse(query.url.clone().unwrap().as_str())?)
|
|
|
|
|
.dereference(&data.to_request_data())
|
|
|
|
|
.await?;
|
|
|
|
|
}
|
2024-07-16 19:35:04 +02:00
|
|
|
|
|
|
|
|
Ok(HttpResponse::Ok()
|
|
|
|
|
.content_type("application/json")
|
|
|
|
|
.json(lysand_post_from_db(target).await?))
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-15 02:06:01 +02:00
|
|
|
#[get("/apbridge/object/{post}")]
|
2024-06-17 19:52:51 +02:00
|
|
|
async fn fetch_post(
|
|
|
|
|
path: web::Path<String>,
|
2024-06-15 02:06:01 +02:00
|
|
|
state: web::Data<State>,
|
|
|
|
|
) -> actix_web::Result<HttpResponse, error::Error> {
|
|
|
|
|
let db = DB.get().unwrap();
|
|
|
|
|
|
|
|
|
|
let post = prelude::Post::find()
|
2024-06-17 19:52:51 +02:00
|
|
|
.filter(post::Column::Id.eq(path.as_str()))
|
2024-06-15 02:06:01 +02:00
|
|
|
.one(db)
|
|
|
|
|
.await?;
|
|
|
|
|
|
2024-06-17 19:52:51 +02:00
|
|
|
let post = match post {
|
|
|
|
|
Some(post) => post,
|
|
|
|
|
None => return Ok(HttpResponse::NotFound().finish()),
|
|
|
|
|
};
|
2024-06-15 02:06:01 +02:00
|
|
|
|
2024-06-18 03:43:59 +02:00
|
|
|
Ok(HttpResponse::Ok()
|
|
|
|
|
.content_type(FEDERATION_CONTENT_TYPE)
|
2024-06-27 09:48:47 +02:00
|
|
|
.json(crate::objects::post::Note::from_db(&post)))
|
2024-06-18 03:43:59 +02:00
|
|
|
}
|
2024-06-27 05:13:38 +02:00
|
|
|
|
2024-07-16 19:35:04 +02:00
|
|
|
#[get("/apbridge/lysand/object/{post}")]
|
|
|
|
|
async fn fetch_lysand_post(
|
|
|
|
|
path: web::Path<String>,
|
|
|
|
|
state: web::Data<State>,
|
|
|
|
|
) -> actix_web::Result<HttpResponse, error::Error> {
|
|
|
|
|
let db = DB.get().unwrap();
|
|
|
|
|
|
|
|
|
|
let post = prelude::Post::find()
|
|
|
|
|
.filter(post::Column::Id.eq(path.as_str()))
|
|
|
|
|
.one(db)
|
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
|
|
let post = match post {
|
|
|
|
|
Some(post) => post,
|
|
|
|
|
None => return Ok(HttpResponse::NotFound().finish()),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Ok(HttpResponse::Ok()
|
|
|
|
|
.content_type("application/json")
|
|
|
|
|
.json(lysand_post_from_db(post).await?))
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-27 05:13:38 +02:00
|
|
|
#[get("/apbridge/create/{id}/{base64url}")]
|
|
|
|
|
async fn create_activity(
|
|
|
|
|
path: web::Path<(String, String)>,
|
|
|
|
|
state: web::Data<State>,
|
|
|
|
|
) -> actix_web::Result<HttpResponse, error::Error> {
|
|
|
|
|
let db = DB.get().unwrap();
|
|
|
|
|
|
|
|
|
|
let url = base_url_decode(path.1.as_str());
|
|
|
|
|
|
|
|
|
|
let post = prelude::Post::find()
|
|
|
|
|
.filter(post::Column::Id.eq(path.0.as_str()))
|
|
|
|
|
.one(db)
|
|
|
|
|
.await?;
|
|
|
|
|
|
|
|
|
|
let post = match post {
|
|
|
|
|
Some(post) => post,
|
|
|
|
|
None => return Ok(HttpResponse::NotFound().finish()),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let ap_post = crate::objects::post::Note::from_db(&post);
|
|
|
|
|
|
|
|
|
|
let data = FEDERATION_CONFIG.get().unwrap();
|
|
|
|
|
|
|
|
|
|
let create = crate::activities::create_post::CreatePost {
|
|
|
|
|
actor: ap_post.attributed_to.clone(),
|
|
|
|
|
to: ap_post.to.clone(),
|
|
|
|
|
object: ap_post,
|
|
|
|
|
kind: CreateType::Create,
|
|
|
|
|
id: generate_create_id(&data.to_request_data().domain(), &path.0, &path.1)?,
|
|
|
|
|
};
|
|
|
|
|
let create_with_context = WithContext::new_default(create);
|
|
|
|
|
|
|
|
|
|
Ok(HttpResponse::Ok()
|
|
|
|
|
.content_type(FEDERATION_CONTENT_TYPE)
|
|
|
|
|
.json(create_with_context))
|
|
|
|
|
}
|