mirror of
https://github.com/nullishamy/ferri.git
synced 2025-04-30 04:39:20 +00:00
fix: cleanup warnings; centralise url creation into config
This commit is contained in:
parent
4b88100373
commit
9bc6c12392
11 changed files with 102 additions and 55 deletions
|
@ -1,6 +1,6 @@
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use tracing::{debug, info, span, Level};
|
use tracing::{info, span, Level};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum QueueMessage {
|
pub enum QueueMessage {
|
||||||
|
|
|
@ -9,3 +9,41 @@ pub struct ServerConfig {
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub server: ServerConfig,
|
pub server: ServerConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub fn host(&self) -> &str {
|
||||||
|
&self.server.host
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn user_url(&self, user_uuid: &str) -> String {
|
||||||
|
format!("{}/users/{}", self.host(), user_uuid)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn user_web_url(&self, user_name: &str) -> String {
|
||||||
|
format!("{}/{}", self.host(), user_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn followers_url(&self, user_uuid: &str) -> String {
|
||||||
|
format!("{}/followers", self.user_url(user_uuid))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn following_url(&self, user_uuid: &str) -> String {
|
||||||
|
format!("{}/following", self.user_url(user_uuid))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn inbox_url(&self, user_uuid: &str) -> String {
|
||||||
|
format!("{}/inbox", self.user_url(user_uuid))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn outbox_url(&self, user_uuid: &str) -> String {
|
||||||
|
format!("{}/outbox", self.user_url(user_uuid))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn post_url(&self, poster_uuid: &str, post_uuid: &str) -> String {
|
||||||
|
format!("{}/{}", self.user_url(poster_uuid), post_uuid)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn activity_url(&self, activity_uuid: &str) -> String {
|
||||||
|
format!("{}/activities/{}", self.host(), activity_uuid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
use rocket::{get, serde::json::Json};
|
use rocket::{get, serde::json::Json, State};
|
||||||
|
|
||||||
|
use crate::Config;
|
||||||
|
|
||||||
use crate::types::instance::{
|
use crate::types::instance::{
|
||||||
Accounts, Configuration, Contact, Instance, MediaAttachments, Polls, Registrations, Statuses,
|
Accounts, Configuration, Contact, Instance, MediaAttachments, Polls, Registrations, Statuses,
|
||||||
|
@ -6,9 +8,9 @@ use crate::types::instance::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[get("/instance")]
|
#[get("/instance")]
|
||||||
pub async fn instance() -> Json<Instance> {
|
pub async fn instance(config: &State<Config>) -> Json<Instance> {
|
||||||
Json(Instance {
|
Json(Instance {
|
||||||
domain: "ferri.amy.mov".to_string(),
|
domain: config.host().to_string(),
|
||||||
title: "Ferri".to_string(),
|
title: "Ferri".to_string(),
|
||||||
version: "0.0.1".to_string(),
|
version: "0.0.1".to_string(),
|
||||||
source_url: "https://forge.amy.mov/amy/ferri".to_string(),
|
source_url: "https://forge.amy.mov/amy/ferri".to_string(),
|
||||||
|
|
|
@ -26,11 +26,11 @@ pub struct StatusContext {
|
||||||
descendants: Vec<Status>
|
descendants: Vec<Status>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/statuses/<status>/context")]
|
#[get("/statuses/<_status>/context")]
|
||||||
pub async fn status_context(
|
pub async fn status_context(
|
||||||
status: &str,
|
_status: &str,
|
||||||
user: AuthenticatedUser,
|
_user: AuthenticatedUser,
|
||||||
mut db: Connection<Db>
|
_db: Connection<Db>
|
||||||
) -> Json<StatusContext> {
|
) -> Json<StatusContext> {
|
||||||
Json(StatusContext {
|
Json(StatusContext {
|
||||||
ancestors: vec![],
|
ancestors: vec![],
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::{AuthenticatedUser, Db, endpoints::api::user::CredentialAcount};
|
use crate::{AuthenticatedUser, Db, endpoints::api::user::CredentialAcount, Config};
|
||||||
use rocket::{
|
use rocket::{
|
||||||
|
State,
|
||||||
get,
|
get,
|
||||||
serde::{Deserialize, Serialize, json::Json},
|
serde::{Deserialize, Serialize, json::Json},
|
||||||
};
|
};
|
||||||
|
@ -32,11 +33,12 @@ pub struct TimelineStatus {
|
||||||
pub account: TimelineAccount,
|
pub account: TimelineAccount,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/timelines/home?<limit>")]
|
#[get("/timelines/home?<_limit>")]
|
||||||
pub async fn home(
|
pub async fn home(
|
||||||
mut db: Connection<Db>,
|
mut db: Connection<Db>,
|
||||||
limit: i64,
|
config: &State<Config>,
|
||||||
user: AuthenticatedUser,
|
_limit: i64,
|
||||||
|
_user: AuthenticatedUser,
|
||||||
) -> Json<Vec<TimelineStatus>> {
|
) -> Json<Vec<TimelineStatus>> {
|
||||||
let posts = sqlx::query!(
|
let posts = sqlx::query!(
|
||||||
r#"
|
r#"
|
||||||
|
@ -66,7 +68,7 @@ pub async fn home(
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let user_uri = format!("https://ferri.amy.mov/users/{}", record.user_id);
|
let user_uri = config.user_url(&record.user_id);
|
||||||
boost = Some(Box::new(TimelineStatus {
|
boost = Some(Box::new(TimelineStatus {
|
||||||
id: record.post_id.clone(),
|
id: record.post_id.clone(),
|
||||||
created_at: record.created_at.clone(),
|
created_at: record.created_at.clone(),
|
||||||
|
@ -110,7 +112,7 @@ pub async fn home(
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
let user_uri = format!("https://ferri.amy.mov/users/{}", record.username);
|
let user_uri = config.user_web_url(&record.username);
|
||||||
out.push(TimelineStatus {
|
out.push(TimelineStatus {
|
||||||
id: record.post_id.clone(),
|
id: record.post_id.clone(),
|
||||||
created_at: record.created_at.clone(),
|
created_at: record.created_at.clone(),
|
||||||
|
|
|
@ -95,7 +95,7 @@ pub async fn new_follow(
|
||||||
pub async fn account(
|
pub async fn account(
|
||||||
mut db: Connection<Db>,
|
mut db: Connection<Db>,
|
||||||
uuid: &str,
|
uuid: &str,
|
||||||
user: AuthenticatedUser,
|
_user: AuthenticatedUser,
|
||||||
) -> Result<Json<TimelineAccount>, NotFound<String>> {
|
) -> Result<Json<TimelineAccount>, NotFound<String>> {
|
||||||
let user = ap::User::from_id(uuid, &mut **db)
|
let user = ap::User::from_id(uuid, &mut **db)
|
||||||
.await
|
.await
|
||||||
|
@ -123,12 +123,12 @@ pub async fn account(
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/accounts/<uuid>/statuses?<limit>")]
|
#[get("/accounts/<uuid>/statuses?<_limit>")]
|
||||||
pub async fn statuses(
|
pub async fn statuses(
|
||||||
mut db: Connection<Db>,
|
mut db: Connection<Db>,
|
||||||
uuid: &str,
|
uuid: &str,
|
||||||
limit: Option<i64>,
|
_limit: Option<i64>,
|
||||||
user: AuthenticatedUser,
|
_user: AuthenticatedUser,
|
||||||
) -> Result<Json<Vec<TimelineStatus>>, NotFound<String>> {
|
) -> Result<Json<Vec<TimelineStatus>>, NotFound<String>> {
|
||||||
let user = ap::User::from_id(uuid, &mut **db)
|
let user = ap::User::from_id(uuid, &mut **db)
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -123,5 +123,7 @@ pub async fn test(http: &State<HttpClient>, outbound: &State<OutboundQueue>) ->
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
dbg!(follow);
|
||||||
|
|
||||||
"Hello, world!"
|
"Hello, world!"
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,12 @@ use rocket::{
|
||||||
};
|
};
|
||||||
use rocket_db_pools::Connection;
|
use rocket_db_pools::Connection;
|
||||||
|
|
||||||
#[get("/oauth/authorize?<client_id>&<scope>&<redirect_uri>&<response_type>")]
|
#[get("/oauth/authorize?<client_id>&<scope>&<redirect_uri>&<_response_type>")]
|
||||||
pub async fn authorize(
|
pub async fn authorize(
|
||||||
client_id: &str,
|
client_id: &str,
|
||||||
scope: &str,
|
scope: &str,
|
||||||
redirect_uri: &str,
|
redirect_uri: &str,
|
||||||
response_type: &str,
|
_response_type: &str,
|
||||||
mut db: Connection<Db>,
|
mut db: Connection<Db>,
|
||||||
) -> Redirect {
|
) -> Redirect {
|
||||||
// For now, we will always authorize the request and assign it to an admin user
|
// For now, we will always authorize the request and assign it to an admin user
|
||||||
|
@ -68,11 +68,11 @@ pub struct Token {
|
||||||
#[derive(Deserialize, Debug, FromForm)]
|
#[derive(Deserialize, Debug, FromForm)]
|
||||||
#[serde(crate = "rocket::serde")]
|
#[serde(crate = "rocket::serde")]
|
||||||
pub struct NewTokenRequest {
|
pub struct NewTokenRequest {
|
||||||
client_id: String,
|
// pub client_id: String,
|
||||||
redirect_uri: String,
|
// pub redirect_uri: String,
|
||||||
grant_type: String,
|
// pub grant_type: String,
|
||||||
code: String,
|
pub code: String,
|
||||||
client_secret: String,
|
// pub client_secret: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/oauth/token", data = "<req>")]
|
#[post("/oauth/token", data = "<req>")]
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
use main::ap;
|
use main::ap;
|
||||||
use rocket::{get, http::ContentType, serde::json::Json};
|
use rocket::{get, http::ContentType, serde::json::Json, State};
|
||||||
use rocket_db_pools::Connection;
|
use rocket_db_pools::Connection;
|
||||||
use rocket::response::status::NotFound;
|
use rocket::response::status::NotFound;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
Config,
|
||||||
Db,
|
Db,
|
||||||
types::{OrderedCollection, Person, UserKey, content},
|
types::{OrderedCollection, Person, UserKey, content},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::activity_type;
|
use super::activity_type;
|
||||||
|
|
||||||
#[get("/users/<user>/inbox")]
|
#[get("/users/<_user>/inbox")]
|
||||||
pub async fn inbox(user: String) -> Json<OrderedCollection> {
|
pub async fn inbox(_user: String) -> Json<OrderedCollection> {
|
||||||
Json(OrderedCollection {
|
Json(OrderedCollection {
|
||||||
ty: "OrderedCollection".to_string(),
|
ty: "OrderedCollection".to_string(),
|
||||||
total_items: 0,
|
total_items: 0,
|
||||||
|
@ -19,8 +20,8 @@ pub async fn inbox(user: String) -> Json<OrderedCollection> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/users/<user>/outbox")]
|
#[get("/users/<_user>/outbox")]
|
||||||
pub async fn outbox(user: String) -> Json<OrderedCollection> {
|
pub async fn outbox(_user: String) -> Json<OrderedCollection> {
|
||||||
Json(OrderedCollection {
|
Json(OrderedCollection {
|
||||||
ty: "OrderedCollection".to_string(),
|
ty: "OrderedCollection".to_string(),
|
||||||
total_items: 0,
|
total_items: 0,
|
||||||
|
@ -89,6 +90,7 @@ pub async fn following(mut db: Connection<Db>, uuid: &str) -> Result<Json<Ordere
|
||||||
#[get("/users/<uuid>/posts/<post>")]
|
#[get("/users/<uuid>/posts/<post>")]
|
||||||
pub async fn post(
|
pub async fn post(
|
||||||
mut db: Connection<Db>,
|
mut db: Connection<Db>,
|
||||||
|
config: &State<Config>,
|
||||||
uuid: &str,
|
uuid: &str,
|
||||||
post: String,
|
post: String,
|
||||||
) -> (ContentType, Json<content::Post>) {
|
) -> (ContentType, Json<content::Post>) {
|
||||||
|
@ -106,19 +108,23 @@ pub async fn post(
|
||||||
activity_type(),
|
activity_type(),
|
||||||
Json(content::Post {
|
Json(content::Post {
|
||||||
context: "https://www.w3.org/ns/activitystreams".to_string(),
|
context: "https://www.w3.org/ns/activitystreams".to_string(),
|
||||||
id: format!("https://ferri.amy.mov/users/{}/posts/{}", uuid, post.id),
|
id: config.post_url(uuid, &post.id),
|
||||||
attributed_to: Some(format!("https://ferri.amy.mov/users/{}/posts/{}", uuid, post.id)),
|
attributed_to: Some(config.user_url(uuid)),
|
||||||
ty: "Note".to_string(),
|
ty: "Note".to_string(),
|
||||||
content: post.content,
|
content: post.content,
|
||||||
ts: post.created_at,
|
ts: post.created_at,
|
||||||
to: vec!["https://ferri.amy.mov/users/amy/followers".to_string()],
|
to: vec![config.followers_url(uuid)],
|
||||||
cc: vec!["https://www.w3.org/ns/activitystreams#Public".to_string()],
|
cc: vec!["https://www.w3.org/ns/activitystreams#Public".to_string()],
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/users/<uuid>")]
|
#[get("/users/<uuid>")]
|
||||||
pub async fn user(mut db: Connection<Db>, uuid: &str) -> Result<(ContentType, Json<Person>), NotFound<String>> {
|
pub async fn user(
|
||||||
|
mut db: Connection<Db>,
|
||||||
|
config: &State<Config>,
|
||||||
|
uuid: &str
|
||||||
|
) -> Result<(ContentType, Json<Person>), NotFound<String>> {
|
||||||
let user = ap::User::from_id(uuid, &mut **db)
|
let user = ap::User::from_id(uuid, &mut **db)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| NotFound(e.to_string()))?;
|
.map_err(|e| NotFound(e.to_string()))?;
|
||||||
|
@ -128,17 +134,17 @@ pub async fn user(mut db: Connection<Db>, uuid: &str) -> Result<(ContentType, Js
|
||||||
Json(Person {
|
Json(Person {
|
||||||
context: "https://www.w3.org/ns/activitystreams".to_string(),
|
context: "https://www.w3.org/ns/activitystreams".to_string(),
|
||||||
ty: "Person".to_string(),
|
ty: "Person".to_string(),
|
||||||
id: format!("https://ferri.amy.mov/users/{}", user.id()),
|
id: config.user_url(user.id()),
|
||||||
name: user.username().to_string(),
|
name: user.username().to_string(),
|
||||||
preferred_username: user.display_name().to_string(),
|
preferred_username: user.display_name().to_string(),
|
||||||
followers: format!("https://ferri.amy.mov/users/{}/followers", uuid),
|
followers: config.followers_url(user.id()),
|
||||||
following: format!("https://ferri.amy.mov/users/{}/following", uuid),
|
following: config.following_url(user.id()),
|
||||||
summary: format!("ferri {}", user.username()),
|
summary: format!("ferri {}", user.username()),
|
||||||
inbox: format!("https://ferri.amy.mov/users/{}/inbox", uuid),
|
inbox: config.inbox_url(user.id()),
|
||||||
outbox: format!("https://ferri.amy.mov/users/{}/outbox", uuid),
|
outbox: config.outbox_url(user.id()),
|
||||||
public_key: Some(UserKey {
|
public_key: Some(UserKey {
|
||||||
id: format!("https://ferri.amy.mov/users/{}#main-key", uuid),
|
id: format!("https://ferri.amy.mov/users/{}#main-key", uuid),
|
||||||
owner: format!("https://ferri.amy.mov/users/{}", uuid),
|
owner: config.user_url(user.id()),
|
||||||
public_key: include_str!("../../../public.pem").to_string(),
|
public_key: include_str!("../../../public.pem").to_string(),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use main::ap;
|
use main::ap;
|
||||||
use rocket::{get, serde::json::Json};
|
use rocket::{get, serde::json::Json, State};
|
||||||
use rocket_db_pools::Connection;
|
use rocket_db_pools::Connection;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
Config,
|
||||||
Db,
|
Db,
|
||||||
types::webfinger::{Link, WebfingerResponse},
|
types::webfinger::{Link, WebfingerResponse},
|
||||||
};
|
};
|
||||||
|
@ -20,7 +21,7 @@ pub async fn host_meta() -> &'static str {
|
||||||
|
|
||||||
// https://mastodon.social/.well-known/webfinger?resource=acct:gargron@mastodon.social
|
// https://mastodon.social/.well-known/webfinger?resource=acct:gargron@mastodon.social
|
||||||
#[get("/.well-known/webfinger?<resource>")]
|
#[get("/.well-known/webfinger?<resource>")]
|
||||||
pub async fn webfinger(mut db: Connection<Db>, resource: &str) -> Json<WebfingerResponse> {
|
pub async fn webfinger(mut db: Connection<Db>, config: &State<Config>, resource: &str) -> Json<WebfingerResponse> {
|
||||||
info!(?resource, "incoming webfinger request");
|
info!(?resource, "incoming webfinger request");
|
||||||
|
|
||||||
let acct = resource.strip_prefix("acct:").unwrap();
|
let acct = resource.strip_prefix("acct:").unwrap();
|
||||||
|
@ -30,19 +31,19 @@ pub async fn webfinger(mut db: Connection<Db>, resource: &str) -> Json<Webfinger
|
||||||
Json(WebfingerResponse {
|
Json(WebfingerResponse {
|
||||||
subject: resource.to_string(),
|
subject: resource.to_string(),
|
||||||
aliases: vec![
|
aliases: vec![
|
||||||
format!("https://ferri.amy.mov/users/{}", user.id()),
|
config.user_url(user.id()),
|
||||||
format!("https://ferri.amy.mov/{}", user.username()),
|
config.user_web_url(user.username())
|
||||||
],
|
],
|
||||||
links: vec![
|
links: vec![
|
||||||
Link {
|
Link {
|
||||||
rel: "http://webfinger.net/rel/profile-page".to_string(),
|
rel: "http://webfinger.net/rel/profile-page".to_string(),
|
||||||
ty: Some("text/html".to_string()),
|
ty: Some("text/html".to_string()),
|
||||||
href: Some(format!("https://ferri.amy.mov/{}", user.username())),
|
href: Some(config.user_web_url(user.username())),
|
||||||
},
|
},
|
||||||
Link {
|
Link {
|
||||||
rel: "self".to_string(),
|
rel: "self".to_string(),
|
||||||
ty: Some("application/activity+json".to_string()),
|
ty: Some("application/activity+json".to_string()),
|
||||||
href: Some(format!("https://ferri.amy.mov/users/{}", user.id())),
|
href: Some(config.user_url(user.id())),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,7 +3,6 @@ use endpoints::{
|
||||||
custom, inbox, oauth, user, well_known,
|
custom, inbox, oauth, user, well_known,
|
||||||
};
|
};
|
||||||
|
|
||||||
use tracing::Level;
|
|
||||||
use tracing_subscriber::fmt;
|
use tracing_subscriber::fmt;
|
||||||
|
|
||||||
use main::ap;
|
use main::ap;
|
||||||
|
@ -27,17 +26,17 @@ mod types;
|
||||||
pub struct Db(sqlx::SqlitePool);
|
pub struct Db(sqlx::SqlitePool);
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
async fn user_profile(cfg: &rocket::State<Config>) -> (ContentType, &'static str) {
|
async fn user_profile() -> (ContentType, &'static str) {
|
||||||
(ContentType::HTML, "<p>hello</p>")
|
(ContentType::HTML, "<p>hello</p>")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/activities/<activity>")]
|
#[get("/activities/<_activity>")]
|
||||||
async fn activity_endpoint(activity: String) {
|
async fn activity_endpoint(_activity: String) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct AuthenticatedUser {
|
pub struct AuthenticatedUser {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub token: String,
|
pub token: String,
|
||||||
|
@ -45,10 +44,7 @@ struct AuthenticatedUser {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum LoginError {
|
pub enum LoginError {
|
||||||
InvalidData,
|
|
||||||
UsernameDoesNotExist,
|
|
||||||
WrongPassword,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rocket::async_trait]
|
#[rocket::async_trait]
|
||||||
|
|
Loading…
Add table
Reference in a new issue