mirror of
https://github.com/Nutomic/ibis.git
synced 2024-11-22 08:41:08 +00:00
reorder files, remove some unnecessary stuff
This commit is contained in:
parent
79df3f3837
commit
9fe5d50075
14 changed files with 85 additions and 188 deletions
|
@ -1,62 +0,0 @@
|
||||||
use crate::{
|
|
||||||
instance::DatabaseHandle,
|
|
||||||
objects::{person::DbUser, post::Note},
|
|
||||||
DbPost,
|
|
||||||
};
|
|
||||||
use activitypub_federation::{
|
|
||||||
config::Data,
|
|
||||||
fetch::object_id::ObjectId,
|
|
||||||
kinds::activity::CreateType,
|
|
||||||
protocol::helpers::deserialize_one_or_many,
|
|
||||||
traits::{ActivityHandler, Object},
|
|
||||||
};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct CreatePost {
|
|
||||||
pub(crate) actor: ObjectId<DbUser>,
|
|
||||||
#[serde(deserialize_with = "deserialize_one_or_many")]
|
|
||||||
pub(crate) to: Vec<Url>,
|
|
||||||
pub(crate) object: Note,
|
|
||||||
#[serde(rename = "type")]
|
|
||||||
pub(crate) kind: CreateType,
|
|
||||||
pub(crate) id: Url,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CreatePost {
|
|
||||||
pub fn new(note: Note, id: Url) -> CreatePost {
|
|
||||||
CreatePost {
|
|
||||||
actor: note.attributed_to.clone(),
|
|
||||||
to: note.to.clone(),
|
|
||||||
object: note,
|
|
||||||
kind: CreateType::Create,
|
|
||||||
id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
|
||||||
impl ActivityHandler for CreatePost {
|
|
||||||
type DataType = DatabaseHandle;
|
|
||||||
type Error = crate::error::Error;
|
|
||||||
|
|
||||||
fn id(&self) -> &Url {
|
|
||||||
&self.id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn actor(&self) -> &Url {
|
|
||||||
self.actor.inner()
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn verify(&self, data: &Data<Self::DataType>) -> Result<(), Self::Error> {
|
|
||||||
DbPost::verify(&self.object, &self.id, data).await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn receive(self, data: &Data<Self::DataType>) -> Result<(), Self::Error> {
|
|
||||||
DbPost::from_json(self.object, data).await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
use crate::error::Error;
|
|
||||||
use crate::{
|
|
||||||
instance::DatabaseHandle,
|
|
||||||
objects::person::{DbUser, Person, PersonAcceptedActivities},
|
|
||||||
};
|
|
||||||
use activitypub_federation::{
|
|
||||||
axum::{
|
|
||||||
inbox::{receive_activity, ActivityData},
|
|
||||||
json::FederationJson,
|
|
||||||
},
|
|
||||||
config::{Data, FederationConfig, FederationMiddleware},
|
|
||||||
fetch::webfinger::{build_webfinger_response, extract_webfinger_name, Webfinger},
|
|
||||||
protocol::context::WithContext,
|
|
||||||
traits::Object,
|
|
||||||
};
|
|
||||||
use axum::{
|
|
||||||
extract::{Path, Query},
|
|
||||||
response::IntoResponse,
|
|
||||||
routing::{get, post},
|
|
||||||
Json, Router,
|
|
||||||
};
|
|
||||||
use axum_macros::debug_handler;
|
|
||||||
use serde::Deserialize;
|
|
||||||
use std::net::ToSocketAddrs;
|
|
||||||
use tracing::info;
|
|
||||||
|
|
||||||
pub fn listen(config: &FederationConfig<DatabaseHandle>) -> Result<(), Error> {
|
|
||||||
let hostname = config.domain();
|
|
||||||
info!("Listening with axum on {hostname}");
|
|
||||||
let config = config.clone();
|
|
||||||
let app = Router::new()
|
|
||||||
.route("/:user/inbox", post(http_post_user_inbox))
|
|
||||||
.route("/:user", get(http_get_user))
|
|
||||||
.route("/.well-known/webfinger", get(webfinger))
|
|
||||||
.layer(FederationMiddleware::new(config));
|
|
||||||
|
|
||||||
let addr = hostname
|
|
||||||
.to_socket_addrs()?
|
|
||||||
.next()
|
|
||||||
.expect("Failed to lookup domain name");
|
|
||||||
let server = axum::Server::bind(&addr).serve(app.into_make_service());
|
|
||||||
|
|
||||||
tokio::spawn(server);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[debug_handler]
|
|
||||||
async fn http_get_user(
|
|
||||||
Path(name): Path<String>,
|
|
||||||
data: Data<DatabaseHandle>,
|
|
||||||
) -> Result<FederationJson<WithContext<Person>>, Error> {
|
|
||||||
let db_user = data.read_user(&name)?;
|
|
||||||
let json_user = db_user.into_json(&data).await?;
|
|
||||||
Ok(FederationJson(WithContext::new_default(json_user)))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[debug_handler]
|
|
||||||
async fn http_post_user_inbox(
|
|
||||||
data: Data<DatabaseHandle>,
|
|
||||||
activity_data: ActivityData,
|
|
||||||
) -> impl IntoResponse {
|
|
||||||
receive_activity::<WithContext<PersonAcceptedActivities>, DbUser, DatabaseHandle>(
|
|
||||||
activity_data,
|
|
||||||
&data,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct WebfingerQuery {
|
|
||||||
resource: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[debug_handler]
|
|
||||||
async fn webfinger(
|
|
||||||
Query(query): Query<WebfingerQuery>,
|
|
||||||
data: Data<DatabaseHandle>,
|
|
||||||
) -> Result<Json<Webfinger>, Error> {
|
|
||||||
let name = extract_webfinger_name(&query.resource, &data)?;
|
|
||||||
let db_user = data.read_user(&name)?;
|
|
||||||
Ok(Json(build_webfinger_response(
|
|
||||||
query.resource,
|
|
||||||
db_user.ap_id.into_inner(),
|
|
||||||
)))
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
use crate::error::Error;
|
|
||||||
use axum::http::StatusCode;
|
|
||||||
use axum::response::{IntoResponse, Response};
|
|
||||||
|
|
||||||
#[allow(clippy::diverging_sub_expression, clippy::items_after_statements)]
|
|
||||||
pub mod http;
|
|
||||||
|
|
||||||
impl IntoResponse for Error {
|
|
||||||
fn into_response(self) -> Response {
|
|
||||||
(StatusCode::INTERNAL_SERVER_ERROR, format!("{}", self.0)).into_response()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use axum::http::StatusCode;
|
||||||
|
use axum::response::{IntoResponse, Response};
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -17,3 +19,9 @@ where
|
||||||
Error(t.into())
|
Error(t.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IntoResponse for Error {
|
||||||
|
fn into_response(self) -> Response {
|
||||||
|
(StatusCode::INTERNAL_SERVER_ERROR, format!("{}", self.0)).into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
use crate::{activities::follow::Follow, instance::DatabaseHandle, objects::person::DbUser};
|
use crate::{
|
||||||
|
federation::activities::follow::Follow, federation::objects::person::DbUser,
|
||||||
|
instance::DatabaseHandle,
|
||||||
|
};
|
||||||
use activitypub_federation::{
|
use activitypub_federation::{
|
||||||
config::Data, fetch::object_id::ObjectId, kinds::activity::AcceptType, traits::ActivityHandler,
|
config::Data, fetch::object_id::ObjectId, kinds::activity::AcceptType, traits::ActivityHandler,
|
||||||
};
|
};
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
activities::accept::Accept, generate_object_id, instance::DatabaseHandle,
|
federation::activities::accept::Accept, federation::objects::person::DbUser,
|
||||||
objects::person::DbUser,
|
generate_object_id, instance::DatabaseHandle,
|
||||||
};
|
};
|
||||||
use activitypub_federation::{
|
use activitypub_federation::{
|
||||||
config::Data,
|
config::Data,
|
|
@ -1,3 +1,2 @@
|
||||||
pub mod accept;
|
pub mod accept;
|
||||||
pub mod create_post;
|
|
||||||
pub mod follow;
|
pub mod follow;
|
3
src/federation/mod.rs
Normal file
3
src/federation/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
pub mod activities;
|
||||||
|
pub mod objects;
|
||||||
|
pub mod routes;
|
|
@ -1,8 +1,7 @@
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::{
|
use crate::{
|
||||||
activities::{accept::Accept, create_post::CreatePost, follow::Follow},
|
federation::activities::{accept::Accept, follow::Follow},
|
||||||
instance::DatabaseHandle,
|
instance::DatabaseHandle,
|
||||||
objects::post::DbPost,
|
|
||||||
utils::generate_object_id,
|
utils::generate_object_id,
|
||||||
};
|
};
|
||||||
use activitypub_federation::{
|
use activitypub_federation::{
|
||||||
|
@ -40,7 +39,6 @@ pub struct DbUser {
|
||||||
pub enum PersonAcceptedActivities {
|
pub enum PersonAcceptedActivities {
|
||||||
Follow(Follow),
|
Follow(Follow),
|
||||||
Accept(Accept),
|
Accept(Accept),
|
||||||
CreateNote(CreatePost),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DbUser {
|
impl DbUser {
|
||||||
|
@ -90,18 +88,6 @@ impl DbUser {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn post(&self, post: DbPost, data: &Data<DatabaseHandle>) -> Result<(), Error> {
|
|
||||||
let id = generate_object_id(data.domain())?;
|
|
||||||
let create = CreatePost::new(post.into_json(data).await?, id.clone());
|
|
||||||
let mut inboxes = vec![];
|
|
||||||
for f in self.followers.clone() {
|
|
||||||
let user: DbUser = ObjectId::from(f).dereference(data).await?;
|
|
||||||
inboxes.push(user.shared_inbox_or_inbox());
|
|
||||||
}
|
|
||||||
self.send(create, inboxes, data).await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) async fn send<Activity>(
|
pub(crate) async fn send<Activity>(
|
||||||
&self,
|
&self,
|
||||||
activity: Activity,
|
activity: Activity,
|
|
@ -1,4 +1,6 @@
|
||||||
use crate::{error::Error, generate_object_id, instance::DatabaseHandle, objects::person::DbUser};
|
use crate::{
|
||||||
|
error::Error, federation::objects::person::DbUser, generate_object_id, instance::DatabaseHandle,
|
||||||
|
};
|
||||||
use activitypub_federation::{
|
use activitypub_federation::{
|
||||||
config::Data,
|
config::Data,
|
||||||
fetch::object_id::ObjectId,
|
fetch::object_id::ObjectId,
|
33
src/federation/routes.rs
Normal file
33
src/federation/routes.rs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
use crate::error::Error;
|
||||||
|
use crate::federation::objects::person::{DbUser, Person, PersonAcceptedActivities};
|
||||||
|
use crate::instance::DatabaseHandle;
|
||||||
|
use activitypub_federation::axum::inbox::{receive_activity, ActivityData};
|
||||||
|
use activitypub_federation::axum::json::FederationJson;
|
||||||
|
use activitypub_federation::config::Data;
|
||||||
|
use activitypub_federation::protocol::context::WithContext;
|
||||||
|
use activitypub_federation::traits::Object;
|
||||||
|
use axum::extract::path::Path;
|
||||||
|
use axum::response::IntoResponse;
|
||||||
|
use axum_macros::debug_handler;
|
||||||
|
|
||||||
|
#[debug_handler]
|
||||||
|
pub async fn http_get_user(
|
||||||
|
Path(name): Path<String>,
|
||||||
|
data: Data<DatabaseHandle>,
|
||||||
|
) -> Result<FederationJson<WithContext<Person>>, Error> {
|
||||||
|
let db_user = data.read_user(&name)?;
|
||||||
|
let json_user = db_user.into_json(&data).await?;
|
||||||
|
Ok(FederationJson(WithContext::new_default(json_user)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[debug_handler]
|
||||||
|
pub async fn http_post_user_inbox(
|
||||||
|
data: Data<DatabaseHandle>,
|
||||||
|
activity_data: ActivityData,
|
||||||
|
) -> impl IntoResponse {
|
||||||
|
receive_activity::<WithContext<PersonAcceptedActivities>, DbUser, DatabaseHandle>(
|
||||||
|
activity_data,
|
||||||
|
&data,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::objects::{person::DbUser, post::DbPost};
|
use crate::federation::objects::{person::DbUser, post::DbPost};
|
||||||
use activitypub_federation::config::{FederationConfig, UrlVerifier};
|
use activitypub_federation::config::{FederationConfig, UrlVerifier};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
pub async fn new_instance(
|
pub async fn federation_config(
|
||||||
hostname: &str,
|
hostname: &str,
|
||||||
name: String,
|
name: String,
|
||||||
) -> Result<FederationConfig<DatabaseHandle>, Error> {
|
) -> Result<FederationConfig<DatabaseHandle>, Error> {
|
||||||
|
|
36
src/main.rs
36
src/main.rs
|
@ -1,13 +1,21 @@
|
||||||
use crate::axum::http::listen;
|
use crate::{instance::federation_config, utils::generate_object_id};
|
||||||
use crate::{instance::new_instance, objects::post::DbPost, utils::generate_object_id};
|
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use tracing::log::LevelFilter;
|
use tracing::log::LevelFilter;
|
||||||
|
|
||||||
mod activities;
|
use activitypub_federation::config::FederationMiddleware;
|
||||||
mod axum;
|
use axum::{
|
||||||
|
routing::{get, post},
|
||||||
|
Router, Server,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::federation::routes::http_get_user;
|
||||||
|
use crate::federation::routes::http_post_user_inbox;
|
||||||
|
use std::net::ToSocketAddrs;
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
|
mod federation;
|
||||||
mod instance;
|
mod instance;
|
||||||
mod objects;
|
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
@ -18,8 +26,22 @@ async fn main() -> Result<(), Error> {
|
||||||
.filter_module("fediwiki", LevelFilter::Info)
|
.filter_module("fediwiki", LevelFilter::Info)
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
let alpha = new_instance("localhost:8001", "alpha".to_string()).await?;
|
let config = federation_config("localhost:8001", "alpha".to_string()).await?;
|
||||||
listen(&alpha)?;
|
|
||||||
|
|
||||||
|
let hostname = config.domain();
|
||||||
|
info!("Listening with axum on {hostname}");
|
||||||
|
let config = config.clone();
|
||||||
|
let app = Router::new()
|
||||||
|
.route("/:user/inbox", post(http_post_user_inbox))
|
||||||
|
.route("/:user", get(http_get_user))
|
||||||
|
.layer(FederationMiddleware::new(config));
|
||||||
|
|
||||||
|
let addr = hostname
|
||||||
|
.to_socket_addrs()?
|
||||||
|
.next()
|
||||||
|
.expect("Failed to lookup domain name");
|
||||||
|
let server = Server::bind(&addr).serve(app.into_make_service());
|
||||||
|
|
||||||
|
tokio::spawn(server);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue