ferri/ferri-server/src/endpoints/user.rs

147 lines
4.3 KiB
Rust
Raw Normal View History

2025-04-11 12:29:29 +01:00
use main::ap;
use rocket::{get, http::ContentType, serde::json::Json};
2025-04-11 12:29:29 +01:00
use rocket_db_pools::Connection;
2025-04-25 16:46:47 +01:00
use rocket::response::status::NotFound;
2025-04-11 12:29:29 +01:00
use crate::{
Db,
types::{OrderedCollection, Person, UserKey, content},
2025-04-11 12:29:29 +01:00
};
use super::activity_type;
#[get("/users/<user>/inbox")]
pub async fn inbox(user: String) -> Json<OrderedCollection> {
Json(OrderedCollection {
ty: "OrderedCollection".to_string(),
total_items: 0,
ordered_items: vec![],
})
}
#[get("/users/<user>/outbox")]
pub async fn outbox(user: String) -> Json<OrderedCollection> {
Json(OrderedCollection {
ty: "OrderedCollection".to_string(),
total_items: 0,
ordered_items: vec![],
})
}
2025-04-12 11:27:03 +01:00
#[get("/users/<uuid>/followers")]
2025-04-25 16:46:47 +01:00
pub async fn followers(mut db: Connection<Db>, uuid: &str) -> Result<Json<OrderedCollection>, NotFound<String>> {
let target = ap::User::from_id(uuid, &mut **db)
.await
.map_err(|e| NotFound(e.to_string()))?;
2025-04-11 12:29:29 +01:00
let actor_id = target.actor_id();
let followers = sqlx::query!(
r#"
SELECT follower_id FROM follow
WHERE followed_id = ?
"#,
actor_id
)
.fetch_all(&mut **db)
.await
.unwrap();
2025-04-25 16:46:47 +01:00
Ok(Json(OrderedCollection {
2025-04-11 12:29:29 +01:00
ty: "OrderedCollection".to_string(),
total_items: 1,
ordered_items: followers
.into_iter()
.map(|f| f.follower_id)
.collect::<Vec<_>>(),
2025-04-25 16:46:47 +01:00
}))
2025-04-11 12:29:29 +01:00
}
2025-04-12 11:27:03 +01:00
#[get("/users/<uuid>/following")]
2025-04-25 16:46:47 +01:00
pub async fn following(mut db: Connection<Db>, uuid: &str) -> Result<Json<OrderedCollection>, NotFound<String>> {
let target = ap::User::from_id(uuid, &mut **db)
.await
.map_err(|e| NotFound(e.to_string()))?;
2025-04-11 12:29:29 +01:00
let actor_id = target.actor_id();
let following = sqlx::query!(
r#"
SELECT followed_id FROM follow
WHERE follower_id = ?
"#,
actor_id
)
.fetch_all(&mut **db)
.await
.unwrap();
2025-04-25 16:46:47 +01:00
Ok(Json(OrderedCollection {
2025-04-11 12:29:29 +01:00
ty: "OrderedCollection".to_string(),
total_items: 1,
ordered_items: following
.into_iter()
.map(|f| f.followed_id)
.collect::<Vec<_>>(),
2025-04-25 16:46:47 +01:00
}))
2025-04-11 12:29:29 +01:00
}
2025-04-12 11:27:03 +01:00
#[get("/users/<uuid>/posts/<post>")]
2025-04-12 15:16:40 +01:00
pub async fn post(
mut db: Connection<Db>,
uuid: &str,
post: String,
) -> (ContentType, Json<content::Post>) {
let post = sqlx::query!(
r#"
2025-04-12 11:27:03 +01:00
SELECT * FROM post WHERE id = ?1
2025-04-12 15:16:40 +01:00
"#,
post
)
.fetch_one(&mut **db)
.await
.unwrap();
2025-04-12 11:27:03 +01:00
2025-04-11 12:29:29 +01:00
(
activity_type(),
Json(content::Post {
context: "https://www.w3.org/ns/activitystreams".to_string(),
2025-04-12 11:27:03 +01:00
id: format!("https://ferri.amy.mov/users/{}/posts/{}", uuid, post.id),
2025-04-26 12:17:32 +01:00
attributed_to: Some(format!("https://ferri.amy.mov/users/{}/posts/{}", uuid, post.id)),
2025-04-11 12:29:29 +01:00
ty: "Note".to_string(),
2025-04-12 11:27:03 +01:00
content: post.content,
ts: post.created_at,
2025-04-11 12:29:29 +01:00
to: vec!["https://ferri.amy.mov/users/amy/followers".to_string()],
cc: vec!["https://www.w3.org/ns/activitystreams#Public".to_string()],
}),
)
}
2025-04-12 11:27:03 +01:00
#[get("/users/<uuid>")]
2025-04-25 16:46:47 +01:00
pub async fn user(mut db: Connection<Db>, uuid: &str) -> Result<(ContentType, Json<Person>), NotFound<String>> {
let user = ap::User::from_id(uuid, &mut **db)
.await
.map_err(|e| NotFound(e.to_string()))?;
Ok((
2025-04-11 12:29:29 +01:00
activity_type(),
Json(Person {
context: "https://www.w3.org/ns/activitystreams".to_string(),
ty: "Person".to_string(),
2025-04-25 16:46:47 +01:00
id: format!("https://ferri.amy.mov/users/{}", user.id()),
2025-04-12 11:27:03 +01:00
name: user.username().to_string(),
preferred_username: user.display_name().to_string(),
followers: format!("https://ferri.amy.mov/users/{}/followers", uuid),
following: format!("https://ferri.amy.mov/users/{}/following", uuid),
summary: format!("ferri {}", user.username()),
inbox: format!("https://ferri.amy.mov/users/{}/inbox", uuid),
outbox: format!("https://ferri.amy.mov/users/{}/outbox", uuid),
2025-04-11 12:29:29 +01:00
public_key: Some(UserKey {
2025-04-12 11:27:03 +01:00
id: format!("https://ferri.amy.mov/users/{}#main-key", uuid),
owner: format!("https://ferri.amy.mov/users/{}", uuid),
2025-04-11 12:29:29 +01:00
public_key: include_str!("../../../public.pem").to_string(),
}),
}),
2025-04-25 16:46:47 +01:00
))
2025-04-11 12:29:29 +01:00
}