1
0
Fork 0
mirror of https://github.com/Nutomic/ibis.git synced 2024-11-22 11:31:08 +00:00

edits federating, need tests and api adjustments

This commit is contained in:
Felix Ableitner 2023-11-20 17:04:52 +01:00
parent c48f26c908
commit afbb81c0d1
9 changed files with 60 additions and 21 deletions

View file

@ -6,7 +6,6 @@ use crate::federation::activities::create_or_update_article::{
};
use crate::federation::objects::article::DbArticle;
use crate::federation::objects::instance::DbInstance;
use crate::utils::generate_object_id;
use activitypub_federation::config::Data;
use activitypub_federation::fetch::object_id::ObjectId;
use anyhow::anyhow;
@ -41,7 +40,13 @@ async fn create_article(
Form(create_article): Form<CreateArticle>,
) -> MyResult<Json<DbArticle>> {
let local_instance_id = data.local_instance().ap_id;
let ap_id = generate_object_id(local_instance_id.inner())?.into();
let ap_id = Url::parse(&format!(
"http://{}:{}/article/{}",
local_instance_id.inner().domain().unwrap(),
local_instance_id.inner().port().unwrap(),
create_article.title
))?
.into();
let article = DbArticle {
title: create_article.title,
text: create_article.text,

View file

@ -15,7 +15,7 @@ pub mod routes;
pub async fn federation_config(hostname: &str) -> Result<FederationConfig<DatabaseHandle>, Error> {
let ap_id = Url::parse(&format!("http://{}", hostname))?.into();
let articles_id = Url::parse(&format!("http://{}/articles", hostname))?.into();
let articles_id = Url::parse(&format!("http://{}/all_articles", hostname))?.into();
let inbox = Url::parse(&format!("http://{}/inbox", hostname))?;
let keypair = generate_actor_keypair()?;
let local_instance = DbInstance {

View file

@ -1,6 +1,6 @@
use crate::error::MyResult;
use crate::federation::objects::edit::DbEdit;
use crate::federation::objects::edits_collection::{ApubEditCollection, DbEditCollection};
use crate::federation::objects::edits_collection::DbEditCollection;
use crate::federation::objects::instance::DbInstance;
use crate::{database::DatabaseHandle, error::Error};
use activitypub_federation::fetch::collection_id::CollectionId;

View file

@ -2,7 +2,7 @@ use crate::database::DatabaseHandle;
use crate::error::Error;
use crate::federation::objects::article::{ApubArticle, DbArticle};
use crate::federation::objects::instance::DbInstance;
use crate::utils::generate_object_id;
use activitypub_federation::kinds::collection::CollectionType;
use activitypub_federation::{
config::Data,

View file

@ -37,25 +37,28 @@ impl Object for DbEdit {
type Error = Error;
async fn read_from_id(
object_id: Url,
data: &Data<Self::DataType>,
_object_id: Url,
_data: &Data<Self::DataType>,
) -> Result<Option<Self>, Self::Error> {
todo!()
}
async fn into_json(self, data: &Data<Self::DataType>) -> Result<Self::Kind, Self::Error> {
async fn into_json(self, _data: &Data<Self::DataType>) -> Result<Self::Kind, Self::Error> {
todo!()
}
async fn verify(
json: &Self::Kind,
expected_domain: &Url,
data: &Data<Self::DataType>,
_json: &Self::Kind,
_expected_domain: &Url,
_data: &Data<Self::DataType>,
) -> Result<(), Self::Error> {
todo!()
}
async fn from_json(json: Self::Kind, data: &Data<Self::DataType>) -> Result<Self, Self::Error> {
async fn from_json(
_json: Self::Kind,
_data: &Data<Self::DataType>,
) -> Result<Self, Self::Error> {
todo!()
}
}

View file

@ -1,10 +1,9 @@
use crate::database::DatabaseHandle;
use crate::error::Error;
use crate::federation::objects::article::{ApubArticle, DbArticle};
use crate::federation::objects::article::DbArticle;
use crate::federation::objects::edit::{ApubEdit, DbEdit};
use crate::federation::objects::instance::DbInstance;
use crate::utils::generate_object_id;
use activitypub_federation::kinds::collection::{CollectionType, OrderedCollectionType};
use activitypub_federation::kinds::collection::OrderedCollectionType;
use activitypub_federation::{
config::Data,
traits::{Collection, Object},
@ -75,7 +74,7 @@ impl Collection for DbEditCollection {
let edits =
try_join_all(apub.items.into_iter().map(|i| DbEdit::from_json(i, data))).await?;
let mut articles = data.articles.lock().unwrap();
let mut article = articles.get_mut(owner.ap_id.inner()).unwrap();
let article = articles.get_mut(owner.ap_id.inner()).unwrap();
for e in edits.clone() {
// TODO: edits need a unique id to avoid pushing duplicates
article.edits.push(e);

View file

@ -1,4 +1,4 @@
use crate::error::{Error, MyResult};
use crate::error::Error;
use crate::federation::objects::articles_collection::DbArticleCollection;
use crate::{database::DatabaseHandle, federation::activities::follow::Follow};
use activitypub_federation::activity_sending::SendActivityTask;

View file

@ -10,9 +10,12 @@ use activitypub_federation::config::Data;
use activitypub_federation::protocol::context::WithContext;
use activitypub_federation::traits::Object;
use activitypub_federation::traits::{ActivityHandler, Collection};
use axum::extract::Path;
use crate::federation::activities::create_or_update_article::CreateOrUpdateArticle;
use crate::federation::objects::article::ApubArticle;
use crate::federation::objects::articles_collection::{ArticleCollection, DbArticleCollection};
use crate::federation::objects::edits_collection::{ApubEditCollection, DbEditCollection};
use axum::response::IntoResponse;
use axum::routing::{get, post};
use axum::Router;
@ -23,7 +26,9 @@ use url::Url;
pub fn federation_routes() -> Router {
Router::new()
.route("/", get(http_get_instance))
.route("/articles", get(http_get_articles))
.route("/all_articles", get(http_get_all_articles))
.route("/article/:title", get(http_get_article))
.route("/article/:title/edits", get(http_get_article_edits))
.route("/inbox", post(http_post_inbox))
}
@ -37,13 +42,39 @@ async fn http_get_instance(
}
#[debug_handler]
async fn http_get_articles(
async fn http_get_all_articles(
data: Data<DatabaseHandle>,
) -> MyResult<FederationJson<WithContext<ArticleCollection>>> {
let collection = DbArticleCollection::read_local(&data.local_instance(), &data).await?;
Ok(FederationJson(WithContext::new_default(collection)))
}
#[debug_handler]
async fn http_get_article(
Path(title): Path<String>,
data: Data<DatabaseHandle>,
) -> MyResult<FederationJson<WithContext<ApubArticle>>> {
let article = {
let lock = data.articles.lock().unwrap();
lock.values().find(|a| a.title == title).unwrap().clone()
};
let json = article.into_json(&data).await?;
Ok(FederationJson(WithContext::new_default(json)))
}
#[debug_handler]
async fn http_get_article_edits(
Path(title): Path<String>,
data: Data<DatabaseHandle>,
) -> MyResult<FederationJson<WithContext<ApubEditCollection>>> {
let article = {
let lock = data.articles.lock().unwrap();
lock.values().find(|a| a.title == title).unwrap().clone()
};
let json = DbEditCollection::read_local(&article, &data).await?;
Ok(FederationJson(WithContext::new_default(json)))
}
/// List of all activities which this actor can receive.
#[derive(Deserialize, Serialize, Debug)]
#[serde(untagged)]

View file

@ -4,11 +4,12 @@ use url::{ParseError, Url};
/// Just generate random url as object id. In a real project, you probably want to use
/// an url which contains the database id for easy retrieval (or store the random id in db).
pub fn generate_object_id(domain: &Url) -> Result<Url, ParseError> {
let port = domain.port().unwrap();
let domain = domain.domain().unwrap();
let id: String = thread_rng()
.sample_iter(&Alphanumeric)
.take(7)
.map(char::from)
.collect();
Url::parse(&format!("http://{}/objects/{}", domain, id))
Url::parse(&format!("http://{}:{}/objects/{}", domain,port, id))
}