From f73aa32549743b2967160d38c1622199c41524a4 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Tue, 29 Apr 2025 15:19:36 +0200 Subject: aaaaaaa --- server/src/logic/mod.rs | 2 +- server/src/logic/session.rs | 109 ------------------------------------------- server/src/logic/stream.rs | 6 +-- server/src/logic/userdata.rs | 34 +++++++------- 4 files changed, 22 insertions(+), 129 deletions(-) delete mode 100644 server/src/logic/session.rs (limited to 'server/src/logic') diff --git a/server/src/logic/mod.rs b/server/src/logic/mod.rs index 745d11b..26f45de 100644 --- a/server/src/logic/mod.rs +++ b/server/src/logic/mod.rs @@ -4,6 +4,6 @@ Copyright (C) 2025 metamuffin */ pub mod playersync; -pub mod session; pub mod stream; pub mod userdata; + diff --git a/server/src/logic/session.rs b/server/src/logic/session.rs deleted file mode 100644 index 105aa10..0000000 --- a/server/src/logic/session.rs +++ /dev/null @@ -1,109 +0,0 @@ -/* - 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 -*/ -use crate::ui::error::MyError; -use anyhow::anyhow; -use jellybase::database::Database; -use jellylogic::session::{validate, AdminSession, Session}; -use log::warn; -use rocket::{ - async_trait, - http::Status, - outcome::Outcome, - request::{self, FromRequest}, - Request, State, -}; - -pub struct A(pub T); - -impl A { - async fn from_request_ut(req: &Request<'_>) -> Result { - let username; - - #[cfg(not(feature = "bypass-auth"))] - { - let token = req - .query_value("session") - .map(|e| e.unwrap()) - .or_else(|| req.query_value("api_key").map(|e| e.unwrap())) - .or_else(|| req.headers().get_one("X-MediaBrowser-Token")) - .or_else(|| { - req.headers() - .get_one("Authorization") - .and_then(parse_jellyfin_auth) - }) // for jellyfin compat - .or(req.cookies().get("session").map(|cookie| cookie.value())) - .ok_or(anyhow!("not logged in"))?; - - // jellyfin urlescapes the token for *some* requests - let token = token.replace("%3D", "="); - username = validate(&token)?; - }; - - #[cfg(feature = "bypass-auth")] - { - parse_jellyfin_auth("a"); // unused warning is annoying - username = "admin".to_string(); - } - - let db = req.guard::<&State>().await.unwrap(); - - let user = db.get_user(&username)?.ok_or(anyhow!("user not found"))?; - - Ok(A(Session { user })) - } -} - -fn parse_jellyfin_auth(h: &str) -> Option<&str> { - for tok in h.split(" ") { - if let Some(tok) = tok.strip_prefix("Token=\"") { - if let Some(tok) = tok.strip_suffix("\"") { - return Some(tok); - } - } - } - None -} - -#[async_trait] -impl<'r> FromRequest<'r> for A { - type Error = MyError; - async fn from_request<'life0>( - request: &'r Request<'life0>, - ) -> request::Outcome { - match Session::from_request_ut(request).await { - Ok(x) => Outcome::Success(x), - Err(e) => { - warn!("authentificated route rejected: {e:?}"); - Outcome::Forward(Status::Unauthorized) - } - } - } -} - -#[async_trait] -impl<'r> FromRequest<'r> for A { - type Error = MyError; - async fn from_request<'life0>( - request: &'r Request<'life0>, - ) -> request::Outcome { - match A::::from_request_ut(request).await { - Ok(x) => { - if x.user.admin { - Outcome::Success(A(AdminSession(x.0))) - } else { - Outcome::Error(( - Status::Unauthorized, - MyError(anyhow!("you are not an admin")), - )) - } - } - Err(e) => { - warn!("authentificated route rejected: {e:?}"); - Outcome::Forward(Status::Unauthorized) - } - } - } -} diff --git a/server/src/logic/stream.rs b/server/src/logic/stream.rs index f9cdb41..9d4db6d 100644 --- a/server/src/logic/stream.rs +++ b/server/src/logic/stream.rs @@ -3,7 +3,7 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2025 metamuffin */ -use crate::{database::Database, ui::error::MyError}; +use crate::{database::Database, helper::A, ui::error::MyError}; use anyhow::{anyhow, Result}; use jellybase::{assetfed::AssetInner, federation::Federation}; use jellycommon::{stream::StreamSpec, TrackSource}; @@ -26,7 +26,7 @@ use tokio::io::{duplex, DuplexStream}; #[head("/n/<_id>/stream?")] pub async fn r_stream_head( - _sess: Session, + _sess: A, _id: &str, spec: BTreeMap, ) -> Result, MyError> { @@ -42,7 +42,7 @@ pub async fn r_stream_head( #[get("/n//stream?")] pub async fn r_stream( - _session: Session, + _session: A, _federation: &State, db: &State, id: &str, diff --git a/server/src/logic/userdata.rs b/server/src/logic/userdata.rs index 8da6be9..25d3893 100644 --- a/server/src/logic/userdata.rs +++ b/server/src/logic/userdata.rs @@ -3,10 +3,12 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2025 metamuffin */ -use crate::ui::error::MyResult; +use crate::{helper::A, ui::error::MyResult}; use jellybase::database::Database; use jellycommon::{ - routes::u_node_id, user::{NodeUserData, WatchedState}, NodeID + routes::u_node_id, + user::{NodeUserData, WatchedState}, + NodeID, }; use jellylogic::session::Session; use rocket::{ @@ -23,25 +25,25 @@ pub enum UrlWatchedState { #[get("/n//userdata")] pub fn r_node_userdata( - session: Session, + session: A, db: &State, - id: NodeID, + id: A, ) -> MyResult> { let u = db - .get_node_udata(id, &session.user.name)? + .get_node_udata(id.0, &session.0.user.name)? .unwrap_or_default(); Ok(Json(u)) } #[post("/n//watched?")] pub async fn r_node_userdata_watched( - session: Session, + session: A, db: &State, - id: NodeID, + id: A, state: UrlWatchedState, ) -> MyResult { // TODO perm - db.update_node_udata(id, &session.user.name, |udata| { + db.update_node_udata(id.0, &session.0.user.name, |udata| { udata.watched = match state { UrlWatchedState::None => WatchedState::None, UrlWatchedState::Watched => WatchedState::Watched, @@ -49,7 +51,7 @@ pub async fn r_node_userdata_watched( }; Ok(()) })?; - Ok(Redirect::found(u_node_id(id))) + Ok(Redirect::found(u_node_id(id.0))) } #[derive(FromForm)] @@ -60,28 +62,28 @@ pub struct UpdateRating { #[post("/n//update_rating", data = "
")] pub async fn r_node_userdata_rating( - session: Session, + session: A, db: &State, - id: NodeID, + id: A, form: Form, ) -> MyResult { // TODO perm - db.update_node_udata(id, &session.user.name, |udata| { + db.update_node_udata(id.0, &session.0.user.name, |udata| { udata.rating = form.rating; Ok(()) })?; - Ok(Redirect::found(u_node_id(id))) + Ok(Redirect::found(u_node_id(id.0))) } #[post("/n//progress?")] pub async fn r_node_userdata_progress( - session: Session, + session: A, db: &State, - id: NodeID, + id: A, t: f64, ) -> MyResult<()> { // TODO perm - db.update_node_udata(id, &session.user.name, |udata| { + db.update_node_udata(id.0, &session.0.user.name, |udata| { udata.watched = match udata.watched { WatchedState::None | WatchedState::Pending | WatchedState::Progress(_) => { WatchedState::Progress(t) -- cgit v1.2.3-70-g09d2