mirror of
https://github.com/versia-pub/activitypub.git
synced 2025-12-06 06:38:20 +01:00
Add a post fuct
This commit is contained in:
parent
4c020229e4
commit
8ac9f7bd4b
8
Cargo.lock
generated
8
Cargo.lock
generated
|
|
@ -442,6 +442,12 @@ dependencies = [
|
||||||
"syn 2.0.58",
|
"syn 2.0.58",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async_once"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2ce4f10ea3abcd6617873bae9f91d1c5332b4a778bd9ce34d0cd517474c1de82"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atoi"
|
name = "atoi"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
|
|
@ -1812,10 +1818,12 @@ dependencies = [
|
||||||
"actix-web-prom",
|
"actix-web-prom",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"async_once",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"enum_delegate",
|
"enum_delegate",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
"lazy_static",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"rand",
|
"rand",
|
||||||
"sea-orm",
|
"sea-orm",
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@ num_cpus = "1.16.0"
|
||||||
actix-web-prom = { version = "0.8.0", features = ["process"] }
|
actix-web-prom = { version = "0.8.0", features = ["process"] }
|
||||||
serde_json = "1.0.115"
|
serde_json = "1.0.115"
|
||||||
chrono = "0.4.38"
|
chrono = "0.4.38"
|
||||||
|
lazy_static = "1.4.0"
|
||||||
|
async_once = "0.2.6"
|
||||||
|
|
||||||
[dependencies.sea-orm]
|
[dependencies.sea-orm]
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
|
|
|
||||||
83
src/main.rs
83
src/main.rs
|
|
@ -1,12 +1,14 @@
|
||||||
use activitypub_federation::{
|
use activitypub_federation::{
|
||||||
config::{FederationConfig, FederationMiddleware},
|
config::{Data, FederationConfig, FederationMiddleware}, fetch::{object_id::ObjectId, webfinger::webfinger_resolve_actor}, http_signatures::generate_actor_keypair, traits::Actor
|
||||||
http_signatures::generate_actor_keypair,
|
|
||||||
};
|
};
|
||||||
use actix_web::{get, http::KeepAlive, middleware, web, App, Error, HttpResponse, HttpServer};
|
use activitystreams_kinds::public;
|
||||||
|
use actix_web::{get, http::KeepAlive, middleware, post, web, App, Error, HttpResponse, HttpServer};
|
||||||
use actix_web_prom::PrometheusMetricsBuilder;
|
use actix_web_prom::PrometheusMetricsBuilder;
|
||||||
|
use async_once::AsyncOnce;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use database::Database;
|
use database::Database;
|
||||||
|
use entities::post;
|
||||||
use http::{http_get_user, http_post_user_inbox, webfinger};
|
use http::{http_get_user, http_post_user_inbox, webfinger};
|
||||||
use objects::person::DbUser;
|
use objects::person::DbUser;
|
||||||
use sea_orm::{ActiveModelTrait, DatabaseConnection, Set};
|
use sea_orm::{ActiveModelTrait, DatabaseConnection, Set};
|
||||||
|
|
@ -15,13 +17,17 @@ use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
env,
|
env,
|
||||||
net::ToSocketAddrs,
|
net::ToSocketAddrs,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex, OnceLock},
|
||||||
};
|
};
|
||||||
use tokio::signal;
|
use tokio::signal;
|
||||||
use tracing::{info, instrument::WithSubscriber};
|
use tracing::{info, instrument::WithSubscriber};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::database::{Config, State};
|
use crate::{activities::create_post::CreatePost, database::{Config, State}, objects::post::{Mention, Note}};
|
||||||
|
use crate::entities::user;
|
||||||
|
use crate::utils::generate_object_id;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
|
||||||
mod activities;
|
mod activities;
|
||||||
mod database;
|
mod database;
|
||||||
|
|
@ -54,26 +60,60 @@ async fn index(_: web::Data<State>) -> actix_web::Result<HttpResponse, Error> {
|
||||||
Ok(HttpResponse::Ok().json(Response { health: true }))
|
Ok(HttpResponse::Ok().json(Response { health: true }))
|
||||||
}
|
}
|
||||||
|
|
||||||
const DOMAIN: &str = "example.com";
|
#[post("/test/postmanually/{user}/{post}")]
|
||||||
|
async fn post_manually(
|
||||||
|
path: web::Path<(String, String)>,
|
||||||
|
state: web::Data<State>,
|
||||||
|
) -> actix_web::Result<HttpResponse, error::Error> {
|
||||||
|
let local_user = state.local_user().await?;
|
||||||
|
let data = FEDERATION_CONFIG.get().unwrap();
|
||||||
|
let creator = webfinger_resolve_actor::<State, user::Model>(path.0.as_str(), &data.to_request_data()).await?;
|
||||||
|
|
||||||
|
let mention = Mention {
|
||||||
|
href: Url::parse(&creator.id)?,
|
||||||
|
kind: Default::default(),
|
||||||
|
};
|
||||||
|
let id: ObjectId<post::Model> = generate_object_id(data.domain())?.into();
|
||||||
|
let note = Note {
|
||||||
|
kind: Default::default(),
|
||||||
|
id,
|
||||||
|
sensitive: false,
|
||||||
|
attributed_to: Url::parse(&data.local_user().await?.id).unwrap().into(),
|
||||||
|
to: vec![public()],
|
||||||
|
content: format!("Hello {}", creator.name),
|
||||||
|
tag: vec![mention],
|
||||||
|
in_reply_to: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
CreatePost::send(note, creator.shared_inbox_or_inbox(), &data.to_request_data()).await?;
|
||||||
|
|
||||||
|
Ok(HttpResponse::Ok().json(Response { health: true }))
|
||||||
|
}
|
||||||
|
|
||||||
|
const DOMAIN_DEF: &str = "example.com";
|
||||||
const LOCAL_USER_NAME: &str = "example";
|
const LOCAL_USER_NAME: &str = "example";
|
||||||
|
|
||||||
|
lazy_static!{
|
||||||
|
static ref SERVER_URL: String = env::var("LISTEN").unwrap_or("127.0.0.1:8080".to_string());
|
||||||
|
static ref DATABASE_URL: String = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
|
||||||
|
static ref USERNAME: String = env::var("LOCAL_USER_NAME").unwrap_or(LOCAL_USER_NAME.to_string());
|
||||||
|
static ref DOMAIN: String = env::var("FEDERATED_DOMAIN").unwrap_or(DOMAIN_DEF.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
static DB: OnceLock<DatabaseConnection> = OnceLock::new();
|
||||||
|
static FEDERATION_CONFIG: OnceLock<FederationConfig<State>> = OnceLock::new();
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn main() -> actix_web::Result<(), anyhow::Error> {
|
async fn main() -> actix_web::Result<(), anyhow::Error> {
|
||||||
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
||||||
|
|
||||||
let server_url = env::var("LISTEN").unwrap_or("127.0.0.1:8080".to_string());
|
let ap_id = Url::parse(&format!("https://{}/{}", DOMAIN.to_string(), &USERNAME.to_string()))?;
|
||||||
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
|
let inbox = Url::parse(&format!("https://{}/{}/inbox", DOMAIN.to_string(), &USERNAME.to_string()))?;
|
||||||
|
|
||||||
let username = env::var("LOCAL_USER_NAME").unwrap_or(LOCAL_USER_NAME.to_string());
|
|
||||||
let domain = env::var("FEDERATED_DOMAIN").unwrap_or(DOMAIN.to_string());
|
|
||||||
|
|
||||||
let ap_id = Url::parse(&format!("https://{}/{}", domain, &username))?;
|
|
||||||
let inbox = Url::parse(&format!("https://{}/{}/inbox", domain, &username))?;
|
|
||||||
let keypair = generate_actor_keypair()?;
|
let keypair = generate_actor_keypair()?;
|
||||||
|
|
||||||
let user = entities::user::ActiveModel {
|
let user = entities::user::ActiveModel {
|
||||||
id: Set(ap_id.clone().into()),
|
id: Set(ap_id.clone().into()),
|
||||||
username: Set(username),
|
username: Set(USERNAME.to_string()),
|
||||||
name: Set("Test account <3".to_string()),
|
name: Set("Test account <3".to_string()),
|
||||||
inbox: Set(inbox.to_string()),
|
inbox: Set(inbox.to_string()),
|
||||||
public_key: Set(keypair.public_key.clone()),
|
public_key: Set(keypair.public_key.clone()),
|
||||||
|
|
@ -87,11 +127,15 @@ async fn main() -> actix_web::Result<(), anyhow::Error> {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let db = sea_orm::Database::connect(database_url).await?;
|
let db = sea_orm::Database::connect(DATABASE_URL.to_string()).await?;
|
||||||
|
|
||||||
info!("Connected to database: {:?}", db);
|
info!("Connected to database: {:?}", db);
|
||||||
|
|
||||||
let user = user.insert(&db).await;
|
DB.set(db).expect("We were not able to save the DB conn into memory");
|
||||||
|
|
||||||
|
let db = DB.get().unwrap();
|
||||||
|
|
||||||
|
let user = user.insert(db).await;
|
||||||
|
|
||||||
if let Err(err) = user {
|
if let Err(err) = user {
|
||||||
eprintln!("Error inserting user: {:?}", err);
|
eprintln!("Error inserting user: {:?}", err);
|
||||||
|
|
@ -100,7 +144,7 @@ async fn main() -> actix_web::Result<(), anyhow::Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let state: State = State {
|
let state: State = State {
|
||||||
database_connection: db.into(),
|
database_connection: Arc::new(db.clone()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let data = FederationConfig::builder()
|
let data = FederationConfig::builder()
|
||||||
|
|
@ -137,12 +181,13 @@ async fn main() -> actix_web::Result<(), anyhow::Error> {
|
||||||
.wrap(middleware::Logger::default()) // enable logger
|
.wrap(middleware::Logger::default()) // enable logger
|
||||||
.wrap(prometheus.clone())
|
.wrap(prometheus.clone())
|
||||||
.wrap(FederationMiddleware::new(data.clone()))
|
.wrap(FederationMiddleware::new(data.clone()))
|
||||||
|
.service(post_manually)
|
||||||
.route("/{user}", web::get().to(http_get_user))
|
.route("/{user}", web::get().to(http_get_user))
|
||||||
.route("/{user}/inbox", web::post().to(http_post_user_inbox))
|
.route("/{user}/inbox", web::post().to(http_post_user_inbox))
|
||||||
.route("/.well-known/webfinger", web::get().to(webfinger))
|
.route("/.well-known/webfinger", web::get().to(webfinger))
|
||||||
.service(index)
|
.service(index)
|
||||||
})
|
})
|
||||||
.bind(&server_url)?
|
.bind(SERVER_URL.to_string())?
|
||||||
.workers(num_cpus::get())
|
.workers(num_cpus::get())
|
||||||
.shutdown_timeout(20)
|
.shutdown_timeout(20)
|
||||||
.keep_alive(KeepAlive::Os)
|
.keep_alive(KeepAlive::Os)
|
||||||
|
|
|
||||||
|
|
@ -31,15 +31,15 @@ pub struct DbPost {
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Note {
|
pub struct Note {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
kind: NoteType,
|
pub(crate) kind: NoteType,
|
||||||
id: ObjectId<post::Model>,
|
pub(crate) id: ObjectId<post::Model>,
|
||||||
pub(crate) attributed_to: ObjectId<user::Model>,
|
pub(crate) attributed_to: ObjectId<user::Model>,
|
||||||
#[serde(deserialize_with = "deserialize_one_or_many")]
|
#[serde(deserialize_with = "deserialize_one_or_many")]
|
||||||
pub(crate) to: Vec<Url>,
|
pub(crate) to: Vec<Url>,
|
||||||
content: String,
|
pub(crate) content: String,
|
||||||
in_reply_to: Option<ObjectId<post::Model>>,
|
pub(crate) in_reply_to: Option<ObjectId<post::Model>>,
|
||||||
tag: Vec<Mention>,
|
pub(crate) tag: Vec<Mention>,
|
||||||
sensitive: bool,
|
pub(crate) sensitive: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue