mirror of
https://github.com/versia-pub/activitypub.git
synced 2025-12-06 06:38:20 +01:00
feat: AP webfinger
This commit is contained in:
parent
f22cae919f
commit
b1c78822de
11
Cargo.lock
generated
11
Cargo.lock
generated
|
|
@ -2091,6 +2091,7 @@ dependencies = [
|
|||
"url",
|
||||
"uuid",
|
||||
"vcpkg",
|
||||
"webfinger",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -4173,6 +4174,16 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webfinger"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f395336b42f1be22490390830ccfe7a735725eef086cd0574bf8759408ecb3af"
|
||||
dependencies = [
|
||||
"reqwest 0.11.27",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.25.4"
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ serde_derive = "1.0.201"
|
|||
dotenv = "0.15.0"
|
||||
async-recursion = "1.1.1"
|
||||
base64-url = "3.0.0"
|
||||
webfinger = "0.5.1"
|
||||
|
||||
[dependencies.sea-orm]
|
||||
version = "0.12.0"
|
||||
|
|
|
|||
21
src/http.rs
21
src/http.rs
|
|
@ -2,8 +2,13 @@ use crate::{
|
|||
database::StateHandle,
|
||||
entities::user,
|
||||
error::Error,
|
||||
lysand::{self, conversion::receive_lysand_note},
|
||||
lysand::{
|
||||
self,
|
||||
conversion::{db_user_from_url, receive_lysand_note},
|
||||
},
|
||||
objects::person::{DbUser, PersonAcceptedActivities},
|
||||
utils::generate_user_id,
|
||||
API_DOMAIN, LYSAND_DOMAIN,
|
||||
};
|
||||
use activitypub_federation::{
|
||||
actix_web::{inbox::receive_activity, signing_actor},
|
||||
|
|
@ -18,6 +23,7 @@ use anyhow::anyhow;
|
|||
use serde::Deserialize;
|
||||
use tracing::info;
|
||||
use url::Url;
|
||||
use webfinger::resolve;
|
||||
|
||||
pub fn listen(config: &FederationConfig<StateHandle>) -> Result<(), Error> {
|
||||
let hostname = config.domain();
|
||||
|
|
@ -101,9 +107,18 @@ pub async fn webfinger(
|
|||
data: Data<StateHandle>,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let name = extract_webfinger_name(&query.resource, &data)?;
|
||||
let db_user = data.read_user(name).await?;
|
||||
let db_user = data.read_user(name.clone()).await;
|
||||
let user;
|
||||
if db_user.is_ok() {
|
||||
user = db_user.unwrap();
|
||||
} else {
|
||||
let res = resolve("acct:".to_string() + name + "@" + &LYSAND_DOMAIN, true)
|
||||
.await
|
||||
.unwrap();
|
||||
user = db_user_from_url(Url::parse(&res.subject)?).await?;
|
||||
}
|
||||
Ok(HttpResponse::Ok().json(build_webfinger_response(
|
||||
query.resource.clone(),
|
||||
Url::parse(&db_user.id)?,
|
||||
generate_user_id(&API_DOMAIN, &user.id)?,
|
||||
)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use activitypub_federation::{
|
||||
fetch::{object_id::ObjectId, webfinger::webfinger_resolve_actor},
|
||||
protocol::context::WithContext,
|
||||
protocol::{context::WithContext, public_key::PublicKey},
|
||||
traits::Object,
|
||||
FEDERATION_CONTENT_TYPE,
|
||||
};
|
||||
|
|
@ -18,8 +18,8 @@ use crate::{
|
|||
error,
|
||||
lysand::conversion::{lysand_post_from_db, lysand_user_from_db},
|
||||
objects,
|
||||
utils::{base_url_decode, generate_create_id},
|
||||
Response, DB, FEDERATION_CONFIG,
|
||||
utils::{base_url_decode, generate_create_id, generate_user_id},
|
||||
Response, API_DOMAIN, DB, FEDERATION_CONFIG,
|
||||
};
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
|
|
@ -117,6 +117,41 @@ async fn fetch_post(
|
|||
.json(crate::objects::post::Note::from_db(&post)))
|
||||
}
|
||||
|
||||
#[get("/apbridge/user/{user}")]
|
||||
async fn fetch_user(
|
||||
path: web::Path<String>,
|
||||
state: web::Data<State>,
|
||||
) -> actix_web::Result<HttpResponse, error::Error> {
|
||||
let db = DB.get().unwrap();
|
||||
|
||||
let user = prelude::User::find()
|
||||
.filter(post::Column::Id.eq(path.as_str()))
|
||||
.one(db)
|
||||
.await?;
|
||||
|
||||
let user = match user {
|
||||
Some(user) => user,
|
||||
None => return Ok(HttpResponse::NotFound().finish()),
|
||||
};
|
||||
|
||||
Ok(HttpResponse::Ok()
|
||||
.content_type(FEDERATION_CONTENT_TYPE)
|
||||
.json(crate::objects::person::Person {
|
||||
kind: Default::default(),
|
||||
id: generate_user_id(&API_DOMAIN, &user.id)?.into(),
|
||||
preferred_username: user.username.clone(),
|
||||
name: user.name.clone(),
|
||||
summary: user.summary.clone(),
|
||||
url: Url::parse(user.url.as_str()).unwrap(),
|
||||
inbox: Url::parse(user.inbox.as_str()).unwrap(),
|
||||
public_key: PublicKey {
|
||||
owner: Url::parse(user.url.as_str()).unwrap(),
|
||||
public_key_pem: user.public_key,
|
||||
id: format!("{}#main-key", Url::parse(user.url.as_str()).unwrap()),
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
#[get("/apbridge/lysand/object/{post}")]
|
||||
async fn fetch_lysand_post(
|
||||
path: web::Path<String>,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use clap::Parser;
|
|||
use database::Database;
|
||||
use entities::post;
|
||||
use http::{http_get_user, http_post_user_inbox, webfinger};
|
||||
use lysand::http::{create_activity, fetch_lysand_post, fetch_post, query_post};
|
||||
use lysand::http::{create_activity, fetch_lysand_post, fetch_post, fetch_user, query_post};
|
||||
use objects::person::DbUser;
|
||||
use sea_orm::{ActiveModelTrait, DatabaseConnection, Set};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
@ -259,6 +259,7 @@ async fn main() -> actix_web::Result<(), anyhow::Error> {
|
|||
.route("/.well-known/webfinger", web::get().to(webfinger))
|
||||
.service(index)
|
||||
.service(fetch_post)
|
||||
.service(fetch_user)
|
||||
.service(create_activity)
|
||||
.service(query_post)
|
||||
.service(fetch_lysand_post)
|
||||
|
|
|
|||
|
|
@ -71,14 +71,14 @@ impl DbUser {
|
|||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Person {
|
||||
#[serde(rename = "type")]
|
||||
kind: PersonType,
|
||||
preferred_username: String,
|
||||
name: String,
|
||||
summary: Option<String>,
|
||||
url: Url,
|
||||
id: ObjectId<user::Model>,
|
||||
inbox: Url,
|
||||
public_key: PublicKey,
|
||||
pub kind: PersonType,
|
||||
pub preferred_username: String,
|
||||
pub name: String,
|
||||
pub summary: Option<String>,
|
||||
pub url: Url,
|
||||
pub id: ObjectId<user::Model>,
|
||||
pub inbox: Url,
|
||||
pub public_key: PublicKey,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
|
|
|
|||
Loading…
Reference in a new issue