diff options
Diffstat (limited to 'server/src/api.rs')
-rw-r--r-- | server/src/api.rs | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/server/src/api.rs b/server/src/api.rs new file mode 100644 index 0000000..f246eab --- /dev/null +++ b/server/src/api.rs @@ -0,0 +1,105 @@ +/* + This file is part of jellything (https://codeberg.org/metamuffin/jellything) + which is licensed under the GNU Affero General Public License (version 3); see /COPYING. + Copyright (C) 2025 metamuffin <metamuffin.org> +*/ +use super::ui::{account::login_logic, error::MyResult}; +use crate::{ + database::Database, + logic::session::{AdminSession, Session}, +}; +use jellybase::assetfed::AssetInner; +use jellycommon::{user::CreateSessionParams, NodeID, Visibility}; +use rocket::{ + get, + http::MediaType, + outcome::Outcome, + post, + request::{self, FromRequest}, + response::Redirect, + serde::json::Json, + Request, State, +}; +use serde_json::{json, Value}; +use std::ops::Deref; + +#[get("/api")] +pub fn r_api_root() -> Redirect { + Redirect::moved("https://jellything.metamuffin.org/book/api.html#jellything-http-api") +} + +#[get("/api/version")] +pub fn r_api_version() -> &'static str { + env!("CARGO_PKG_VERSION") +} + +#[post("/api/create_session", data = "<data>")] +pub fn r_api_account_login( + database: &State<Database>, + data: Json<CreateSessionParams>, +) -> MyResult<Value> { + let token = login_logic( + database, + &data.username, + &data.password, + data.expire, + data.drop_permissions.clone(), + )?; + Ok(json!(token)) +} + +#[get("/api/asset_token_raw/<token>")] +pub fn r_api_asset_token_raw(_admin: AdminSession, token: &str) -> MyResult<Json<AssetInner>> { + Ok(Json(AssetInner::deser(token)?)) +} + +#[get("/api/nodes_modified?<since>")] +pub fn r_api_nodes_modified_since( + _session: Session, + database: &State<Database>, + since: u64, +) -> MyResult<Json<Vec<NodeID>>> { + let mut nodes = database.get_nodes_modified_since(since)?; + nodes.retain(|id| { + database.get_node(*id).is_ok_and(|n| { + n.as_ref() + .is_some_and(|n| n.visibility >= Visibility::Reduced) + }) + }); + Ok(Json(nodes)) +} + +pub struct AcceptJson(bool); +impl Deref for AcceptJson { + type Target = bool; + fn deref(&self) -> &Self::Target { + &self.0 + } +} +impl<'r> FromRequest<'r> for AcceptJson { + type Error = (); + + fn from_request<'life0, 'async_trait>( + request: &'r Request<'life0>, + ) -> ::core::pin::Pin< + Box< + dyn ::core::future::Future<Output = request::Outcome<Self, Self::Error>> + + ::core::marker::Send + + 'async_trait, + >, + > + where + 'r: 'async_trait, + 'life0: 'async_trait, + Self: 'async_trait, + { + Box::pin(async move { + Outcome::Success(AcceptJson( + request + .accept() + .map(|a| a.preferred().exact_eq(&MediaType::JSON)) + .unwrap_or(false), + )) + }) + } +} |