aboutsummaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-05-20 15:59:51 +0200
committermetamuffin <metamuffin@disroot.org>2025-05-20 15:59:51 +0200
commita1db84ac3b776e929ce3286b6f77dd1ca97ea249 (patch)
treed9f271a0af46960c3d4a65f0213d1a27ca99b737 /server
parent09f86ee5b25fbddf667ef98a22eaa076cedba23c (diff)
downloadjellything-a1db84ac3b776e929ce3286b6f77dd1ca97ea249.tar
jellything-a1db84ac3b776e929ce3286b6f77dd1ca97ea249.tar.bz2
jellything-a1db84ac3b776e929ce3286b6f77dd1ca97ea249.tar.zst
requestinfo from request impl
Diffstat (limited to 'server')
-rw-r--r--server/src/helper/mod.rs30
-rw-r--r--server/src/helper/session.rs71
2 files changed, 64 insertions, 37 deletions
diff --git a/server/src/helper/mod.rs b/server/src/helper/mod.rs
index 4b0644c..9e8ce79 100644
--- a/server/src/helper/mod.rs
+++ b/server/src/helper/mod.rs
@@ -11,9 +11,18 @@ pub mod language;
pub mod node_id;
pub mod session;
+use crate::ui::error::{MyError, MyResult};
use accept::Accept;
use jellylogic::session::Session;
use jellyui::locale::Language;
+use language::lang_from_request;
+use rocket::{
+ async_trait,
+ http::Status,
+ request::{FromRequest, Outcome},
+ Request,
+};
+use session::session_from_request;
#[derive(Debug, Clone, Copy, Default)]
pub struct A<T>(pub T);
@@ -23,3 +32,24 @@ pub struct RequestInfo {
pub accept: Accept,
pub session: Session,
}
+
+impl RequestInfo {
+ pub async fn from_request_ut(request: &Request<'_>) -> MyResult<Self> {
+ Ok(Self {
+ lang: lang_from_request(request),
+ accept: Accept::from_request_ut(request),
+ session: session_from_request(request).await?,
+ })
+ }
+}
+
+#[async_trait]
+impl<'r> FromRequest<'r> for RequestInfo {
+ type Error = MyError;
+ async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
+ match Self::from_request_ut(request).await {
+ Ok(a) => Outcome::Success(a),
+ Err(a) => Outcome::Error((Status::BadRequest, a)),
+ }
+ }
+}
diff --git a/server/src/helper/session.rs b/server/src/helper/session.rs
index 7e23152..2ab87a0 100644
--- a/server/src/helper/session.rs
+++ b/server/src/helper/session.rs
@@ -3,6 +3,7 @@
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2025 metamuffin <metamuffin.org>
*/
+use super::A;
use crate::ui::error::MyError;
use anyhow::anyhow;
use jellylogic::{
@@ -18,44 +19,40 @@ use rocket::{
Request, State,
};
-use super::A;
-
-impl A<Session> {
- async fn from_request_ut(req: &Request<'_>) -> Result<Self, MyError> {
- let username;
+pub(super) async fn session_from_request(req: &Request<'_>) -> Result<Session, MyError> {
+ 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"))?;
+ #[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)?;
- };
+ // 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();
- }
+ #[cfg(feature = "bypass-auth")]
+ {
+ parse_jellyfin_auth("a"); // unused warning is annoying
+ username = "admin".to_string();
+ }
- let db = req.guard::<&State<Database>>().await.unwrap();
+ let db = req.guard::<&State<Database>>().await.unwrap();
- let user = db.get_user(&username)?.ok_or(anyhow!("user not found"))?;
+ let user = db.get_user(&username)?.ok_or(anyhow!("user not found"))?;
- Ok(A(Session { user }))
- }
+ Ok(Session { user })
}
fn parse_jellyfin_auth(h: &str) -> Option<&str> {
@@ -75,8 +72,8 @@ impl<'r> FromRequest<'r> for A<Session> {
async fn from_request<'life0>(
request: &'r Request<'life0>,
) -> request::Outcome<Self, Self::Error> {
- match A::<Session>::from_request_ut(request).await {
- Ok(x) => Outcome::Success(x),
+ match session_from_request(request).await {
+ Ok(x) => Outcome::Success(A(x)),
Err(e) => {
warn!("authentificated route rejected: {e:?}");
Outcome::Forward(Status::Unauthorized)
@@ -91,10 +88,10 @@ impl<'r> FromRequest<'r> for A<AdminSession> {
async fn from_request<'life0>(
request: &'r Request<'life0>,
) -> request::Outcome<Self, Self::Error> {
- match A::<Session>::from_request_ut(request).await {
+ match session_from_request(request).await {
Ok(x) => {
- if x.0.user.admin {
- Outcome::Success(A(AdminSession(x.0)))
+ if x.user.admin {
+ Outcome::Success(A(AdminSession(x)))
} else {
Outcome::Error((
Status::Unauthorized,